| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 } while (NULL == fp); | 121 } while (NULL == fp); |
| 122 return fp; | 122 return fp; |
| 123 } | 123 } |
| 124 | 124 |
| 125 ////////////////////////////////////////////////////////////////////////////// | 125 ////////////////////////////////////////////////////////////////////////////// |
| 126 | 126 |
| 127 class GLCircularRRectEffect : public GrGLFragmentProcessor { | 127 class GLCircularRRectEffect : public GrGLFragmentProcessor { |
| 128 public: | 128 public: |
| 129 GLCircularRRectEffect(const GrProcessor&); | 129 GLCircularRRectEffect(const GrProcessor&); |
| 130 | 130 |
| 131 virtual void emitCode(GrGLFPBuilder* builder, | 131 virtual void emitCode(EmitArgs&) override; |
| 132 const GrFragmentProcessor& fp, | |
| 133 const char* outputColor, | |
| 134 const char* inputColor, | |
| 135 const TransformedCoordsArray&, | |
| 136 const TextureSamplerArray&) override; | |
| 137 | 132 |
| 138 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); | 133 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
| 139 | 134 |
| 140 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 135 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
| 141 | 136 |
| 142 private: | 137 private: |
| 143 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 138 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
| 144 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; | 139 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; |
| 145 SkRRect fPrevRRect; | 140 SkRRect fPrevRRect; |
| 146 typedef GrGLFragmentProcessor INHERITED; | 141 typedef GrGLFragmentProcessor INHERITED; |
| 147 }; | 142 }; |
| 148 | 143 |
| 149 GLCircularRRectEffect::GLCircularRRectEffect(const GrProcessor& ) { | 144 GLCircularRRectEffect::GLCircularRRectEffect(const GrProcessor& ) { |
| 150 fPrevRRect.setEmpty(); | 145 fPrevRRect.setEmpty(); |
| 151 } | 146 } |
| 152 | 147 |
| 153 void GLCircularRRectEffect::emitCode(GrGLFPBuilder* builder, | 148 void GLCircularRRectEffect::emitCode(EmitArgs& args) { |
| 154 const GrFragmentProcessor& fp, | 149 const CircularRRectEffect& crre = args.fFp.cast<CircularRRectEffect>(); |
| 155 const char* outputColor, | |
| 156 const char* inputColor, | |
| 157 const TransformedCoordsArray&, | |
| 158 const TextureSamplerArray& samplers) { | |
| 159 const CircularRRectEffect& crre = fp.cast<CircularRRectEffect>(); | |
| 160 const char *rectName; | 150 const char *rectName; |
| 161 const char *radiusPlusHalfName; | 151 const char *radiusPlusHalfName; |
| 162 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom | 152 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom |
| 163 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has | 153 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has |
| 164 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by | 154 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by |
| 165 // half a pixel. | 155 // half a pixel. |
| 166 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 156 fInnerRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
| 167 kVec4f_GrSLType, kDefault_GrSLPrecis
ion, | 157 kVec4f_GrSLType, kDefault_GrSLPrecis
ion, |
| 168 "innerRect", | 158 "innerRect", |
| 169 &rectName); | 159 &rectName); |
| 170 fRadiusPlusHalfUniform = builder->addUniform(GrGLProgramBuilder::kFragment_V
isibility, | 160 fRadiusPlusHalfUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFrag
ment_Visibility, |
| 171 kFloat_GrSLType, kDefault_GrSLP
recision, | 161 kFloat_GrSLType, kDefault_GrSLP
recision, |
| 172 "radiusPlusHalf", | 162 "radiusPlusHalf", |
| 173 &radiusPlusHalfName); | 163 &radiusPlusHalfName); |
| 174 | 164 |
| 175 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 165 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
| 176 const char* fragmentPos = fsBuilder->fragmentPosition(); | 166 const char* fragmentPos = fsBuilder->fragmentPosition(); |
| 177 // At each quarter-circle corner we compute a vector that is the offset of t
he fragment position | 167 // At each quarter-circle corner we compute a vector that is the offset of t
he fragment position |
| 178 // from the circle center. The vector is pinned in x and y to be in the quar
ter-plane relevant | 168 // from the circle center. The vector is pinned in x and y to be in the quar
ter-plane relevant |
| 179 // to that corner. This means that points near the interior near the rrect t
op edge will have | 169 // to that corner. This means that points near the interior near the rrect t
op edge will have |
| 180 // a vector that points straight up for both the TL left and TR corners. Com
puting an | 170 // a vector that points straight up for both the TL left and TR corners. Com
puting an |
| 181 // alpha from this vector at either the TR or TL corner will give the correc
t result. Similarly, | 171 // alpha from this vector at either the TR or TL corner will give the correc
t result. Similarly, |
| 182 // fragments near the other three edges will get the correct AA. Fragments i
n the interior of | 172 // fragments near the other three edges will get the correct AA. Fragments i
n the interior of |
| 183 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dius > 0.5 they will | 173 // the rrect will have a (0,0) vector at all four corners. So long as the ra
dius > 0.5 they will |
| 184 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. | 174 // correctly produce an alpha value of 1 at all four corners. We take the mi
n of all the alphas. |
| 185 // The code below is a simplified version of the above that performs maxs on
the vector | 175 // The code below is a simplified version of the above that performs maxs on
the vector |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 fragmentPos, rectName); | 262 fragmentPos, rectName); |
| 273 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", | 263 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", |
| 274 radiusPlusHalfName); | 264 radiusPlusHalfName); |
| 275 break; | 265 break; |
| 276 } | 266 } |
| 277 | 267 |
| 278 if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) { | 268 if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) { |
| 279 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); | 269 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); |
| 280 } | 270 } |
| 281 | 271 |
| 282 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 272 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor, |
| 283 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 273 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")
).c_str()); |
| 284 } | 274 } |
| 285 | 275 |
| 286 void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLSLCap
s&, | 276 void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLSLCap
s&, |
| 287 GrProcessorKeyBuilder* b) { | 277 GrProcessorKeyBuilder* b) { |
| 288 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); | 278 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); |
| 289 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); | 279 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); |
| 290 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); | 280 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); |
| 291 } | 281 } |
| 292 | 282 |
| 293 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, | 283 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 } while (NULL == fp); | 466 } while (NULL == fp); |
| 477 return fp; | 467 return fp; |
| 478 } | 468 } |
| 479 | 469 |
| 480 ////////////////////////////////////////////////////////////////////////////// | 470 ////////////////////////////////////////////////////////////////////////////// |
| 481 | 471 |
| 482 class GLEllipticalRRectEffect : public GrGLFragmentProcessor { | 472 class GLEllipticalRRectEffect : public GrGLFragmentProcessor { |
| 483 public: | 473 public: |
| 484 GLEllipticalRRectEffect(const GrProcessor&); | 474 GLEllipticalRRectEffect(const GrProcessor&); |
| 485 | 475 |
| 486 virtual void emitCode(GrGLFPBuilder* builder, | 476 virtual void emitCode(EmitArgs&) override; |
| 487 const GrFragmentProcessor& effect, | |
| 488 const char* outputColor, | |
| 489 const char* inputColor, | |
| 490 const TransformedCoordsArray&, | |
| 491 const TextureSamplerArray&) override; | |
| 492 | 477 |
| 493 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); | 478 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
| 494 | 479 |
| 495 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 480 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
| 496 | 481 |
| 497 private: | 482 private: |
| 498 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 483 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
| 499 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; | 484 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; |
| 500 SkRRect fPrevRRect; | 485 SkRRect fPrevRRect; |
| 501 typedef GrGLFragmentProcessor INHERITED; | 486 typedef GrGLFragmentProcessor INHERITED; |
| 502 }; | 487 }; |
| 503 | 488 |
| 504 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrProcessor& effect) { | 489 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrProcessor& effect) { |
| 505 fPrevRRect.setEmpty(); | 490 fPrevRRect.setEmpty(); |
| 506 } | 491 } |
| 507 | 492 |
| 508 void GLEllipticalRRectEffect::emitCode(GrGLFPBuilder* builder, | 493 void GLEllipticalRRectEffect::emitCode(EmitArgs& args) { |
| 509 const GrFragmentProcessor& effect, | 494 const EllipticalRRectEffect& erre = args.fFp.cast<EllipticalRRectEffect>(); |
| 510 const char* outputColor, | |
| 511 const char* inputColor, | |
| 512 const TransformedCoordsArray&, | |
| 513 const TextureSamplerArray& samplers) { | |
| 514 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | |
| 515 const char *rectName; | 495 const char *rectName; |
| 516 // The inner rect is the rrect bounds inset by the x/y radii | 496 // The inner rect is the rrect bounds inset by the x/y radii |
| 517 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 497 fInnerRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
| 518 kVec4f_GrSLType, kDefault_GrSLPrecis
ion, | 498 kVec4f_GrSLType, kDefault_GrSLPrecis
ion, |
| 519 "innerRect", | 499 "innerRect", |
| 520 &rectName); | 500 &rectName); |
| 521 | 501 |
| 522 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 502 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
| 523 const char* fragmentPos = fsBuilder->fragmentPosition(); | 503 const char* fragmentPos = fsBuilder->fragmentPosition(); |
| 524 // 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 |
| 525 // 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 |
| 526 // 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 |
| 527 // 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 |
| 528 // 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, |
| 529 // 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 |
| 530 // 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 |
| 531 // 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. |
| 532 // The code below is a simplified version of the above that performs maxs on
the vector | 512 // The code below is a simplified version of the above that performs maxs on
the vector |
| 533 // components before computing distances and alpha values so that only one d
istance computation | 513 // components before computing distances and alpha values so that only one d
istance computation |
| 534 // need be computed to determine the min alpha. | 514 // need be computed to determine the min alpha. |
| 535 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen
tPos); | 515 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen
tPos); |
| 536 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect
Name); | 516 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect
Name); |
| 537 switch (erre.getRRect().getType()) { | 517 switch (erre.getRRect().getType()) { |
| 538 case SkRRect::kSimple_Type: { | 518 case SkRRect::kSimple_Type: { |
| 539 const char *invRadiiXYSqdName; | 519 const char *invRadiiXYSqdName; |
| 540 fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragm
ent_Visibility, | 520 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, |
| 541 kVec2f_GrSLType, kDefault_
GrSLPrecision, | 521 kVec2f_GrSLType, kDefault_
GrSLPrecision, |
| 542 "invRadiiXY", | 522 "invRadiiXY", |
| 543 &invRadiiXYSqdName); | 523 &invRadiiXYSqdName); |
| 544 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; | 524 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; |
| 545 // Z is the x/y offsets divided by squared radii. | 525 // Z is the x/y offsets divided by squared radii. |
| 546 fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName
); | 526 fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName
); |
| 547 break; | 527 break; |
| 548 } | 528 } |
| 549 case SkRRect::kNinePatch_Type: { | 529 case SkRRect::kNinePatch_Type: { |
| 550 const char *invRadiiLTRBSqdName; | 530 const char *invRadiiLTRBSqdName; |
| 551 fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragm
ent_Visibility, | 531 fInvRadiiSqdUniform = args.fBuilder->addUniform(GrGLProgramBuilder::
kFragment_Visibility, |
| 552 kVec4f_GrSLType, kDefault_
GrSLPrecision, | 532 kVec4f_GrSLType, kDefault_
GrSLPrecision, |
| 553 "invRadiiLTRB", | 533 "invRadiiLTRB", |
| 554 &invRadiiLTRBSqdName); | 534 &invRadiiLTRBSqdName); |
| 555 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; | 535 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n")
; |
| 556 // Z is the x/y offsets divided by squared radii. We only care about
the (at most) one | 536 // Z is the x/y offsets divided by squared radii. We only care about
the (at most) one |
| 557 // corner where both the x and y offsets are positive, hence the max
es. (The inverse | 537 // corner where both the x and y offsets are positive, hence the max
es. (The inverse |
| 558 // squared radii will always be positive.) | 538 // squared radii will always be positive.) |
| 559 fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s
.zw), 0.0);\n", | 539 fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s
.zw), 0.0);\n", |
| 560 invRadiiLTRBSqdName, invRadiiLTRBSqdName); | 540 invRadiiLTRBSqdName, invRadiiLTRBSqdName); |
| 561 break; | 541 break; |
| 562 } | 542 } |
| 563 default: | 543 default: |
| 564 SkFAIL("RRect should always be simple or nine-patch."); | 544 SkFAIL("RRect should always be simple or nine-patch."); |
| 565 } | 545 } |
| 566 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. | 546 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. |
| 567 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); | 547 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); |
| 568 // grad_dot is the squared length of the gradient of the implicit. | 548 // grad_dot is the squared length of the gradient of the implicit. |
| 569 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); | 549 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); |
| 570 // avoid calling inversesqrt on zero. | 550 // avoid calling inversesqrt on zero. |
| 571 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 551 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
| 572 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); | 552 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); |
| 573 | 553 |
| 574 if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) { | 554 if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) { |
| 575 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); | 555 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); |
| 576 } else { | 556 } else { |
| 577 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); | 557 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); |
| 578 } | 558 } |
| 579 | 559 |
| 580 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 560 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor, |
| 581 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 561 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")
).c_str()); |
| 582 } | 562 } |
| 583 | 563 |
| 584 void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps
&, | 564 void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps
&, |
| 585 GrProcessorKeyBuilder* b) { | 565 GrProcessorKeyBuilder* b) { |
| 586 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 566 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
| 587 GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3)); | 567 GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3)); |
| 588 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); | 568 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); |
| 589 } | 569 } |
| 590 | 570 |
| 591 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, | 571 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 if (rrect.isNinePatch()) { | 707 if (rrect.isNinePatch()) { |
| 728 return EllipticalRRectEffect::Create(edgeType, rrect); | 708 return EllipticalRRectEffect::Create(edgeType, rrect); |
| 729 } | 709 } |
| 730 return NULL; | 710 return NULL; |
| 731 } | 711 } |
| 732 } | 712 } |
| 733 } | 713 } |
| 734 | 714 |
| 735 return NULL; | 715 return NULL; |
| 736 } | 716 } |
| OLD | NEW |