OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrRRectEffect.h" | 8 #include "GrRRectEffect.h" |
9 | 9 |
10 #include "GrConvexPolyEffect.h" | 10 #include "GrConvexPolyEffect.h" |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 502 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
503 const char* fragmentPos = fsBuilder->fragmentPosition(); | 503 const char* fragmentPos = fsBuilder->fragmentPosition(); |
504 // At each quarter-ellipse corner we compute a vector that is the offset of
the fragment pos | 504 // At each quarter-ellipse corner we compute a vector that is the offset of
the fragment pos |
505 // to the ellipse center. The vector is pinned in x and y to be in the quart
er-plane relevant | 505 // to the ellipse center. The vector is pinned in x and y to be in the quart
er-plane relevant |
506 // to that corner. This means that points near the interior near the rrect t
op edge will have | 506 // to that corner. This means that points near the interior near the rrect t
op edge will have |
507 // a vector that points straight up for both the TL left and TR corners. Com
puting an | 507 // a vector that points straight up for both the TL left and TR corners. Com
puting an |
508 // alpha from this vector at either the TR or TL corner will give the correc
t result. Similarly, | 508 // alpha from this vector at either the TR or TL corner will give the correc
t result. Similarly, |
509 // fragments near the other three edges will get the correct AA. Fragments i
n the interior of | 509 // fragments near the other three edges will get the correct AA. Fragments i
n the interior of |
510 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dii > 0.5 they will | 510 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dii > 0.5 they will |
511 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. | 511 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. |
| 512 // |
512 // The code below is a simplified version of the above that performs maxs on
the vector | 513 // The code below is a simplified version of the above that performs maxs on
the vector |
513 // components before computing distances and alpha values so that only one d
istance computation | 514 // components before computing distances and alpha values so that only one d
istance computation |
514 // need be computed to determine the min alpha. | 515 // need be computed to determine the min alpha. |
515 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen
tPos); | 516 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen
tPos); |
516 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect
Name); | 517 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect
Name); |
| 518 // The uniforms with the inv squared radii are highp to prevent underflow. |
517 switch (erre.getRRect().getType()) { | 519 switch (erre.getRRect().getType()) { |
518 case SkRRect::kSimple_Type: { | 520 case SkRRect::kSimple_Type: { |
519 const char *invRadiiXYSqdName; | 521 const char *invRadiiXYSqdName; |
520 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, | 522 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, |
521 kVec2f_GrSLType, kDefault_
GrSLPrecision, | 523 kVec2f_GrSLType, kHigh_GrS
LPrecision, |
522 "invRadiiXY", | 524 "invRadiiXY", |
523 &invRadiiXYSqdName); | 525 &invRadiiXYSqdName); |
524 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; | 526 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; |
525 // Z is the x/y offsets divided by squared radii. | 527 // Z is the x/y offsets divided by squared radii. |
526 fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName
); | 528 fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName
); |
527 break; | 529 break; |
528 } | 530 } |
529 case SkRRect::kNinePatch_Type: { | 531 case SkRRect::kNinePatch_Type: { |
530 const char *invRadiiLTRBSqdName; | 532 const char *invRadiiLTRBSqdName; |
531 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, | 533 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, |
532 kVec4f_GrSLType, kDefault_
GrSLPrecision, | 534 kVec4f_GrSLType, kHigh_GrS
LPrecision, |
533 "invRadiiLTRB", | 535 "invRadiiLTRB", |
534 &invRadiiLTRBSqdName); | 536 &invRadiiLTRBSqdName); |
535 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; | 537 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; |
536 // Z is the x/y offsets divided by squared radii. We only care about
the (at most) one | 538 // Z is the x/y offsets divided by squared radii. We only care about
the (at most) one |
537 // corner where both the x and y offsets are positive, hence the max
es. (The inverse | 539 // corner where both the x and y offsets are positive, hence the max
es. (The inverse |
538 // squared radii will always be positive.) | 540 // squared radii will always be positive.) |
539 fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s
.zw), 0.0);\n", | 541 fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s
.zw), 0.0);\n", |
540 invRadiiLTRBSqdName, invRadiiLTRBSqdName); | 542 invRadiiLTRBSqdName, invRadiiLTRBSqdName); |
541 break; | 543 break; |
542 } | 544 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 if (rrect.isNinePatch()) { | 709 if (rrect.isNinePatch()) { |
708 return EllipticalRRectEffect::Create(edgeType, rrect); | 710 return EllipticalRRectEffect::Create(edgeType, rrect); |
709 } | 711 } |
710 return NULL; | 712 return NULL; |
711 } | 713 } |
712 } | 714 } |
713 } | 715 } |
714 | 716 |
715 return NULL; | 717 return NULL; |
716 } | 718 } |
OLD | NEW |