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 "gl/builders/GrGLProgramBuilder.h" | 8 #include "gl/builders/GrGLProgramBuilder.h" |
9 #include "GrRRectEffect.h" | 9 #include "GrRRectEffect.h" |
10 | 10 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 95 |
96 CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t cir
cularCornerFlags, | 96 CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t cir
cularCornerFlags, |
97 const SkRRect& rrect) | 97 const SkRRect& rrect) |
98 : fRRect(rrect) | 98 : fRRect(rrect) |
99 , fEdgeType(edgeType) | 99 , fEdgeType(edgeType) |
100 , fCircularCornerFlags(circularCornerFlags) { | 100 , fCircularCornerFlags(circularCornerFlags) { |
101 this->setWillReadFragmentPosition(); | 101 this->setWillReadFragmentPosition(); |
102 } | 102 } |
103 | 103 |
104 bool CircularRRectEffect::onIsEqual(const GrEffect& other) const { | 104 bool CircularRRectEffect::onIsEqual(const GrEffect& other) const { |
105 const CircularRRectEffect& crre = CastEffect<CircularRRectEffect>(other); | 105 const CircularRRectEffect& crre = GrEffect::CastEffect<CircularRRectEffect>(
other); |
106 // The corner flags are derived from fRRect, so no need to check them. | 106 // The corner flags are derived from fRRect, so no need to check them. |
107 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; | 107 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; |
108 } | 108 } |
109 | 109 |
110 ////////////////////////////////////////////////////////////////////////////// | 110 ////////////////////////////////////////////////////////////////////////////// |
111 | 111 |
112 GR_DEFINE_EFFECT_TEST(CircularRRectEffect); | 112 GR_DEFINE_EFFECT_TEST(CircularRRectEffect); |
113 | 113 |
114 GrEffect* CircularRRectEffect::TestCreate(SkRandom* random, | 114 GrEffect* CircularRRectEffect::TestCreate(SkRandom* random, |
115 GrContext*, | 115 GrContext*, |
116 const GrDrawTargetCaps& caps, | 116 const GrDrawTargetCaps& caps, |
117 GrTexture*[]) { | 117 GrTexture*[]) { |
118 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 118 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
119 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 119 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
120 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); | 120 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); |
121 SkRRect rrect; | 121 SkRRect rrect; |
122 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 122 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
123 GrEffect* effect; | 123 GrEffect* effect; |
124 do { | 124 do { |
125 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 125 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); |
126 effect = GrRRectEffect::Create(et, rrect); | 126 effect = GrRRectEffect::Create(et, rrect); |
127 } while (NULL == effect); | 127 } while (NULL == effect); |
128 return effect; | 128 return effect; |
129 } | 129 } |
130 | 130 |
131 ////////////////////////////////////////////////////////////////////////////// | 131 ////////////////////////////////////////////////////////////////////////////// |
132 | 132 |
133 class GLCircularRRectEffect : public GrGLEffect { | 133 class GLCircularRRectEffect : public GrGLEffect { |
134 public: | 134 public: |
135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrEffect&); |
136 | 136 |
137 virtual void emitCode(GrGLProgramBuilder* builder, | 137 virtual void emitCode(GrGLProgramBuilder* builder, |
138 const GrDrawEffect& drawEffect, | 138 const GrEffect& effect, |
139 const GrEffectKey& key, | 139 const GrEffectKey& key, |
140 const char* outputColor, | 140 const char* outputColor, |
141 const char* inputColor, | 141 const char* inputColor, |
142 const TransformedCoordsArray&, | 142 const TransformedCoordsArray&, |
143 const TextureSamplerArray&) SK_OVERRIDE; | 143 const TextureSamplerArray&) SK_OVERRIDE; |
144 | 144 |
145 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB
uilder*); | 145 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); |
146 | 146 |
147 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_
OVERRIDE; | 147 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; |
148 | 148 |
149 private: | 149 private: |
150 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 150 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; | 151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; |
152 SkRRect fPrevRRect; | 152 SkRRect fPrevRRect; |
153 typedef GrGLEffect INHERITED; | 153 typedef GrGLEffect INHERITED; |
154 }; | 154 }; |
155 | 155 |
156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto
ry, | 156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto
ry, |
157 const GrDrawEffect& drawEffect) | 157 const GrEffect& effect) |
158 : INHERITED (factory) { | 158 : INHERITED (factory) { |
159 fPrevRRect.setEmpty(); | 159 fPrevRRect.setEmpty(); |
160 } | 160 } |
161 | 161 |
162 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, | 162 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, |
163 const GrDrawEffect& drawEffect, | 163 const GrEffect& effect, |
164 const GrEffectKey& key, | 164 const GrEffectKey& key, |
165 const char* outputColor, | 165 const char* outputColor, |
166 const char* inputColor, | 166 const char* inputColor, |
167 const TransformedCoordsArray&, | 167 const TransformedCoordsArray&, |
168 const TextureSamplerArray& samplers) { | 168 const TextureSamplerArray& samplers) { |
169 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>
(); | 169 const CircularRRectEffect& crre = GrEffect::CastEffect<CircularRRectEffect>(
effect); |
170 const char *rectName; | 170 const char *rectName; |
171 const char *radiusPlusHalfName; | 171 const char *radiusPlusHalfName; |
172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom | 172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom |
173 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has | 173 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has |
174 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by | 174 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by |
175 // half a pixel. | 175 // half a pixel. |
176 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 176 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
177 kVec4f_GrSLType, | 177 kVec4f_GrSLType, |
178 "innerRect", | 178 "innerRect", |
179 &rectName); | 179 &rectName); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 286 } |
287 | 287 |
288 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { | 288 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { |
289 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); | 289 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); |
290 } | 290 } |
291 | 291 |
292 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 292 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
293 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 293 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
294 } | 294 } |
295 | 295 |
296 void GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCap
s&, | 296 void GLCircularRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, |
297 GrEffectKeyBuilder* b) { | 297 GrEffectKeyBuilder* b) { |
298 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>
(); | 298 const CircularRRectEffect& crre = GrEffect::CastEffect<CircularRRectEffect>(
effect); |
299 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); | 299 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); |
300 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); | 300 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); |
301 } | 301 } |
302 | 302 |
303 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, | 303 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, |
304 const GrDrawEffect& drawEffect) { | 304 const GrEffect& effect) { |
305 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>
(); | 305 const CircularRRectEffect& crre = GrEffect::CastEffect<CircularRRectEffect>(
effect); |
306 const SkRRect& rrect = crre.getRRect(); | 306 const SkRRect& rrect = crre.getRRect(); |
307 if (rrect != fPrevRRect) { | 307 if (rrect != fPrevRRect) { |
308 SkRect rect = rrect.getBounds(); | 308 SkRect rect = rrect.getBounds(); |
309 SkScalar radius = 0; | 309 SkScalar radius = 0; |
310 switch (crre.getCircularCornerFlags()) { | 310 switch (crre.getCircularCornerFlags()) { |
311 case CircularRRectEffect::kAll_CornerFlags: | 311 case CircularRRectEffect::kAll_CornerFlags: |
312 SkASSERT(rrect.isSimpleCircular()); | 312 SkASSERT(rrect.isSimpleCircular()); |
313 radius = rrect.getSimpleRadii().fX; | 313 radius = rrect.getSimpleRadii().fX; |
314 SkASSERT(radius >= kRadiusMin); | 314 SkASSERT(radius >= kRadiusMin); |
315 rect.inset(radius, radius); | 315 rect.inset(radius, radius); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance(); | 429 return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance(); |
430 } | 430 } |
431 | 431 |
432 EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const Sk
RRect& rrect) | 432 EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const Sk
RRect& rrect) |
433 : fRRect(rrect) | 433 : fRRect(rrect) |
434 , fEdgeType(edgeType){ | 434 , fEdgeType(edgeType){ |
435 this->setWillReadFragmentPosition(); | 435 this->setWillReadFragmentPosition(); |
436 } | 436 } |
437 | 437 |
438 bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { | 438 bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { |
439 const EllipticalRRectEffect& erre = CastEffect<EllipticalRRectEffect>(other)
; | 439 const EllipticalRRectEffect& erre = GrEffect::CastEffect<EllipticalRRectEffe
ct>(other); |
440 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; | 440 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; |
441 } | 441 } |
442 | 442 |
443 ////////////////////////////////////////////////////////////////////////////// | 443 ////////////////////////////////////////////////////////////////////////////// |
444 | 444 |
445 GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect); | 445 GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect); |
446 | 446 |
447 GrEffect* EllipticalRRectEffect::TestCreate(SkRandom* random, | 447 GrEffect* EllipticalRRectEffect::TestCreate(SkRandom* random, |
448 GrContext*, | 448 GrContext*, |
449 const GrDrawTargetCaps& caps, | 449 const GrDrawTargetCaps& caps, |
(...skipping 29 matching lines...) Expand all Loading... |
479 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 479 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); |
480 effect = GrRRectEffect::Create(et, rrect); | 480 effect = GrRRectEffect::Create(et, rrect); |
481 } while (NULL == effect); | 481 } while (NULL == effect); |
482 return effect; | 482 return effect; |
483 } | 483 } |
484 | 484 |
485 ////////////////////////////////////////////////////////////////////////////// | 485 ////////////////////////////////////////////////////////////////////////////// |
486 | 486 |
487 class GLEllipticalRRectEffect : public GrGLEffect { | 487 class GLEllipticalRRectEffect : public GrGLEffect { |
488 public: | 488 public: |
489 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 489 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrEffect&); |
490 | 490 |
491 virtual void emitCode(GrGLProgramBuilder* builder, | 491 virtual void emitCode(GrGLProgramBuilder* builder, |
492 const GrDrawEffect& drawEffect, | 492 const GrEffect& effect, |
493 const GrEffectKey& key, | 493 const GrEffectKey& key, |
494 const char* outputColor, | 494 const char* outputColor, |
495 const char* inputColor, | 495 const char* inputColor, |
496 const TransformedCoordsArray&, | 496 const TransformedCoordsArray&, |
497 const TextureSamplerArray&) SK_OVERRIDE; | 497 const TextureSamplerArray&) SK_OVERRIDE; |
498 | 498 |
499 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB
uilder*); | 499 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); |
500 | 500 |
501 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_
OVERRIDE; | 501 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; |
502 | 502 |
503 private: | 503 private: |
504 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 504 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
505 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; | 505 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; |
506 SkRRect fPrevRRect; | 506 SkRRect fPrevRRect; |
507 typedef GrGLEffect INHERITED; | 507 typedef GrGLEffect INHERITED; |
508 }; | 508 }; |
509 | 509 |
510 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f
actory, | 510 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f
actory, |
511 const GrDrawEffect& drawEffect) | 511 const GrEffect& effect) |
512 : INHERITED (factory) { | 512 : INHERITED (factory) { |
513 fPrevRRect.setEmpty(); | 513 fPrevRRect.setEmpty(); |
514 } | 514 } |
515 | 515 |
516 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, | 516 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, |
517 const GrDrawEffect& drawEffect, | 517 const GrEffect& effect, |
518 const GrEffectKey& key, | 518 const GrEffectKey& key, |
519 const char* outputColor, | 519 const char* outputColor, |
520 const char* inputColor, | 520 const char* inputColor, |
521 const TransformedCoordsArray&, | 521 const TransformedCoordsArray&, |
522 const TextureSamplerArray& samplers) { | 522 const TextureSamplerArray& samplers) { |
523 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff
ect>(); | 523 const EllipticalRRectEffect& erre = GrEffect::CastEffect<EllipticalRRectEffe
ct>(effect); |
524 const char *rectName; | 524 const char *rectName; |
525 // The inner rect is the rrect bounds inset by the x/y radii | 525 // The inner rect is the rrect bounds inset by the x/y radii |
526 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 526 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
527 kVec4f_GrSLType, | 527 kVec4f_GrSLType, |
528 "innerRect", | 528 "innerRect", |
529 &rectName); | 529 &rectName); |
530 | 530 |
531 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 531 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
532 const char* fragmentPos = fsBuilder->fragmentPosition(); | 532 const char* fragmentPos = fsBuilder->fragmentPosition(); |
533 // At each quarter-ellipse corner we compute a vector that is the offset of
the fragment pos | 533 // At each quarter-ellipse corner we compute a vector that is the offset of
the fragment pos |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { | 583 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { |
584 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); | 584 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); |
585 } else { | 585 } else { |
586 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); | 586 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); |
587 } | 587 } |
588 | 588 |
589 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 589 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
590 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 590 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
591 } | 591 } |
592 | 592 |
593 void GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLC
aps&, | 593 void GLEllipticalRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, |
594 GrEffectKeyBuilder* b) { | 594 GrEffectKeyBuilder* b) { |
595 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff
ect>(); | 595 const EllipticalRRectEffect& erre = GrEffect::CastEffect<EllipticalRRectEffe
ct>(effect); |
596 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); | 596 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); |
597 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); | 597 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); |
598 } | 598 } |
599 | 599 |
600 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, | 600 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, |
601 const GrDrawEffect& drawEffect) { | 601 const GrEffect& effect) { |
602 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff
ect>(); | 602 const EllipticalRRectEffect& erre = GrEffect::CastEffect<EllipticalRRectEffe
ct>(effect); |
603 const SkRRect& rrect = erre.getRRect(); | 603 const SkRRect& rrect = erre.getRRect(); |
604 if (rrect != fPrevRRect) { | 604 if (rrect != fPrevRRect) { |
605 SkRect rect = rrect.getBounds(); | 605 SkRect rect = rrect.getBounds(); |
606 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); | 606 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); |
607 SkASSERT(r0.fX >= kRadiusMin); | 607 SkASSERT(r0.fX >= kRadiusMin); |
608 SkASSERT(r0.fY >= kRadiusMin); | 608 SkASSERT(r0.fY >= kRadiusMin); |
609 switch (erre.getRRect().getType()) { | 609 switch (erre.getRRect().getType()) { |
610 case SkRRect::kSimple_Type: | 610 case SkRRect::kSimple_Type: |
611 rect.inset(r0.fX, r0.fY); | 611 rect.inset(r0.fX, r0.fY); |
612 pdman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), | 612 pdman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 if (rrect.isNinePatch()) { | 725 if (rrect.isNinePatch()) { |
726 return EllipticalRRectEffect::Create(edgeType, rrect); | 726 return EllipticalRRectEffect::Create(edgeType, rrect); |
727 } | 727 } |
728 return NULL; | 728 return NULL; |
729 } | 729 } |
730 } | 730 } |
731 } | 731 } |
732 | 732 |
733 return NULL; | 733 return NULL; |
734 } | 734 } |
OLD | NEW |