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 "GrOvalEffect.h" | 8 #include "GrOvalEffect.h" |
9 | 9 |
10 #include "GrFragmentProcessor.h" | 10 #include "GrFragmentProcessor.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } while (kHairlineAA_GrProcessorEdgeType == et); | 86 } while (kHairlineAA_GrProcessorEdgeType == et); |
87 return CircleEffect::Create(et, center, radius); | 87 return CircleEffect::Create(et, center, radius); |
88 } | 88 } |
89 | 89 |
90 ////////////////////////////////////////////////////////////////////////////// | 90 ////////////////////////////////////////////////////////////////////////////// |
91 | 91 |
92 class GLCircleEffect : public GrGLFragmentProcessor { | 92 class GLCircleEffect : public GrGLFragmentProcessor { |
93 public: | 93 public: |
94 GLCircleEffect(const GrProcessor&); | 94 GLCircleEffect(const GrProcessor&); |
95 | 95 |
96 virtual void emitCode(GrGLFPBuilder* builder, | 96 virtual void emitCode(EmitArgs&) override; |
97 const GrFragmentProcessor& fp, | |
98 const char* outputColor, | |
99 const char* inputColor, | |
100 const TransformedCoordsArray&, | |
101 const TextureSamplerArray&) override; | |
102 | 97 |
103 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); | 98 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
104 | 99 |
105 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 100 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
106 | 101 |
107 private: | 102 private: |
108 GrGLProgramDataManager::UniformHandle fCircleUniform; | 103 GrGLProgramDataManager::UniformHandle fCircleUniform; |
109 SkPoint fPrevCenter; | 104 SkPoint fPrevCenter; |
110 SkScalar fPrevRadius; | 105 SkScalar fPrevRadius; |
111 | 106 |
112 typedef GrGLFragmentProcessor INHERITED; | 107 typedef GrGLFragmentProcessor INHERITED; |
113 }; | 108 }; |
114 | 109 |
115 GLCircleEffect::GLCircleEffect(const GrProcessor&) { | 110 GLCircleEffect::GLCircleEffect(const GrProcessor&) { |
116 fPrevRadius = -1.f; | 111 fPrevRadius = -1.f; |
117 } | 112 } |
118 | 113 |
119 void GLCircleEffect::emitCode(GrGLFPBuilder* builder, | 114 void GLCircleEffect::emitCode(EmitArgs& args) { |
120 const GrFragmentProcessor& fp, | 115 const CircleEffect& ce = args.fFp.cast<CircleEffect>(); |
121 const char* outputColor, | |
122 const char* inputColor, | |
123 const TransformedCoordsArray&, | |
124 const TextureSamplerArray& samplers) { | |
125 const CircleEffect& ce = fp.cast<CircleEffect>(); | |
126 const char *circleName; | 116 const char *circleName; |
127 // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.
5)) for regular | 117 // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.
5)) for regular |
128 // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills. | 118 // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills. |
129 fCircleUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, | 119 fCircleUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
130 kVec4f_GrSLType, kDefault_GrSLPrecision
, | 120 kVec4f_GrSLType, kDefault_GrSLPrecision
, |
131 "circle", | 121 "circle", |
132 &circleName); | 122 &circleName); |
133 | 123 |
134 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 124 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
135 const char* fragmentPos = fsBuilder->fragmentPosition(); | 125 const char* fragmentPos = fsBuilder->fragmentPosition(); |
136 | 126 |
137 SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType()); | 127 SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType()); |
138 // TODO: Right now the distance to circle caclulation is performed in a spac
e normalized to the | 128 // TODO: Right now the distance to circle caclulation is performed in a spac
e normalized to the |
139 // radius and then denormalized. This is to prevent overflow on devices that
have a "real" | 129 // radius and then denormalized. This is to prevent overflow on devices that
have a "real" |
140 // mediump. It'd be nice to only to this on mediump devices but we currently
don't have the | 130 // mediump. It'd be nice to only to this on mediump devices but we currently
don't have the |
141 // caps here. | 131 // caps here. |
142 if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) { | 132 if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) { |
143 fsBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) -
1.0) * %s.z;\n", | 133 fsBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) -
1.0) * %s.z;\n", |
144 circleName, fragmentPos, circleName, circleName)
; | 134 circleName, fragmentPos, circleName, circleName)
; |
145 } else { | 135 } else { |
146 fsBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) * %
s.w)) * %s.z;\n", | 136 fsBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) * %
s.w)) * %s.z;\n", |
147 circleName, fragmentPos, circleName, circleName); | 137 circleName, fragmentPos, circleName, circleName); |
148 } | 138 } |
149 if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) { | 139 if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) { |
150 fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n"); | 140 fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n"); |
151 } else { | 141 } else { |
152 fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n"); | 142 fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n"); |
153 } | 143 } |
154 | 144 |
155 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 145 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor, |
156 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("d")).c_str())
; | 146 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("d")).c_
str()); |
157 } | 147 } |
158 | 148 |
159 void GLCircleEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&, | 149 void GLCircleEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&, |
160 GrProcessorKeyBuilder* b) { | 150 GrProcessorKeyBuilder* b) { |
161 const CircleEffect& ce = processor.cast<CircleEffect>(); | 151 const CircleEffect& ce = processor.cast<CircleEffect>(); |
162 b->add32(ce.getEdgeType()); | 152 b->add32(ce.getEdgeType()); |
163 } | 153 } |
164 | 154 |
165 void GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProces
sor& processor) { | 155 void GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProces
sor& processor) { |
166 const CircleEffect& ce = processor.cast<CircleEffect>(); | 156 const CircleEffect& ce = processor.cast<CircleEffect>(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 } while (kHairlineAA_GrProcessorEdgeType == et); | 256 } while (kHairlineAA_GrProcessorEdgeType == et); |
267 return EllipseEffect::Create(et, center, rx, ry); | 257 return EllipseEffect::Create(et, center, rx, ry); |
268 } | 258 } |
269 | 259 |
270 ////////////////////////////////////////////////////////////////////////////// | 260 ////////////////////////////////////////////////////////////////////////////// |
271 | 261 |
272 class GLEllipseEffect : public GrGLFragmentProcessor { | 262 class GLEllipseEffect : public GrGLFragmentProcessor { |
273 public: | 263 public: |
274 GLEllipseEffect(const GrProcessor&); | 264 GLEllipseEffect(const GrProcessor&); |
275 | 265 |
276 virtual void emitCode(GrGLFPBuilder* builder, | 266 virtual void emitCode(EmitArgs&) override; |
277 const GrFragmentProcessor& fp, | |
278 const char* outputColor, | |
279 const char* inputColor, | |
280 const TransformedCoordsArray&, | |
281 const TextureSamplerArray&) override; | |
282 | 267 |
283 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); | 268 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
284 | 269 |
285 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 270 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
286 | 271 |
287 private: | 272 private: |
288 GrGLProgramDataManager::UniformHandle fEllipseUniform; | 273 GrGLProgramDataManager::UniformHandle fEllipseUniform; |
289 SkPoint fPrevCenter; | 274 SkPoint fPrevCenter; |
290 SkVector fPrevRadii; | 275 SkVector fPrevRadii; |
291 | 276 |
292 typedef GrGLFragmentProcessor INHERITED; | 277 typedef GrGLFragmentProcessor INHERITED; |
293 }; | 278 }; |
294 | 279 |
295 GLEllipseEffect::GLEllipseEffect(const GrProcessor& effect) { | 280 GLEllipseEffect::GLEllipseEffect(const GrProcessor& effect) { |
296 fPrevRadii.fX = -1.f; | 281 fPrevRadii.fX = -1.f; |
297 } | 282 } |
298 | 283 |
299 void GLEllipseEffect::emitCode(GrGLFPBuilder* builder, | 284 void GLEllipseEffect::emitCode(EmitArgs& args) { |
300 const GrFragmentProcessor& fp, | 285 const EllipseEffect& ee = args.fFp.cast<EllipseEffect>(); |
301 const char* outputColor, | |
302 const char* inputColor, | |
303 const TransformedCoordsArray&, | |
304 const TextureSamplerArray& samplers) { | |
305 const EllipseEffect& ee = fp.cast<EllipseEffect>(); | |
306 const char *ellipseName; | 286 const char *ellipseName; |
307 // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2) | 287 // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2) |
308 fEllipseUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibili
ty, | 288 fEllipseUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Vi
sibility, |
309 kVec4f_GrSLType, kDefault_GrSLPrecision
, | 289 kVec4f_GrSLType, kDefault_GrSLPrecision
, |
310 "ellipse", | 290 "ellipse", |
311 &ellipseName); | 291 &ellipseName); |
312 | 292 |
313 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 293 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
314 const char* fragmentPos = fsBuilder->fragmentPosition(); | 294 const char* fragmentPos = fsBuilder->fragmentPosition(); |
315 | 295 |
316 // d is the offset to the ellipse center | 296 // d is the offset to the ellipse center |
317 fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipse
Name); | 297 fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipse
Name); |
318 fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName); | 298 fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName); |
319 // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1. | 299 // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1. |
320 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n"); | 300 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n"); |
321 // grad_dot is the squared length of the gradient of the implicit. | 301 // grad_dot is the squared length of the gradient of the implicit. |
322 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); | 302 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); |
323 // avoid calling inversesqrt on zero. | 303 // avoid calling inversesqrt on zero. |
(...skipping 10 matching lines...) Expand all Loading... |
334 case kFillBW_GrProcessorEdgeType: | 314 case kFillBW_GrProcessorEdgeType: |
335 fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1
.0;\n"); | 315 fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1
.0;\n"); |
336 break; | 316 break; |
337 case kInverseFillBW_GrProcessorEdgeType: | 317 case kInverseFillBW_GrProcessorEdgeType: |
338 fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0
.0;\n"); | 318 fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0
.0;\n"); |
339 break; | 319 break; |
340 case kHairlineAA_GrProcessorEdgeType: | 320 case kHairlineAA_GrProcessorEdgeType: |
341 SkFAIL("Hairline not expected here."); | 321 SkFAIL("Hairline not expected here."); |
342 } | 322 } |
343 | 323 |
344 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 324 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor, |
345 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 325 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")
).c_str()); |
346 } | 326 } |
347 | 327 |
348 void GLEllipseEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps&, | 328 void GLEllipseEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps&, |
349 GrProcessorKeyBuilder* b) { | 329 GrProcessorKeyBuilder* b) { |
350 const EllipseEffect& ee = effect.cast<EllipseEffect>(); | 330 const EllipseEffect& ee = effect.cast<EllipseEffect>(); |
351 b->add32(ee.getEdgeType()); | 331 b->add32(ee.getEdgeType()); |
352 } | 332 } |
353 | 333 |
354 void GLEllipseEffect::setData(const GrGLProgramDataManager& pdman, const GrProce
ssor& effect) { | 334 void GLEllipseEffect::setData(const GrGLProgramDataManager& pdman, const GrProce
ssor& effect) { |
355 const EllipseEffect& ee = effect.cast<EllipseEffect>(); | 335 const EllipseEffect& ee = effect.cast<EllipseEffect>(); |
(...skipping 29 matching lines...) Expand all Loading... |
385 w /= 2; | 365 w /= 2; |
386 return CircleEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval
.fTop + w), w); | 366 return CircleEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval
.fTop + w), w); |
387 } else { | 367 } else { |
388 w /= 2; | 368 w /= 2; |
389 h /= 2; | 369 h /= 2; |
390 return EllipseEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, ova
l.fTop + h), w, h); | 370 return EllipseEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, ova
l.fTop + h), w, h); |
391 } | 371 } |
392 | 372 |
393 return NULL; | 373 return NULL; |
394 } | 374 } |
OLD | NEW |