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 #if SK_SUPPORT_GPU | 8 #if SK_SUPPORT_GPU |
8 #include "SkTwoPointConicalGradient_gpu.h" | 9 #include "SkTwoPointConicalGradient_gpu.h" |
9 #include "GrTBackendEffectFactory.h" | 10 #include "GrTBackendEffectFactory.h" |
10 | 11 |
11 #include "SkTwoPointConicalGradient.h" | 12 #include "SkTwoPointConicalGradient.h" |
12 | 13 |
13 // For brevity | 14 // For brevity |
14 typedef GrGLUniformManager::UniformHandle UniformHandle; | 15 typedef GrGLUniformManager::UniformHandle UniformHandle; |
15 | 16 |
16 class GrGL2PtConicalGradientEffect : public GrGLGradientEffect { | 17 ////////////////////////////////////////////////////////////////////////////// |
| 18 |
| 19 static void set_matrix_default_conical(const SkTwoPointConicalGradient& shader, |
| 20 SkMatrix* invLMatrix) { |
| 21 // Inverse of the current local matrix is passed in then, |
| 22 // translate to center1, rotate so center2 is on x axis. |
| 23 const SkPoint& center1 = shader.getStartCenter(); |
| 24 const SkPoint& center2 = shader.getEndCenter(); |
| 25 |
| 26 invLMatrix->postTranslate(-center1.fX, -center1.fY); |
| 27 |
| 28 SkPoint diff = center2 - center1; |
| 29 SkScalar diffLen = diff.length(); |
| 30 if (0 != diffLen) { |
| 31 SkScalar invDiffLen = SkScalarInvert(diffLen); |
| 32 SkMatrix rot; |
| 33 rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY), |
| 34 SkScalarMul(invDiffLen, diff.fX)); |
| 35 invLMatrix->postConcat(rot); |
| 36 } |
| 37 } |
| 38 |
| 39 class GLDefault2PtConicalEffect; |
| 40 |
| 41 class Default2PtConicalEffect : public GrGradientEffect { |
17 public: | 42 public: |
18 | 43 |
19 GrGL2PtConicalGradientEffect(const GrBackendEffectFactory& factory, const Gr
DrawEffect&); | 44 static GrEffectRef* Create(GrContext* ctx, |
20 virtual ~GrGL2PtConicalGradientEffect() { } | 45 const SkTwoPointConicalGradient& shader, |
| 46 const SkMatrix& matrix, |
| 47 SkShader::TileMode tm) { |
| 48 AutoEffectUnref effect(SkNEW_ARGS(Default2PtConicalEffect, (ctx, shader,
matrix, tm))); |
| 49 return CreateEffectRef(effect); |
| 50 } |
| 51 |
| 52 virtual ~Default2PtConicalEffect() { } |
| 53 |
| 54 static const char* Name() { return "Two-Point Conical Gradient"; } |
| 55 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 56 |
| 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); } |
| 59 SkScalar center() const { return fCenterX1; } |
| 60 SkScalar diffRadius() const { return fDiffRadius; } |
| 61 SkScalar radius() const { return fRadius0; } |
| 62 |
| 63 typedef GLDefault2PtConicalEffect GLEffect; |
| 64 |
| 65 private: |
| 66 virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE { |
| 67 const Default2PtConicalEffect& s = CastEffect<Default2PtConicalEffect>(s
Base); |
| 68 return (INHERITED::onIsEqual(sBase) && |
| 69 this->fCenterX1 == s.fCenterX1 && |
| 70 this->fRadius0 == s.fRadius0 && |
| 71 this->fDiffRadius == s.fDiffRadius); |
| 72 } |
| 73 |
| 74 Default2PtConicalEffect(GrContext* ctx, |
| 75 const SkTwoPointConicalGradient& shader, |
| 76 const SkMatrix& matrix, |
| 77 SkShader::TileMode tm) |
| 78 : INHERITED(ctx, shader, matrix, tm), |
| 79 fCenterX1(shader.getCenterX1()), |
| 80 fRadius0(shader.getStartRadius()), |
| 81 fDiffRadius(shader.getDiffRadius()) { |
| 82 // We pass the linear part of the quadratic as a varying. |
| 83 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) |
| 84 fBTransform = this->getCoordTransform(); |
| 85 SkMatrix& bMatrix = *fBTransform.accessMatrix(); |
| 86 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); |
| 87 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMScaleX]) + |
| 88 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp0])); |
| 89 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatr
ix::kMSkewX]) + |
| 90 SkScalarMul(r0dr, bMatrix[SkMatrix::k
MPersp1])); |
| 91 bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat
rix::kMTransX]) + |
| 92 SkScalarMul(r0dr, bMatrix[SkMatrix::
kMPersp2])); |
| 93 this->addCoordTransform(&fBTransform); |
| 94 } |
| 95 |
| 96 GR_DECLARE_EFFECT_TEST; |
| 97 |
| 98 // @{ |
| 99 // Cache of values - these can change arbitrarily, EXCEPT |
| 100 // we shouldn't change between degenerate and non-degenerate?! |
| 101 |
| 102 GrCoordTransform fBTransform; |
| 103 SkScalar fCenterX1; |
| 104 SkScalar fRadius0; |
| 105 SkScalar fDiffRadius; |
| 106 |
| 107 // @} |
| 108 |
| 109 typedef GrGradientEffect INHERITED; |
| 110 }; |
| 111 |
| 112 class GLDefault2PtConicalEffect : public GrGLGradientEffect { |
| 113 public: |
| 114 GLDefault2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDra
wEffect&); |
| 115 virtual ~GLDefault2PtConicalEffect() { } |
21 | 116 |
22 virtual void emitCode(GrGLShaderBuilder*, | 117 virtual void emitCode(GrGLShaderBuilder*, |
23 const GrDrawEffect&, | 118 const GrDrawEffect&, |
24 EffectKey, | 119 EffectKey, |
25 const char* outputColor, | 120 const char* outputColor, |
26 const char* inputColor, | 121 const char* inputColor, |
27 const TransformedCoordsArray&, | 122 const TransformedCoordsArray&, |
28 const TextureSamplerArray&) SK_OVERRIDE; | 123 const TextureSamplerArray&) SK_OVERRIDE; |
29 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 124 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
30 | 125 |
31 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); | 126 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
32 | 127 |
33 protected: | 128 protected: |
34 | |
35 UniformHandle fParamUni; | 129 UniformHandle fParamUni; |
36 | 130 |
37 const char* fVSVaryingName; | 131 const char* fVSVaryingName; |
38 const char* fFSVaryingName; | 132 const char* fFSVaryingName; |
39 | 133 |
40 bool fIsDegenerate; | 134 bool fIsDegenerate; |
41 | 135 |
42 // @{ | 136 // @{ |
43 /// Values last uploaded as uniforms | 137 /// Values last uploaded as uniforms |
44 | 138 |
45 SkScalar fCachedCenter; | 139 SkScalar fCachedCenter; |
46 SkScalar fCachedRadius; | 140 SkScalar fCachedRadius; |
47 SkScalar fCachedDiffRadius; | 141 SkScalar fCachedDiffRadius; |
48 | 142 |
49 // @} | 143 // @} |
50 | 144 |
51 private: | 145 private: |
52 | |
53 typedef GrGLGradientEffect INHERITED; | 146 typedef GrGLGradientEffect INHERITED; |
54 | 147 |
55 }; | 148 }; |
56 | 149 |
57 const GrBackendEffectFactory& Gr2PtConicalGradientEffect::getFactory() const { | 150 const GrBackendEffectFactory& Default2PtConicalEffect::getFactory() const { |
58 return GrTBackendEffectFactory<Gr2PtConicalGradientEffect>::getInstance(); | 151 return GrTBackendEffectFactory<Default2PtConicalEffect>::getInstance(); |
59 } | 152 } |
60 | 153 |
61 Gr2PtConicalGradientEffect::Gr2PtConicalGradientEffect(GrContext* ctx, | 154 GR_DEFINE_EFFECT_TEST(Default2PtConicalEffect); |
62 const SkTwoPointConical
Gradient& shader, | |
63 const SkMatrix& matrix, | |
64 SkShader::TileMode tm)
: | |
65 INHERITED(ctx, shader, matrix, tm), | |
66 fCenterX1(shader.getCenterX1()), | |
67 fRadius0(shader.getStartRadius()), | |
68 fDiffRadius(shader.getDiffRadius()) { | |
69 // We pass the linear part of the quadratic as a varying. | |
70 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) | |
71 fBTransform = this->getCoordTransform(); | |
72 SkMatrix& bMatrix = *fBTransform.accessMatrix(); | |
73 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); | |
74 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix:
:kMScaleX]) + | |
75 SkScalarMul(r0dr, bMatrix[SkMatrix::kMPe
rsp0])); | |
76 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::
kMSkewX]) + | |
77 SkScalarMul(r0dr, bMatrix[SkMatrix::kMPer
sp1])); | |
78 bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix:
:kMTransX]) + | |
79 SkScalarMul(r0dr, bMatrix[SkMatrix::kMPe
rsp2])); | |
80 this->addCoordTransform(&fBTransform); | |
81 } | |
82 | 155 |
83 GR_DEFINE_EFFECT_TEST(Gr2PtConicalGradientEffect); | 156 GrEffectRef* Default2PtConicalEffect::TestCreate(SkRandom* random, |
84 | |
85 GrEffectRef* Gr2PtConicalGradientEffect::TestCreate(SkRandom* random, | |
86 GrContext* context, | 157 GrContext* context, |
87 const GrDrawTargetCaps&, | 158 const GrDrawTargetCaps&, |
88 GrTexture**) { | 159 GrTexture**) { |
89 SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()}; | 160 SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()}; |
90 SkScalar radius1 = random->nextUScalar1(); | 161 SkScalar radius1 = random->nextUScalar1(); |
91 SkPoint center2; | 162 SkPoint center2; |
92 SkScalar radius2; | 163 SkScalar radius2; |
93 do { | 164 do { |
94 center2.set(random->nextUScalar1(), random->nextUScalar1()); | 165 center2.set(random->nextUScalar1(), random->nextUScalar1()); |
95 radius2 = random->nextUScalar1 (); | 166 radius2 = random->nextUScalar1 (); |
96 // If the circles are identical the factory will give us an empty shader
. | 167 // If the circles are identical the factory will give us an empty shader
. |
97 } while (radius1 == radius2 && center1 == center2); | 168 } while (radius1 == radius2 && center1 == center2); |
98 | 169 |
99 SkColor colors[kMaxRandomGradientColors]; | 170 SkColor colors[kMaxRandomGradientColors]; |
100 SkScalar stopsArray[kMaxRandomGradientColors]; | 171 SkScalar stopsArray[kMaxRandomGradientColors]; |
101 SkScalar* stops = stopsArray; | 172 SkScalar* stops = stopsArray; |
102 SkShader::TileMode tm; | 173 SkShader::TileMode tm; |
103 int colorCount = RandomGradientParams(random, colors, &stops, &tm); | 174 int colorCount = RandomGradientParams(random, colors, &stops, &tm); |
104 SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center
1, radius1, | 175 SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center
1, radius1, |
105 center
2, radius2, | 176 center
2, radius2, |
106 colors
, stops, colorCount, | 177 colors
, stops, colorCount, |
107 tm)); | 178 tm)); |
108 SkPaint paint; | 179 SkPaint paint; |
109 return shader->asNewEffect(context, paint); | 180 return shader->asNewEffect(context, paint); |
110 } | 181 } |
111 | 182 |
112 | 183 |
113 ///////////////////////////////////////////////////////////////////// | 184 ///////////////////////////////////////////////////////////////////// |
114 | 185 |
115 GrGL2PtConicalGradientEffect::GrGL2PtConicalGradientEffect(const GrBackendEffect
Factory& factory, | 186 GLDefault2PtConicalEffect::GLDefault2PtConicalEffect(const GrBackendEffectFactor
y& factory, |
116 const GrDrawEffect& drawEffect) | 187 const GrDrawEffect& drawEffect) |
117 : INHERITED(factory) | 188 : INHERITED(factory) |
118 , fVSVaryingName(NULL) | 189 , fVSVaryingName(NULL) |
119 , fFSVaryingName(NULL) | 190 , fFSVaryingName(NULL) |
120 , fCachedCenter(SK_ScalarMax) | 191 , fCachedCenter(SK_ScalarMax) |
121 , fCachedRadius(-SK_ScalarMax) | 192 , fCachedRadius(-SK_ScalarMax) |
122 , fCachedDiffRadius(-SK_ScalarMax) { | 193 , fCachedDiffRadius(-SK_ScalarMax) { |
123 | 194 |
124 const Gr2PtConicalGradientEffect& data = drawEffect.castEffect<Gr2PtConicalG
radientEffect>(); | 195 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); |
125 fIsDegenerate = data.isDegenerate(); | 196 fIsDegenerate = data.isDegenerate(); |
126 } | 197 } |
127 | 198 |
128 void GrGL2PtConicalGradientEffect::emitCode(GrGLShaderBuilder* builder, | 199 void GLDefault2PtConicalEffect::emitCode(GrGLShaderBuilder* builder, |
129 const GrDrawEffect&, | 200 const GrDrawEffect&, |
130 EffectKey key, | 201 EffectKey key, |
131 const char* outputColor, | 202 const char* outputColor, |
132 const char* inputColor, | 203 const char* inputColor, |
133 const TransformedCoordsArray& coords, | 204 const TransformedCoordsArray& coords, |
134 const TextureSamplerArray& samplers) { | 205 const TextureSamplerArray& samplers) { |
135 this->emitUniforms(builder, key); | 206 this->emitUniforms(builder, key); |
136 fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility
, | 207 fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility
, |
137 kFloat_GrSLType, "Conical2FSParams", 6)
; | 208 kFloat_GrSLType, "Conical2FSParams", 6)
; |
138 | 209 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 318 |
248 // if r(t) > 0, then t will be the x coordinate | 319 // if r(t) > 0, then t will be the x coordinate |
249 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), | 320 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), |
250 p5.c_str(), p3.c_str()); | 321 p5.c_str(), p3.c_str()); |
251 builder->fsCodeAppend("\t"); | 322 builder->fsCodeAppend("\t"); |
252 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); | 323 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa
mplers); |
253 builder->fsCodeAppend("\t}\n"); | 324 builder->fsCodeAppend("\t}\n"); |
254 } | 325 } |
255 } | 326 } |
256 | 327 |
257 void GrGL2PtConicalGradientEffect::setData(const GrGLUniformManager& uman, | 328 void GLDefault2PtConicalEffect::setData(const GrGLUniformManager& uman, |
258 const GrDrawEffect& drawEffect) { | 329 const GrDrawEffect& drawEffect) { |
259 INHERITED::setData(uman, drawEffect); | 330 INHERITED::setData(uman, drawEffect); |
260 const Gr2PtConicalGradientEffect& data = drawEffect.castEffect<Gr2PtConicalG
radientEffect>(); | 331 const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConica
lEffect>(); |
261 SkASSERT(data.isDegenerate() == fIsDegenerate); | 332 SkASSERT(data.isDegenerate() == fIsDegenerate); |
262 SkScalar centerX1 = data.center(); | 333 SkScalar centerX1 = data.center(); |
263 SkScalar radius0 = data.radius(); | 334 SkScalar radius0 = data.radius(); |
264 SkScalar diffRadius = data.diffRadius(); | 335 SkScalar diffRadius = data.diffRadius(); |
265 | 336 |
266 if (fCachedCenter != centerX1 || | 337 if (fCachedCenter != centerX1 || |
267 fCachedRadius != radius0 || | 338 fCachedRadius != radius0 || |
268 fCachedDiffRadius != diffRadius) { | 339 fCachedDiffRadius != diffRadius) { |
269 | 340 |
270 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; | 341 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; |
(...skipping 12 matching lines...) Expand all Loading... |
283 SkScalarToFloat(diffRadius) | 354 SkScalarToFloat(diffRadius) |
284 }; | 355 }; |
285 | 356 |
286 uman.set1fv(fParamUni, 6, values); | 357 uman.set1fv(fParamUni, 6, values); |
287 fCachedCenter = centerX1; | 358 fCachedCenter = centerX1; |
288 fCachedRadius = radius0; | 359 fCachedRadius = radius0; |
289 fCachedDiffRadius = diffRadius; | 360 fCachedDiffRadius = diffRadius; |
290 } | 361 } |
291 } | 362 } |
292 | 363 |
293 GrGLEffect::EffectKey GrGL2PtConicalGradientEffect::GenKey(const GrDrawEffect& d
rawEffect, | 364 GrGLEffect::EffectKey GLDefault2PtConicalEffect::GenKey(const GrDrawEffect& draw
Effect, |
294 const GrGLCaps&) { | 365 const GrGLCaps&) { |
295 enum { | 366 enum { |
296 kIsDegenerate = 1 << kBaseKeyBitCnt, | 367 kIsDegenerate = 1 << kBaseKeyBitCnt, |
297 }; | 368 }; |
298 | 369 |
299 EffectKey key = GenBaseGradientKey(drawEffect); | 370 EffectKey key = GenBaseGradientKey(drawEffect); |
300 if (drawEffect.castEffect<Gr2PtConicalGradientEffect>().isDegenerate()) { | 371 if (drawEffect.castEffect<Default2PtConicalEffect>().isDegenerate()) { |
301 key |= kIsDegenerate; | 372 key |= kIsDegenerate; |
302 } | 373 } |
303 return key; | 374 return key; |
304 } | 375 } |
| 376 |
| 377 ////////////////////////////////////////////////////////////////////////////// |
| 378 |
| 379 GrEffectRef* Gr2PtConicalGradientEffect::Create(GrContext* ctx, |
| 380 const SkTwoPointConicalGradient&
shader, |
| 381 SkShader::TileMode tm) { |
| 382 |
| 383 SkMatrix matrix; |
| 384 if (!shader.getLocalMatrix().invert(&matrix)) { |
| 385 return NULL; |
| 386 } |
| 387 |
| 388 set_matrix_default_conical(shader, &matrix); |
| 389 return Default2PtConicalEffect::Create(ctx, shader, matrix, tm); |
| 390 } |
| 391 |
305 #endif | 392 #endif |
OLD | NEW |