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 "SkTwoPointConicalGradient_gpu.h" | 8 #include "SkTwoPointConicalGradient_gpu.h" |
9 | 9 |
10 #include "SkTwoPointConicalGradient.h" | 10 #include "SkTwoPointConicalGradient.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 return CreateEffectRef(effect); | 49 return CreateEffectRef(effect); |
50 } | 50 } |
51 | 51 |
52 virtual ~Default2PtConicalEffect() { } | 52 virtual ~Default2PtConicalEffect() { } |
53 | 53 |
54 static const char* Name() { return "Two-Point Conical Gradient"; } | 54 static const char* Name() { return "Two-Point Conical Gradient"; } |
55 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 55 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
56 | 56 |
57 // The radial gradient parameters can collapse to a linear (instead of quadr
atic) equation. | 57 // The radial gradient parameters can collapse to a linear (instead of quadr
atic) equation. |
58 bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(f
CenterX1); } | 58 bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(f
CenterX1); } |
59 bool isFlipped() const { return fIsFlipped; } | |
60 SkScalar center() const { return fCenterX1; } | 59 SkScalar center() const { return fCenterX1; } |
61 SkScalar diffRadius() const { return fDiffRadius; } | 60 SkScalar diffRadius() const { return fDiffRadius; } |
62 SkScalar radius() const { return fRadius0; } | 61 SkScalar radius() const { return fRadius0; } |
63 | 62 |
64 typedef GLDefault2PtConicalEffect GLEffect; | 63 typedef GLDefault2PtConicalEffect GLEffect; |
65 | 64 |
66 private: | 65 private: |
67 virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE { | 66 virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE { |
68 const Default2PtConicalEffect& s = CastEffect<Default2PtConicalEffect>(s
Base); | 67 const Default2PtConicalEffect& s = CastEffect<Default2PtConicalEffect>(s
Base); |
69 return (INHERITED::onIsEqual(sBase) && | 68 return (INHERITED::onIsEqual(sBase) && |
70 this->fCenterX1 == s.fCenterX1 && | 69 this->fCenterX1 == s.fCenterX1 && |
71 this->fRadius0 == s.fRadius0 && | 70 this->fRadius0 == s.fRadius0 && |
72 this->fDiffRadius == s.fDiffRadius && | 71 this->fDiffRadius == s.fDiffRadius); |
73 this->fIsFlipped == s.fIsFlipped); | |
74 } | 72 } |
75 | 73 |
76 Default2PtConicalEffect(GrContext* ctx, | 74 Default2PtConicalEffect(GrContext* ctx, |
77 const SkTwoPointConicalGradient& shader, | 75 const SkTwoPointConicalGradient& shader, |
78 const SkMatrix& matrix, | 76 const SkMatrix& matrix, |
79 SkShader::TileMode tm) | 77 SkShader::TileMode tm) |
80 : INHERITED(ctx, shader, matrix, tm), | 78 : INHERITED(ctx, shader, matrix, tm), |
81 fCenterX1(shader.getCenterX1()), | 79 fCenterX1(shader.getCenterX1()), |
82 fRadius0(shader.getStartRadius()), | 80 fRadius0(shader.getStartRadius()), |
83 fDiffRadius(shader.getDiffRadius()), | 81 fDiffRadius(shader.getDiffRadius()) { |
84 fIsFlipped(shader.isFlippedGrad()) { | |
85 // We pass the linear part of the quadratic as a varying. | 82 // We pass the linear part of the quadratic as a varying. |
86 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) | 83 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) |
87 fBTransform = this->getCoordTransform(); | 84 fBTransform = this->getCoordTransform(); |
88 SkMatrix& bMatrix = *fBTransform.accessMatrix(); | 85 SkMatrix& bMatrix = *fBTransform.accessMatrix(); |
89 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); | 86 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); |
90 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMScaleX]) + | 87 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMScaleX]) + |
91 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp0])); | 88 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp0])); |
92 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatr
ix::kMSkewX]) + | 89 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatr
ix::kMSkewX]) + |
93 SkScalarMul(r0dr, bMatrix[SkMatrix::k
MPersp1])); | 90 SkScalarMul(r0dr, bMatrix[SkMatrix::k
MPersp1])); |
94 bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMTransX]) + | 91 bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMTransX]) + |
95 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp2])); | 92 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp2])); |
96 this->addCoordTransform(&fBTransform); | 93 this->addCoordTransform(&fBTransform); |
97 } | 94 } |
98 | 95 |
99 GR_DECLARE_EFFECT_TEST; | 96 GR_DECLARE_EFFECT_TEST; |
100 | 97 |
101 // @{ | 98 // @{ |
102 // Cache of values - these can change arbitrarily, EXCEPT | 99 // Cache of values - these can change arbitrarily, EXCEPT |
103 // we shouldn't change between degenerate and non-degenerate?! | 100 // we shouldn't change between degenerate and non-degenerate?! |
104 | 101 |
105 GrCoordTransform fBTransform; | 102 GrCoordTransform fBTransform; |
106 SkScalar fCenterX1; | 103 SkScalar fCenterX1; |
107 SkScalar fRadius0; | 104 SkScalar fRadius0; |
108 SkScalar fDiffRadius; | 105 SkScalar fDiffRadius; |
109 bool fIsFlipped; | |
110 | 106 |
111 // @} | 107 // @} |
112 | 108 |
113 typedef GrGradientEffect INHERITED; | 109 typedef GrGradientEffect INHERITED; |
114 }; | 110 }; |
115 | 111 |
116 class GLDefault2PtConicalEffect : public GrGLGradientEffect { | 112 class GLDefault2PtConicalEffect : public GrGLGradientEffect { |
117 public: | 113 public: |
118 GLDefault2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDra
wEffect&); | 114 GLDefault2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDra
wEffect&); |
119 virtual ~GLDefault2PtConicalEffect() { } | 115 virtual ~GLDefault2PtConicalEffect() { } |
120 | 116 |
121 virtual void emitCode(GrGLShaderBuilder*, | 117 virtual void emitCode(GrGLShaderBuilder*, |
122 const GrDrawEffect&, | 118 const GrDrawEffect&, |
123 EffectKey, | 119 EffectKey, |
124 const char* outputColor, | 120 const char* outputColor, |
125 const char* inputColor, | 121 const char* inputColor, |
126 const TransformedCoordsArray&, | 122 const TransformedCoordsArray&, |
127 const TextureSamplerArray&) SK_OVERRIDE; | 123 const TextureSamplerArray&) SK_OVERRIDE; |
128 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 124 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
129 | 125 |
130 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); | 126 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
131 | 127 |
132 protected: | 128 protected: |
133 UniformHandle fParamUni; | 129 UniformHandle fParamUni; |
134 | 130 |
135 const char* fVSVaryingName; | 131 const char* fVSVaryingName; |
136 const char* fFSVaryingName; | 132 const char* fFSVaryingName; |
137 | 133 |
138 bool fIsDegenerate; | 134 bool fIsDegenerate; |
139 bool fIsFlipped; | |
140 | 135 |
141 // @{ | 136 // @{ |
142 /// Values last uploaded as uniforms | 137 /// Values last uploaded as uniforms |
143 | 138 |
144 SkScalar fCachedCenter; | 139 SkScalar fCachedCenter; |
145 SkScalar fCachedRadius; | 140 SkScalar fCachedRadius; |
146 SkScalar fCachedDiffRadius; | 141 SkScalar fCachedDiffRadius; |
147 | 142 |
148 // @} | 143 // @} |
149 | 144 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 const GrDrawEffect& drawEffect) | 187 const GrDrawEffect& drawEffect) |
193 : INHERITED(factory) | 188 : INHERITED(factory) |
194 , fVSVaryingName(NULL) | 189 , fVSVaryingName(NULL) |
195 , fFSVaryingName(NULL) | 190 , fFSVaryingName(NULL) |
196 , fCachedCenter(SK_ScalarMax) | 191 , fCachedCenter(SK_ScalarMax) |
197 , fCachedRadius(-SK_ScalarMax) | 192 , fCachedRadius(-SK_ScalarMax) |
198 , fCachedDiffRadius(-SK_ScalarMax) { | 193 , fCachedDiffRadius(-SK_ScalarMax) { |
199 | 194 |
200 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); | 195 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); |
201 fIsDegenerate = data.isDegenerate(); | 196 fIsDegenerate = data.isDegenerate(); |
202 fIsFlipped = data.isFlipped(); | |
203 } | 197 } |
204 | 198 |
205 void GLDefault2PtConicalEffect::emitCode(GrGLShaderBuilder* builder, | 199 void GLDefault2PtConicalEffect::emitCode(GrGLShaderBuilder* builder, |
206 const GrDrawEffect&, | 200 const GrDrawEffect&, |
207 EffectKey key, | 201 EffectKey key, |
208 const char* outputColor, | 202 const char* outputColor, |
209 const char* inputColor, | 203 const char* inputColor, |
210 const TransformedCoordsArray& coords, | 204 const TransformedCoordsArray& coords, |
211 const TextureSamplerArray& samplers) { | 205 const TextureSamplerArray& samplers) { |
212 this->emitUniforms(builder, key); | 206 this->emitUniforms(builder, key); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 // r0 = q * params[1] | 274 // r0 = q * params[1] |
281 builder->fsCodeAppendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(), | 275 builder->fsCodeAppendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(), |
282 qName.c_str(), p1.c_str()); | 276 qName.c_str(), p1.c_str()); |
283 // r1 = c / q | 277 // r1 = c / q |
284 builder->fsCodeAppendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(), | 278 builder->fsCodeAppendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(), |
285 cName.c_str(), qName.c_str()); | 279 cName.c_str(), qName.c_str()); |
286 | 280 |
287 // Note: If there are two roots that both generate radius(t) > 0, the | 281 // Note: If there are two roots that both generate radius(t) > 0, the |
288 // Canvas spec says to choose the larger t. | 282 // Canvas spec says to choose the larger t. |
289 | 283 |
290 // so we'll look at the larger one first (or smaller if flipped): | 284 // so we'll look at the larger one first: |
291 if (!fIsFlipped) { | 285 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(), |
292 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(
), | 286 r0Name.c_str(), r1Name.c_str()); |
293 r0Name.c_str(), r1Name.c_str()); | |
294 } else { | |
295 builder->fsCodeAppendf("\t\tfloat %s = min(%s, %s);\n", tName.c_str(
), | |
296 r0Name.c_str(), r1Name.c_str()); | |
297 } | |
298 | 287 |
299 // if r(t) > 0, then we're done; t will be our x coordinate | 288 // if r(t) > 0, then we're done; t will be our x coordinate |
300 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), | 289 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), |
301 p5.c_str(), p3.c_str()); | 290 p5.c_str(), p3.c_str()); |
302 | 291 |
303 builder->fsCodeAppend("\t\t"); | 292 builder->fsCodeAppend("\t\t"); |
304 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); | 293 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); |
305 | 294 |
306 // otherwise, if r(t) for the larger root was <= 0, try the other root | 295 // otherwise, if r(t) for the larger root was <= 0, try the other root |
307 builder->fsCodeAppend("\t\t} else {\n"); | 296 builder->fsCodeAppend("\t\t} else {\n"); |
308 if (!fIsFlipped) { | 297 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), |
309 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), | 298 r0Name.c_str(), r1Name.c_str()); |
310 r0Name.c_str(), r1Name.c_str()); | |
311 } else { | |
312 builder->fsCodeAppendf("\t\t\t%s = max(%s, %s);\n", tName.c_str(), | |
313 r0Name.c_str(), r1Name.c_str()); | |
314 } | |
315 | 299 |
316 // if r(t) > 0 for the smaller root, then t will be our x coordinate | 300 // if r(t) > 0 for the smaller root, then t will be our x coordinate |
317 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", | 301 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", |
318 tName.c_str(), p5.c_str(), p3.c_str()); | 302 tName.c_str(), p5.c_str(), p3.c_str()); |
319 | 303 |
320 builder->fsCodeAppend("\t\t\t"); | 304 builder->fsCodeAppend("\t\t\t"); |
321 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); | 305 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); |
322 | 306 |
323 // end if (r(t) > 0) for smaller root | 307 // end if (r(t) > 0) for smaller root |
324 builder->fsCodeAppend("\t\t\t}\n"); | 308 builder->fsCodeAppend("\t\t\t}\n"); |
(...skipping 14 matching lines...) Expand all Loading... |
339 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); | 323 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); |
340 builder->fsCodeAppend("\t}\n"); | 324 builder->fsCodeAppend("\t}\n"); |
341 } | 325 } |
342 } | 326 } |
343 | 327 |
344 void GLDefault2PtConicalEffect::setData(const GrGLUniformManager& uman, | 328 void GLDefault2PtConicalEffect::setData(const GrGLUniformManager& uman, |
345 const GrDrawEffect& drawEffect) { | 329 const GrDrawEffect& drawEffect) { |
346 INHERITED::setData(uman, drawEffect); | 330 INHERITED::setData(uman, drawEffect); |
347 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); | 331 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); |
348 SkASSERT(data.isDegenerate() == fIsDegenerate); | 332 SkASSERT(data.isDegenerate() == fIsDegenerate); |
349 SkASSERT(data.isFlipped() == fIsFlipped); | |
350 SkScalar centerX1 = data.center(); | 333 SkScalar centerX1 = data.center(); |
351 SkScalar radius0 = data.radius(); | 334 SkScalar radius0 = data.radius(); |
352 SkScalar diffRadius = data.diffRadius(); | 335 SkScalar diffRadius = data.diffRadius(); |
353 | 336 |
354 if (fCachedCenter != centerX1 || | 337 if (fCachedCenter != centerX1 || |
355 fCachedRadius != radius0 || | 338 fCachedRadius != radius0 || |
356 fCachedDiffRadius != diffRadius) { | 339 fCachedDiffRadius != diffRadius) { |
357 | 340 |
358 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; | 341 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; |
359 | 342 |
(...skipping 15 matching lines...) Expand all Loading... |
375 fCachedCenter = centerX1; | 358 fCachedCenter = centerX1; |
376 fCachedRadius = radius0; | 359 fCachedRadius = radius0; |
377 fCachedDiffRadius = diffRadius; | 360 fCachedDiffRadius = diffRadius; |
378 } | 361 } |
379 } | 362 } |
380 | 363 |
381 GrGLEffect::EffectKey GLDefault2PtConicalEffect::GenKey(const GrDrawEffect& draw
Effect, | 364 GrGLEffect::EffectKey GLDefault2PtConicalEffect::GenKey(const GrDrawEffect& draw
Effect, |
382 const GrGLCaps&) { | 365 const GrGLCaps&) { |
383 enum { | 366 enum { |
384 kIsDegenerate = 1 << kBaseKeyBitCnt, | 367 kIsDegenerate = 1 << kBaseKeyBitCnt, |
385 kIsFlipped = 1 << (kBaseKeyBitCnt + 1), | |
386 }; | 368 }; |
387 | 369 |
388 EffectKey key = GenBaseGradientKey(drawEffect); | 370 EffectKey key = GenBaseGradientKey(drawEffect); |
389 if (drawEffect.castEffect<Default2PtConicalEffect>().isDegenerate()) { | 371 if (drawEffect.castEffect<Default2PtConicalEffect>().isDegenerate()) { |
390 key |= kIsDegenerate; | 372 key |= kIsDegenerate; |
391 } | 373 } |
392 if (drawEffect.castEffect<Default2PtConicalEffect>().isFlipped()) { | |
393 key |= kIsFlipped; | |
394 } | |
395 return key; | 374 return key; |
396 } | 375 } |
397 | 376 |
398 ////////////////////////////////////////////////////////////////////////////// | 377 ////////////////////////////////////////////////////////////////////////////// |
399 | 378 |
400 GrEffectRef* Gr2PtConicalGradientEffect::Create(GrContext* ctx, | 379 GrEffectRef* Gr2PtConicalGradientEffect::Create(GrContext* ctx, |
401 const SkTwoPointConicalGradient&
shader, | 380 const SkTwoPointConicalGradient&
shader, |
402 SkShader::TileMode tm) { | 381 SkShader::TileMode tm) { |
403 | 382 |
404 SkMatrix matrix; | 383 SkMatrix matrix; |
405 if (!shader.getLocalMatrix().invert(&matrix)) { | 384 if (!shader.getLocalMatrix().invert(&matrix)) { |
406 return NULL; | 385 return NULL; |
407 } | 386 } |
408 | 387 |
409 set_matrix_default_conical(shader, &matrix); | 388 set_matrix_default_conical(shader, &matrix); |
410 return Default2PtConicalEffect::Create(ctx, shader, matrix, tm); | 389 return Default2PtConicalEffect::Create(ctx, shader, matrix, tm); |
411 } | 390 } |
412 | 391 |
413 #endif | 392 #endif |
OLD | NEW |