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 |
11 #include "gl/GrGLEffect.h" | 11 #include "gl/GrGLProcessor.h" |
12 #include "gl/GrGLSL.h" | 12 #include "gl/GrGLSL.h" |
13 #include "GrConvexPolyEffect.h" | 13 #include "GrConvexPolyEffect.h" |
14 #include "GrOvalEffect.h" | 14 #include "GrOvalEffect.h" |
15 #include "GrTBackendEffectFactory.h" | 15 #include "GrTBackendProcessorFactory.h" |
16 | 16 |
17 #include "SkRRect.h" | 17 #include "SkRRect.h" |
18 | 18 |
19 // The effects defined here only handle rrect radii >= kRadiusMin. | 19 // The effects defined here only handle rrect radii >= kRadiusMin. |
20 static const SkScalar kRadiusMin = SK_ScalarHalf; | 20 static const SkScalar kRadiusMin = SK_ScalarHalf; |
21 | 21 |
22 ////////////////////////////////////////////////////////////////////////////// | 22 ////////////////////////////////////////////////////////////////////////////// |
23 | 23 |
24 class GLCircularRRectEffect; | 24 class GLCircularRRectEffect; |
25 | 25 |
26 class CircularRRectEffect : public GrEffect { | 26 class CircularRRectEffect : public GrFragmentProcessor { |
27 public: | 27 public: |
28 | 28 |
29 enum CornerFlags { | 29 enum CornerFlags { |
30 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), | 30 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), |
31 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), | 31 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), |
32 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), | 32 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), |
33 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), | 33 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), |
34 | 34 |
35 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, | 35 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, |
36 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, | 36 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, |
37 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, | 37 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, |
38 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 38 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
39 | 39 |
40 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | | 40 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | |
41 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 41 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
42 | 42 |
43 kNone_CornerFlags = 0 | 43 kNone_CornerFlags = 0 |
44 }; | 44 }; |
45 | 45 |
46 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to | 46 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to |
47 // be square). | 47 // be square). |
48 static GrEffect* Create(GrEffectEdgeType, uint32_t circularCornerFlags, cons
t SkRRect&); | 48 static GrFragmentProcessor* Create(GrProcessorEdgeType, uint32_t circularCor
nerFlags, |
| 49 const SkRRect&); |
49 | 50 |
50 virtual ~CircularRRectEffect() {}; | 51 virtual ~CircularRRectEffect() {}; |
51 static const char* Name() { return "CircularRRect"; } | 52 static const char* Name() { return "CircularRRect"; } |
52 | 53 |
53 const SkRRect& getRRect() const { return fRRect; } | 54 const SkRRect& getRRect() const { return fRRect; } |
54 | 55 |
55 uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; } | 56 uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; } |
56 | 57 |
57 GrEffectEdgeType getEdgeType() const { return fEdgeType; } | 58 GrProcessorEdgeType getEdgeType() const { return fEdgeType; } |
58 | 59 |
59 typedef GLCircularRRectEffect GLEffect; | 60 typedef GLCircularRRectEffect GLProcessor; |
60 | 61 |
61 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 62 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
62 | 63 |
63 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 64 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
64 | 65 |
65 private: | 66 private: |
66 CircularRRectEffect(GrEffectEdgeType, uint32_t circularCornerFlags, const Sk
RRect&); | 67 CircularRRectEffect(GrProcessorEdgeType, uint32_t circularCornerFlags, const
SkRRect&); |
67 | 68 |
68 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 69 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; |
69 | 70 |
70 SkRRect fRRect; | 71 SkRRect fRRect; |
71 GrEffectEdgeType fEdgeType; | 72 GrProcessorEdgeType fEdgeType; |
72 uint32_t fCircularCornerFlags; | 73 uint32_t fCircularCornerFlags; |
73 | 74 |
74 GR_DECLARE_EFFECT_TEST; | 75 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
75 | 76 |
76 typedef GrEffect INHERITED; | 77 typedef GrFragmentProcessor INHERITED; |
77 }; | 78 }; |
78 | 79 |
79 GrEffect* CircularRRectEffect::Create(GrEffectEdgeType edgeType, | 80 GrFragmentProcessor* CircularRRectEffect::Create(GrProcessorEdgeType edgeType, |
80 uint32_t circularCornerFlags, | 81 uint32_t circularCornerFlags, |
81 const SkRRect& rrect) { | 82 const SkRRect& rrect) { |
82 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { | 83 if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdg
eType != edgeType) { |
83 return NULL; | 84 return NULL; |
84 } | 85 } |
85 return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect
)); | 86 return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect
)); |
86 } | 87 } |
87 | 88 |
88 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { | 89 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { |
89 *validFlags = 0; | 90 *validFlags = 0; |
90 } | 91 } |
91 | 92 |
92 const GrBackendEffectFactory& CircularRRectEffect::getFactory() const { | 93 const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const
{ |
93 return GrTBackendEffectFactory<CircularRRectEffect>::getInstance(); | 94 return GrTBackendFragmentProcessorFactory<CircularRRectEffect>::getInstance(
); |
94 } | 95 } |
95 | 96 |
96 CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t cir
cularCornerFlags, | 97 CircularRRectEffect::CircularRRectEffect(GrProcessorEdgeType edgeType, uint32_t
circularCornerFlags, |
97 const SkRRect& rrect) | 98 const SkRRect& rrect) |
98 : fRRect(rrect) | 99 : fRRect(rrect) |
99 , fEdgeType(edgeType) | 100 , fEdgeType(edgeType) |
100 , fCircularCornerFlags(circularCornerFlags) { | 101 , fCircularCornerFlags(circularCornerFlags) { |
101 this->setWillReadFragmentPosition(); | 102 this->setWillReadFragmentPosition(); |
102 } | 103 } |
103 | 104 |
104 bool CircularRRectEffect::onIsEqual(const GrEffect& other) const { | 105 bool CircularRRectEffect::onIsEqual(const GrProcessor& other) const { |
105 const CircularRRectEffect& crre = other.cast<CircularRRectEffect>(); | 106 const CircularRRectEffect& crre = other.cast<CircularRRectEffect>(); |
106 // The corner flags are derived from fRRect, so no need to check them. | 107 // The corner flags are derived from fRRect, so no need to check them. |
107 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; | 108 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; |
108 } | 109 } |
109 | 110 |
110 ////////////////////////////////////////////////////////////////////////////// | 111 ////////////////////////////////////////////////////////////////////////////// |
111 | 112 |
112 GR_DEFINE_EFFECT_TEST(CircularRRectEffect); | 113 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircularRRectEffect); |
113 | 114 |
114 GrEffect* CircularRRectEffect::TestCreate(SkRandom* random, | 115 GrFragmentProcessor* CircularRRectEffect::TestCreate(SkRandom* random, |
115 GrContext*, | 116 GrContext*, |
116 const GrDrawTargetCaps& caps, | 117 const GrDrawTargetCaps& cap
s, |
117 GrTexture*[]) { | 118 GrTexture*[]) { |
118 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 119 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
119 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 120 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
120 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); | 121 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); |
121 SkRRect rrect; | 122 SkRRect rrect; |
122 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 123 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
123 GrEffect* effect; | 124 GrFragmentProcessor* fp; |
124 do { | 125 do { |
125 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 126 GrProcessorEdgeType et = |
126 effect = GrRRectEffect::Create(et, rrect); | 127 (GrProcessorEdgeType)random->nextULessThan(kGrProcessorEdgeTypeC
nt); |
127 } while (NULL == effect); | 128 fp = GrRRectEffect::Create(et, rrect); |
128 return effect; | 129 } while (NULL == fp); |
| 130 return fp; |
129 } | 131 } |
130 | 132 |
131 ////////////////////////////////////////////////////////////////////////////// | 133 ////////////////////////////////////////////////////////////////////////////// |
132 | 134 |
133 class GLCircularRRectEffect : public GrGLEffect { | 135 class GLCircularRRectEffect : public GrGLFragmentProcessor { |
134 public: | 136 public: |
135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrEffect&); | 137 GLCircularRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&); |
136 | 138 |
137 virtual void emitCode(GrGLProgramBuilder* builder, | 139 virtual void emitCode(GrGLProgramBuilder* builder, |
138 const GrEffect& effect, | 140 const GrFragmentProcessor& fp, |
139 const GrEffectKey& key, | 141 const GrProcessorKey& key, |
140 const char* outputColor, | 142 const char* outputColor, |
141 const char* inputColor, | 143 const char* inputColor, |
142 const TransformedCoordsArray&, | 144 const TransformedCoordsArray&, |
143 const TextureSamplerArray&) SK_OVERRIDE; | 145 const TextureSamplerArray&) SK_OVERRIDE; |
144 | 146 |
145 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); | 147 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); |
146 | 148 |
147 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 149 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
148 | 150 |
149 private: | 151 private: |
150 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 152 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; | 153 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; |
152 SkRRect fPrevRRect; | 154 SkRRect fPrevRRect; |
153 typedef GrGLEffect INHERITED; | 155 typedef GrGLFragmentProcessor INHERITED; |
154 }; | 156 }; |
155 | 157 |
156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto
ry, | 158 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendProcessorFactory& fa
ctory, |
157 const GrEffect& effect) | 159 const GrProcessor& ) |
158 : INHERITED (factory) { | 160 : INHERITED (factory) { |
159 fPrevRRect.setEmpty(); | 161 fPrevRRect.setEmpty(); |
160 } | 162 } |
161 | 163 |
162 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, | 164 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, |
163 const GrEffect& effect, | 165 const GrFragmentProcessor& fp, |
164 const GrEffectKey& key, | 166 const GrProcessorKey& key, |
165 const char* outputColor, | 167 const char* outputColor, |
166 const char* inputColor, | 168 const char* inputColor, |
167 const TransformedCoordsArray&, | 169 const TransformedCoordsArray&, |
168 const TextureSamplerArray& samplers) { | 170 const TextureSamplerArray& samplers) { |
169 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 171 const CircularRRectEffect& crre = fp.cast<CircularRRectEffect>(); |
170 const char *rectName; | 172 const char *rectName; |
171 const char *radiusPlusHalfName; | 173 const char *radiusPlusHalfName; |
172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom | 174 // 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 | 175 // 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 | 176 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by |
175 // half a pixel. | 177 // half a pixel. |
176 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 178 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
177 kVec4f_GrSLType, | 179 kVec4f_GrSLType, |
178 "innerRect", | 180 "innerRect", |
179 &rectName); | 181 &rectName); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); | 280 fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); |
279 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); | 281 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); |
280 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); | 282 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); |
281 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", | 283 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", |
282 fragmentPos, rectName); | 284 fragmentPos, rectName); |
283 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", | 285 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", |
284 radiusPlusHalfName); | 286 radiusPlusHalfName); |
285 break; | 287 break; |
286 } | 288 } |
287 | 289 |
288 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { | 290 if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) { |
289 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); | 291 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); |
290 } | 292 } |
291 | 293 |
292 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 294 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
293 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 295 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
294 } | 296 } |
295 | 297 |
296 void GLCircularRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, | 298 void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&
, |
297 GrEffectKeyBuilder* b) { | 299 GrProcessorKeyBuilder* b) { |
298 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 300 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); |
299 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); | 301 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); |
300 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); | 302 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); |
301 } | 303 } |
302 | 304 |
303 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, | 305 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, |
304 const GrEffect& effect) { | 306 const GrProcessor& processor) { |
305 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 307 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); |
306 const SkRRect& rrect = crre.getRRect(); | 308 const SkRRect& rrect = crre.getRRect(); |
307 if (rrect != fPrevRRect) { | 309 if (rrect != fPrevRRect) { |
308 SkRect rect = rrect.getBounds(); | 310 SkRect rect = rrect.getBounds(); |
309 SkScalar radius = 0; | 311 SkScalar radius = 0; |
310 switch (crre.getCircularCornerFlags()) { | 312 switch (crre.getCircularCornerFlags()) { |
311 case CircularRRectEffect::kAll_CornerFlags: | 313 case CircularRRectEffect::kAll_CornerFlags: |
312 SkASSERT(rrect.isSimpleCircular()); | 314 SkASSERT(rrect.isSimpleCircular()); |
313 radius = rrect.getSimpleRadii().fX; | 315 radius = rrect.getSimpleRadii().fX; |
314 SkASSERT(radius >= kRadiusMin); | 316 SkASSERT(radius >= kRadiusMin); |
315 rect.inset(radius, radius); | 317 rect.inset(radius, radius); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); | 378 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); |
377 pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); | 379 pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); |
378 fPrevRRect = rrect; | 380 fPrevRRect = rrect; |
379 } | 381 } |
380 } | 382 } |
381 | 383 |
382 ////////////////////////////////////////////////////////////////////////////// | 384 ////////////////////////////////////////////////////////////////////////////// |
383 | 385 |
384 class GLEllipticalRRectEffect; | 386 class GLEllipticalRRectEffect; |
385 | 387 |
386 class EllipticalRRectEffect : public GrEffect { | 388 class EllipticalRRectEffect : public GrFragmentProcessor { |
387 public: | 389 public: |
388 static GrEffect* Create(GrEffectEdgeType, const SkRRect&); | 390 static GrFragmentProcessor* Create(GrProcessorEdgeType, const SkRRect&); |
389 | 391 |
390 virtual ~EllipticalRRectEffect() {}; | 392 virtual ~EllipticalRRectEffect() {}; |
391 static const char* Name() { return "EllipticalRRect"; } | 393 static const char* Name() { return "EllipticalRRect"; } |
392 | 394 |
393 const SkRRect& getRRect() const { return fRRect; } | 395 const SkRRect& getRRect() const { return fRRect; } |
394 | 396 |
395 | 397 |
396 GrEffectEdgeType getEdgeType() const { return fEdgeType; } | 398 GrProcessorEdgeType getEdgeType() const { return fEdgeType; } |
397 | 399 |
398 typedef GLEllipticalRRectEffect GLEffect; | 400 typedef GLEllipticalRRectEffect GLProcessor; |
399 | 401 |
400 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 402 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
401 | 403 |
402 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 404 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
403 | 405 |
404 private: | 406 private: |
405 EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&); | 407 EllipticalRRectEffect(GrProcessorEdgeType, const SkRRect&); |
406 | 408 |
407 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 409 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; |
408 | 410 |
409 SkRRect fRRect; | 411 SkRRect fRRect; |
410 GrEffectEdgeType fEdgeType; | 412 GrProcessorEdgeType fEdgeType; |
411 | 413 |
412 GR_DECLARE_EFFECT_TEST; | 414 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
413 | 415 |
414 typedef GrEffect INHERITED; | 416 typedef GrFragmentProcessor INHERITED; |
415 }; | 417 }; |
416 | 418 |
417 GrEffect* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect
& rrect) { | 419 GrFragmentProcessor* |
418 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { | 420 EllipticalRRectEffect::Create(GrProcessorEdgeType edgeType, const SkRRect& rrect
) { |
| 421 if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdg
eType != edgeType) { |
419 return NULL; | 422 return NULL; |
420 } | 423 } |
421 return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)); | 424 return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)); |
422 } | 425 } |
423 | 426 |
424 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { | 427 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { |
425 *validFlags = 0; | 428 *validFlags = 0; |
426 } | 429 } |
427 | 430 |
428 const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { | 431 const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() con
st { |
429 return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance(); | 432 return GrTBackendFragmentProcessorFactory<EllipticalRRectEffect>::getInstanc
e(); |
430 } | 433 } |
431 | 434 |
432 EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const Sk
RRect& rrect) | 435 EllipticalRRectEffect::EllipticalRRectEffect(GrProcessorEdgeType edgeType, const
SkRRect& rrect) |
433 : fRRect(rrect) | 436 : fRRect(rrect) |
434 , fEdgeType(edgeType){ | 437 , fEdgeType(edgeType){ |
435 this->setWillReadFragmentPosition(); | 438 this->setWillReadFragmentPosition(); |
436 } | 439 } |
437 | 440 |
438 bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { | 441 bool EllipticalRRectEffect::onIsEqual(const GrProcessor& other) const { |
439 const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>(); | 442 const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>(); |
440 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; | 443 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; |
441 } | 444 } |
442 | 445 |
443 ////////////////////////////////////////////////////////////////////////////// | 446 ////////////////////////////////////////////////////////////////////////////// |
444 | 447 |
445 GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect); | 448 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipticalRRectEffect); |
446 | 449 |
447 GrEffect* EllipticalRRectEffect::TestCreate(SkRandom* random, | 450 GrFragmentProcessor* EllipticalRRectEffect::TestCreate(SkRandom* random, |
448 GrContext*, | 451 GrContext*, |
449 const GrDrawTargetCaps& caps, | 452 const GrDrawTargetCaps& c
aps, |
450 GrTexture*[]) { | 453 GrTexture*[]) { |
451 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 454 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
452 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 455 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
453 SkVector r[4]; | 456 SkVector r[4]; |
454 r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); | 457 r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); |
455 // ensure at least one corner really is elliptical | 458 // ensure at least one corner really is elliptical |
456 do { | 459 do { |
457 r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); | 460 r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); |
458 } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].f
X); | 461 } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].f
X); |
459 | 462 |
460 SkRRect rrect; | 463 SkRRect rrect; |
461 if (random->nextBool()) { | 464 if (random->nextBool()) { |
462 // half the time create a four-radii rrect. | 465 // half the time create a four-radii rrect. |
463 r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); | 466 r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); |
464 r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); | 467 r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); |
465 | 468 |
466 r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; | 469 r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; |
467 r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; | 470 r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; |
468 | 471 |
469 r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; | 472 r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; |
470 r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; | 473 r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; |
471 | 474 |
472 rrect.setRectRadii(SkRect::MakeWH(w, h), r); | 475 rrect.setRectRadii(SkRect::MakeWH(w, h), r); |
473 } else { | 476 } else { |
474 rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, | 477 rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, |
475 r[SkRRect::kUpperLeft_Corner].fY); | 478 r[SkRRect::kUpperLeft_Corner].fY); |
476 } | 479 } |
477 GrEffect* effect; | 480 GrFragmentProcessor* fp; |
478 do { | 481 do { |
479 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 482 GrProcessorEdgeType et = (GrProcessorEdgeType)random->nextULessThan(kGrP
rocessorEdgeTypeCnt); |
480 effect = GrRRectEffect::Create(et, rrect); | 483 fp = GrRRectEffect::Create(et, rrect); |
481 } while (NULL == effect); | 484 } while (NULL == fp); |
482 return effect; | 485 return fp; |
483 } | 486 } |
484 | 487 |
485 ////////////////////////////////////////////////////////////////////////////// | 488 ////////////////////////////////////////////////////////////////////////////// |
486 | 489 |
487 class GLEllipticalRRectEffect : public GrGLEffect { | 490 class GLEllipticalRRectEffect : public GrGLFragmentProcessor { |
488 public: | 491 public: |
489 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrEffect&); | 492 GLEllipticalRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&
); |
490 | 493 |
491 virtual void emitCode(GrGLProgramBuilder* builder, | 494 virtual void emitCode(GrGLProgramBuilder* builder, |
492 const GrEffect& effect, | 495 const GrFragmentProcessor& effect, |
493 const GrEffectKey& key, | 496 const GrProcessorKey& key, |
494 const char* outputColor, | 497 const char* outputColor, |
495 const char* inputColor, | 498 const char* inputColor, |
496 const TransformedCoordsArray&, | 499 const TransformedCoordsArray&, |
497 const TextureSamplerArray&) SK_OVERRIDE; | 500 const TextureSamplerArray&) SK_OVERRIDE; |
498 | 501 |
499 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); | 502 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); |
500 | 503 |
501 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 504 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
502 | 505 |
503 private: | 506 private: |
504 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 507 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
505 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; | 508 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; |
506 SkRRect fPrevRRect; | 509 SkRRect fPrevRRect; |
507 typedef GrGLEffect INHERITED; | 510 typedef GrGLFragmentProcessor INHERITED; |
508 }; | 511 }; |
509 | 512 |
510 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f
actory, | 513 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendProcessorFactory
& factory, |
511 const GrEffect& effect) | 514 const GrProcessor& effect) |
512 : INHERITED (factory) { | 515 : INHERITED (factory) { |
513 fPrevRRect.setEmpty(); | 516 fPrevRRect.setEmpty(); |
514 } | 517 } |
515 | 518 |
516 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, | 519 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, |
517 const GrEffect& effect, | 520 const GrFragmentProcessor& effect, |
518 const GrEffectKey& key, | 521 const GrProcessorKey& key, |
519 const char* outputColor, | 522 const char* outputColor, |
520 const char* inputColor, | 523 const char* inputColor, |
521 const TransformedCoordsArray&, | 524 const TransformedCoordsArray&, |
522 const TextureSamplerArray& samplers) { | 525 const TextureSamplerArray& samplers) { |
523 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 526 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
524 const char *rectName; | 527 const char *rectName; |
525 // The inner rect is the rrect bounds inset by the x/y radii | 528 // The inner rect is the rrect bounds inset by the x/y radii |
526 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 529 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
527 kVec4f_GrSLType, | 530 kVec4f_GrSLType, |
528 "innerRect", | 531 "innerRect", |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 SkFAIL("RRect should always be simple or nine-patch."); | 576 SkFAIL("RRect should always be simple or nine-patch."); |
574 } | 577 } |
575 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. | 578 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. |
576 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); | 579 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); |
577 // grad_dot is the squared length of the gradient of the implicit. | 580 // grad_dot is the squared length of the gradient of the implicit. |
578 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); | 581 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); |
579 // avoid calling inversesqrt on zero. | 582 // avoid calling inversesqrt on zero. |
580 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 583 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
581 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); | 584 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); |
582 | 585 |
583 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { | 586 if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) { |
584 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); | 587 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); |
585 } else { | 588 } else { |
586 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); | 589 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); |
587 } | 590 } |
588 | 591 |
589 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 592 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
590 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 593 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
591 } | 594 } |
592 | 595 |
593 void GLEllipticalRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, | 596 void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLCaps&, |
594 GrEffectKeyBuilder* b) { | 597 GrProcessorKeyBuilder* b) { |
595 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 598 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
596 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); | 599 GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3)); |
597 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); | 600 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); |
598 } | 601 } |
599 | 602 |
600 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, | 603 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, |
601 const GrEffect& effect) { | 604 const GrProcessor& effect) { |
602 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 605 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
603 const SkRRect& rrect = erre.getRRect(); | 606 const SkRRect& rrect = erre.getRRect(); |
604 if (rrect != fPrevRRect) { | 607 if (rrect != fPrevRRect) { |
605 SkRect rect = rrect.getBounds(); | 608 SkRect rect = rrect.getBounds(); |
606 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); | 609 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); |
607 SkASSERT(r0.fX >= kRadiusMin); | 610 SkASSERT(r0.fX >= kRadiusMin); |
608 SkASSERT(r0.fY >= kRadiusMin); | 611 SkASSERT(r0.fY >= kRadiusMin); |
609 switch (erre.getRRect().getType()) { | 612 switch (erre.getRRect().getType()) { |
610 case SkRRect::kSimple_Type: | 613 case SkRRect::kSimple_Type: |
611 rect.inset(r0.fX, r0.fY); | 614 rect.inset(r0.fX, r0.fY); |
(...skipping 17 matching lines...) Expand all Loading... |
629 default: | 632 default: |
630 SkFAIL("RRect should always be simple or nine-patch."); | 633 SkFAIL("RRect should always be simple or nine-patch."); |
631 } | 634 } |
632 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); | 635 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); |
633 fPrevRRect = rrect; | 636 fPrevRRect = rrect; |
634 } | 637 } |
635 } | 638 } |
636 | 639 |
637 ////////////////////////////////////////////////////////////////////////////// | 640 ////////////////////////////////////////////////////////////////////////////// |
638 | 641 |
639 GrEffect* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rrect)
{ | 642 GrFragmentProcessor* GrRRectEffect::Create(GrProcessorEdgeType edgeType, const S
kRRect& rrect) { |
640 if (rrect.isRect()) { | 643 if (rrect.isRect()) { |
641 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); | 644 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); |
642 } | 645 } |
643 | 646 |
644 if (rrect.isOval()) { | 647 if (rrect.isOval()) { |
645 return GrOvalEffect::Create(edgeType, rrect.getBounds()); | 648 return GrOvalEffect::Create(edgeType, rrect.getBounds()); |
646 } | 649 } |
647 | 650 |
648 if (rrect.isSimple()) { | 651 if (rrect.isSimple()) { |
649 if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY
< kRadiusMin) { | 652 if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY
< kRadiusMin) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 if (rrect.isNinePatch()) { | 728 if (rrect.isNinePatch()) { |
726 return EllipticalRRectEffect::Create(edgeType, rrect); | 729 return EllipticalRRectEffect::Create(edgeType, rrect); |
727 } | 730 } |
728 return NULL; | 731 return NULL; |
729 } | 732 } |
730 } | 733 } |
731 } | 734 } |
732 | 735 |
733 return NULL; | 736 return NULL; |
734 } | 737 } |
OLD | NEW |