Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/gpu/effects/GrDistanceFieldTextureEffect.cpp

Issue 666693012: GP Emit Code takes a struct (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDashingEffect.cpp ('k') | src/gpu/gl/GrGLGeometryProcessor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "GrDistanceFieldTextureEffect.h" 8 #include "GrDistanceFieldTextureEffect.h"
9 #include "gl/builders/GrGLProgramBuilder.h" 9 #include "gl/builders/GrGLProgramBuilder.h"
10 #include "gl/GrGLProcessor.h" 10 #include "gl/GrGLProcessor.h"
(...skipping 22 matching lines...) Expand all
33 public: 33 public:
34 GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory, 34 GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory,
35 const GrProcessor&) 35 const GrProcessor&)
36 : INHERITED (factory) 36 : INHERITED (factory)
37 , fTextureSize(SkISize::Make(-1,-1)) 37 , fTextureSize(SkISize::Make(-1,-1))
38 #ifdef SK_GAMMA_APPLY_TO_A8 38 #ifdef SK_GAMMA_APPLY_TO_A8
39 , fLuminance(-1.0f) 39 , fLuminance(-1.0f)
40 #endif 40 #endif
41 {} 41 {}
42 42
43 virtual void emitCode(GrGLGPBuilder* builder, 43 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
44 const GrGeometryProcessor& geometryProcessor,
45 const GrProcessorKey& key,
46 const char* outputColor,
47 const char* inputColor,
48 const TransformedCoordsArray&,
49 const TextureSamplerArray& samplers) SK_OVERRIDE {
50 const GrDistanceFieldTextureEffect& dfTexEffect = 44 const GrDistanceFieldTextureEffect& dfTexEffect =
51 geometryProcessor.cast<GrDistanceFieldTextureEffect>(); 45 args.fGP.cast<GrDistanceFieldTextureEffect>();
52 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); 46 SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
53 47
54 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 48 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
55 SkAssertResult(fsBuilder->enableFeature( 49 SkAssertResult(fsBuilder->enableFeature(
56 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 50 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
57 51
58 SkString fsCoordName; 52 SkString fsCoordName;
59 const char* vsCoordName; 53 const char* vsCoordName;
60 const char* fsCoordNamePtr; 54 const char* fsCoordNamePtr;
61 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr); 55 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs CoordNamePtr);
62 fsCoordName = fsCoordNamePtr; 56 fsCoordName = fsCoordNamePtr;
63 57
64 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder(); 58 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
65 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur eCoords().c_str()); 59 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur eCoords().c_str());
66 60
67 const char* textureSizeUniName = NULL; 61 const char* textureSizeUniName = NULL;
68 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi bility, 62 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis ibility,
69 kVec2f_GrSLType, "TextureSize", 63 kVec2f_GrSLType, "TextureSize",
70 &textureSizeUniName); 64 &textureSizeUniName);
71 65
72 fsBuilder->codeAppend("\tvec4 texColor = "); 66 fsBuilder->codeAppend("\tvec4 texColor = ");
73 fsBuilder->appendTextureLookup(samplers[0], 67 fsBuilder->appendTextureLookup(args.fSamplers[0],
74 fsCoordName.c_str(), 68 fsCoordName.c_str(),
75 kVec2f_GrSLType); 69 kVec2f_GrSLType);
76 fsBuilder->codeAppend(";\n"); 70 fsBuilder->codeAppend(";\n");
77 fsBuilder->codeAppend("\tfloat distance = " 71 fsBuilder->codeAppend("\tfloat distance = "
78 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan ceFieldThreshold ")" 72 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan ceFieldThreshold ")"
79 "+ " SK_DistanceFieldNonLCDFactor ";\n"); 73 "+ " SK_DistanceFieldNonLCDFactor ";\n");
80 74
81 // we adjust for the effect of the transformation on the distance by usi ng 75 // we adjust for the effect of the transformation on the distance by usi ng
82 // the length of the gradient of the texture coordinates. We use st coor dinates 76 // the length of the gradient of the texture coordinates. We use st coor dinates
83 // to ensure we're mapping 1:1 from texel space to pixel space. 77 // to ensure we're mapping 1:1 from texel space to pixel space.
84 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 78 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
85 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 79 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
86 fsBuilder->codeAppend("\tfloat afwidth;\n"); 80 fsBuilder->codeAppend("\tfloat afwidth;\n");
87 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 81 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
88 // this gives us a smooth step across approximately one fragment 82 // this gives us a smooth step across approximately one fragment
89 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dFdx(st.x));\n"); 83 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dFdx(st.x));\n");
90 } else { 84 } else {
91 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 85 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
92 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 86 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
93 87
94 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 88 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
95 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 89 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
96 // this is to compensate for the Adreno, which likes to drop til es on division by 0 90 // this is to compensate for the Adreno, which likes to drop til es on division by 0
97 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 91 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
98 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 92 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
99 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 93 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
100 fsBuilder->codeAppend("\t} else {\n"); 94 fsBuilder->codeAppend("\t} else {\n");
101 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 95 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
102 fsBuilder->codeAppend("\t}\n"); 96 fsBuilder->codeAppend("\t}\n");
103 } else { 97 } else {
104 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 98 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
105 } 99 }
106 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n"); 100 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n");
107 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n"); 101 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n");
108 102
109 // this gives us a smooth step across approximately one fragment 103 // this gives us a smooth step across approximately one fragment
110 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n"); 104 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n");
111 } 105 }
112 fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista nce);\n"); 106 fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista nce);\n");
113 107
114 #ifdef SK_GAMMA_APPLY_TO_A8 108 #ifdef SK_GAMMA_APPLY_TO_A8
115 // adjust based on gamma 109 // adjust based on gamma
116 const char* luminanceUniName = NULL; 110 const char* luminanceUniName = NULL;
117 // width, height, 1/(3*width) 111 // width, height, 1/(3*width)
118 fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi lity, 112 fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib ility,
119 kFloat_GrSLType, "Luminance", 113 kFloat_GrSLType, "Luminance",
120 &luminanceUniName); 114 &luminanceUniName);
121 115
122 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); 116 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
123 fsBuilder->codeAppend("\tvec4 gammaColor = "); 117 fsBuilder->codeAppend("\tvec4 gammaColor = ");
124 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 118 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
125 fsBuilder->codeAppend(";\n"); 119 fsBuilder->codeAppend(";\n");
126 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); 120 fsBuilder->codeAppend("\tval = gammaColor.r;\n");
127 #endif 121 #endif
128 122
129 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 123 fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
130 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val") ).c_str()); 124 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("val" )).c_str());
131 } 125 }
132 126
133 virtual void setData(const GrGLProgramDataManager& pdman, 127 virtual void setData(const GrGLProgramDataManager& pdman,
134 const GrProcessor& effect) SK_OVERRIDE { 128 const GrProcessor& effect) SK_OVERRIDE {
135 SkASSERT(fTextureSizeUni.isValid()); 129 SkASSERT(fTextureSizeUni.isValid());
136 130
137 GrTexture* texture = effect.texture(0); 131 GrTexture* texture = effect.texture(0);
138 if (texture->width() != fTextureSize.width() || 132 if (texture->width() != fTextureSize.width() ||
139 texture->height() != fTextureSize.height()) { 133 texture->height() != fTextureSize.height()) {
140 fTextureSize = SkISize::Make(texture->width(), texture->height()); 134 fTextureSize = SkISize::Make(texture->width(), texture->height());
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 248
255 /////////////////////////////////////////////////////////////////////////////// 249 ///////////////////////////////////////////////////////////////////////////////
256 250
257 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { 251 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
258 public: 252 public:
259 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto ry, 253 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto ry,
260 const GrProcessor& effect) 254 const GrProcessor& effect)
261 : INHERITED(factory) 255 : INHERITED(factory)
262 , fTextureSize(SkISize::Make(-1, -1)) {} 256 , fTextureSize(SkISize::Make(-1, -1)) {}
263 257
264 virtual void emitCode(GrGLGPBuilder* builder, 258 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
265 const GrGeometryProcessor& effect,
266 const GrProcessorKey& key,
267 const char* outputColor,
268 const char* inputColor,
269 const TransformedCoordsArray&,
270 const TextureSamplerArray& samplers) SK_OVERRIDE {
271 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = 259 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
272 effect.cast<GrDistanceFieldNoGam maTextureEffect>(); 260 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>();
273 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); 261 SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
274 262
275 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 263 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
276 SkAssertResult(fsBuilder->enableFeature( 264 SkAssertResult(fsBuilder->enableFeature(
277 GrGLFragmentShaderBuilder::kStandardDerivat ives_GLSLFeature)); 265 GrGLFragmentShaderBuilder::kStandardDerivat ives_GLSLFeature));
278 266
279 SkString fsCoordName; 267 SkString fsCoordName;
280 const char* vsCoordName; 268 const char* vsCoordName;
281 const char* fsCoordNamePtr; 269 const char* fsCoordNamePtr;
282 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr); 270 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs CoordNamePtr);
283 fsCoordName = fsCoordNamePtr; 271 fsCoordName = fsCoordNamePtr;
284 272
285 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder(); 273 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
286 vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoo rds().c_str()); 274 vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoo rds().c_str());
287 275
288 const char* textureSizeUniName = NULL; 276 const char* textureSizeUniName = NULL;
289 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi bility, 277 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis ibility,
290 kVec2f_GrSLType, "TextureSize", 278 kVec2f_GrSLType, "TextureSize",
291 &textureSizeUniName); 279 &textureSizeUniName);
292 280
293 fsBuilder->codeAppend("vec4 texColor = "); 281 fsBuilder->codeAppend("vec4 texColor = ");
294 fsBuilder->appendTextureLookup(samplers[0], 282 fsBuilder->appendTextureLookup(args.fSamplers[0],
295 fsCoordName.c_str(), 283 fsCoordName.c_str(),
296 kVec2f_GrSLType); 284 kVec2f_GrSLType);
297 fsBuilder->codeAppend(";"); 285 fsBuilder->codeAppend(";");
298 fsBuilder->codeAppend("float distance = " 286 fsBuilder->codeAppend("float distance = "
299 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho ld ");"); 287 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho ld ");");
300 288
301 // we adjust for the effect of the transformation on the distance by usi ng 289 // we adjust for the effect of the transformation on the distance by usi ng
302 // the length of the gradient of the texture coordinates. We use st coor dinates 290 // the length of the gradient of the texture coordinates. We use st coor dinates
303 // to ensure we're mapping 1:1 from texel space to pixel space. 291 // to ensure we're mapping 1:1 from texel space to pixel space.
304 fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str()); 292 fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str());
305 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 293 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
306 fsBuilder->codeAppend("float afwidth;"); 294 fsBuilder->codeAppend("float afwidth;");
307 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 295 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
308 // this gives us a smooth step across approximately one fragment 296 // this gives us a smooth step across approximately one fragment
309 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF dx(st.x));"); 297 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF dx(st.x));");
310 } else { 298 } else {
311 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 299 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
312 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 300 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
313 301
314 fsBuilder->codeAppend("vec2 uv_grad;"); 302 fsBuilder->codeAppend("vec2 uv_grad;");
315 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 303 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
316 // this is to compensate for the Adreno, which likes to drop til es on division by 0 304 // this is to compensate for the Adreno, which likes to drop til es on division by 0
317 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);"); 305 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
318 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {"); 306 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
319 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);"); 307 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
320 fsBuilder->codeAppend("} else {"); 308 fsBuilder->codeAppend("} else {");
321 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);"); 309 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
322 fsBuilder->codeAppend("}"); 310 fsBuilder->codeAppend("}");
323 } else { 311 } else {
324 fsBuilder->codeAppend("uv_grad = normalize(uv);"); 312 fsBuilder->codeAppend("uv_grad = normalize(uv);");
325 } 313 }
326 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y* Jdy.x,"); 314 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y* Jdy.x,");
327 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y* Jdy.y);"); 315 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y* Jdy.y);");
328 316
329 // this gives us a smooth step across approximately one fragment 317 // this gives us a smooth step across approximately one fragment
330 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 318 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);");
331 } 319 }
332 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);"); 320 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);");
333 321
334 fsBuilder->codeAppendf("%s = %s;", outputColor, 322 fsBuilder->codeAppendf("%s = %s;", args.fOutput,
335 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); 323 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("val")).c_str());
336 } 324 }
337 325
338 virtual void setData(const GrGLProgramDataManager& pdman, 326 virtual void setData(const GrGLProgramDataManager& pdman,
339 const GrProcessor& effect) SK_OVERRIDE { 327 const GrProcessor& effect) SK_OVERRIDE {
340 SkASSERT(fTextureSizeUni.isValid()); 328 SkASSERT(fTextureSizeUni.isValid());
341 329
342 GrTexture* texture = effect.texture(0); 330 GrTexture* texture = effect.texture(0);
343 if (texture->width() != fTextureSize.width() || 331 if (texture->width() != fTextureSize.width() ||
344 texture->height() != fTextureSize.height()) { 332 texture->height() != fTextureSize.height()) {
345 fTextureSize = SkISize::Make(texture->width(), texture->height()); 333 fTextureSize = SkISize::Make(texture->width(), texture->height());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 /////////////////////////////////////////////////////////////////////////////// 409 ///////////////////////////////////////////////////////////////////////////////
422 410
423 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 411 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
424 public: 412 public:
425 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, 413 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory,
426 const GrProcessor&) 414 const GrProcessor&)
427 : INHERITED (factory) 415 : INHERITED (factory)
428 , fTextureSize(SkISize::Make(-1,-1)) 416 , fTextureSize(SkISize::Make(-1,-1))
429 , fTextColor(GrColor_ILLEGAL) {} 417 , fTextColor(GrColor_ILLEGAL) {}
430 418
431 virtual void emitCode(GrGLGPBuilder* builder, 419 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
432 const GrGeometryProcessor& geometryProcessor,
433 const GrProcessorKey& key,
434 const char* outputColor,
435 const char* inputColor,
436 const TransformedCoordsArray&,
437 const TextureSamplerArray& samplers) SK_OVERRIDE {
438 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 420 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
439 geometryProcessor.cast<GrDistanceFieldLCDTextureEffect>(); 421 args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
440 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); 422 SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
441 423
442 SkString fsCoordName; 424 SkString fsCoordName;
443 const char* vsCoordName; 425 const char* vsCoordName;
444 const char* fsCoordNamePtr; 426 const char* fsCoordNamePtr;
445 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr); 427 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs CoordNamePtr);
446 fsCoordName = fsCoordNamePtr; 428 fsCoordName = fsCoordNamePtr;
447 429
448 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder(); 430 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
449 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur eCoords().c_str()); 431 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur eCoords().c_str());
450 432
451 const char* textureSizeUniName = NULL; 433 const char* textureSizeUniName = NULL;
452 // width, height, 1/(3*width) 434 // width, height, 1/(3*width)
453 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi bility, 435 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis ibility,
454 kVec3f_GrSLType, "TextureSize", 436 kVec3f_GrSLType, "TextureSize",
455 &textureSizeUniName); 437 &textureSizeUniName);
456 438
457 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 439 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
458 440
459 SkAssertResult(fsBuilder->enableFeature( 441 SkAssertResult(fsBuilder->enableFeature(
460 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 442 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
461 443
462 // create LCD offset adjusted by inverse of transform 444 // create LCD offset adjusted by inverse of transform
463 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 445 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
464 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 446 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
465 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance FieldEffectMask); 447 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance FieldEffectMask);
466 if (isUniformScale) { 448 if (isUniformScale) {
467 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); 449 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
468 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text ureSizeUniName); 450 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text ureSizeUniName);
469 } else { 451 } else {
470 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 452 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
471 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 453 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
472 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni Name); 454 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni Name);
473 } 455 }
474 456
475 // green is distance to uv center 457 // green is distance to uv center
476 fsBuilder->codeAppend("\tvec4 texColor = "); 458 fsBuilder->codeAppend("\tvec4 texColor = ");
477 fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); 459 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType) ;
478 fsBuilder->codeAppend(";\n"); 460 fsBuilder->codeAppend(";\n");
479 fsBuilder->codeAppend("\tvec3 distance;\n"); 461 fsBuilder->codeAppend("\tvec3 distance;\n");
480 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 462 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
481 // red is distance to left offset 463 // red is distance to left offset
482 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 464 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
483 fsBuilder->codeAppend("\ttexColor = "); 465 fsBuilder->codeAppend("\ttexColor = ");
484 fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe); 466 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType);
485 fsBuilder->codeAppend(";\n"); 467 fsBuilder->codeAppend(";\n");
486 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 468 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
487 // blue is distance to right offset 469 // blue is distance to right offset
488 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 470 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
489 fsBuilder->codeAppend("\ttexColor = "); 471 fsBuilder->codeAppend("\ttexColor = ");
490 fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe); 472 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType);
491 fsBuilder->codeAppend(";\n"); 473 fsBuilder->codeAppend(";\n");
492 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 474 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
493 475
494 fsBuilder->codeAppend("\tdistance = " 476 fsBuilder->codeAppend("\tdistance = "
495 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_Distance FieldThreshold"))" 477 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_Distance FieldThreshold"))"
496 "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); 478 "+ vec3(" SK_DistanceFieldLCDFactor ");\n");
497 479
498 // we adjust for the effect of the transformation on the distance by usi ng 480 // we adjust for the effect of the transformation on the distance by usi ng
499 // the length of the gradient of the texture coordinates. We use st coor dinates 481 // the length of the gradient of the texture coordinates. We use st coor dinates
500 // to ensure we're mapping 1:1 from texel space to pixel space. 482 // to ensure we're mapping 1:1 from texel space to pixel space.
501 483
502 // To be strictly correct, we should compute the anti-aliasing factor se parately 484 // To be strictly correct, we should compute the anti-aliasing factor se parately
503 // for each color component. However, this is only important when using perspective 485 // for each color component. However, this is only important when using perspective
504 // transformations, and even then using a single factor seems like a rea sonable 486 // transformations, and even then using a single factor seems like a rea sonable
505 // trade-off between quality and speed. 487 // trade-off between quality and speed.
506 fsBuilder->codeAppend("\tfloat afwidth;\n"); 488 fsBuilder->codeAppend("\tfloat afwidth;\n");
507 if (isUniformScale) { 489 if (isUniformScale) {
508 // this gives us a smooth step across approximately one fragment 490 // this gives us a smooth step across approximately one fragment
509 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dx);\n"); 491 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dx);\n");
510 } else { 492 } else {
511 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 493 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
512 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 494 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
513 // this is to compensate for the Adreno, which likes to drop til es on division by 0 495 // this is to compensate for the Adreno, which likes to drop til es on division by 0
514 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 496 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
515 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 497 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
516 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 498 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
517 fsBuilder->codeAppend("\t} else {\n"); 499 fsBuilder->codeAppend("\t} else {\n");
518 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 500 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
519 fsBuilder->codeAppend("\t}\n"); 501 fsBuilder->codeAppend("\t}\n");
520 } else { 502 } else {
521 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 503 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
522 } 504 }
523 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n"); 505 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n");
524 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n"); 506 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n");
525 507
526 // this gives us a smooth step across approximately one fragment 508 // this gives us a smooth step across approximately one fragment
527 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n"); 509 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n");
528 } 510 }
529 511
530 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3 (afwidth), distance), 1.0);\n"); 512 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3 (afwidth), distance), 1.0);\n");
531 513
532 // adjust based on gamma 514 // adjust based on gamma
533 const char* textColorUniName = NULL; 515 const char* textColorUniName = NULL;
534 // width, height, 1/(3*width) 516 // width, height, 1/(3*width)
535 fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi lity, 517 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib ility,
536 kVec3f_GrSLType, "TextColor", 518 kVec3f_GrSLType, "TextColor",
537 &textColorUniName); 519 &textColorUniName);
538 520
539 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); 521 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
540 fsBuilder->codeAppend("\tvec4 gammaColor = "); 522 fsBuilder->codeAppend("\tvec4 gammaColor = ");
541 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 523 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
542 fsBuilder->codeAppend(";\n"); 524 fsBuilder->codeAppend(";\n");
543 fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); 525 fsBuilder->codeAppend("\tval.x = gammaColor.r;\n");
544 526
545 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); 527 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
546 fsBuilder->codeAppend("\tgammaColor = "); 528 fsBuilder->codeAppend("\tgammaColor = ");
547 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 529 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
548 fsBuilder->codeAppend(";\n"); 530 fsBuilder->codeAppend(";\n");
549 fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); 531 fsBuilder->codeAppend("\tval.y = gammaColor.r;\n");
550 532
551 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); 533 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
552 fsBuilder->codeAppend("\tgammaColor = "); 534 fsBuilder->codeAppend("\tgammaColor = ");
553 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 535 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
554 fsBuilder->codeAppend(";\n"); 536 fsBuilder->codeAppend(";\n");
555 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); 537 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n");
556 538
557 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 539 fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
558 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_ str()); 540 (GrGLSLExpr4(args.fInput) * GrGLSLExpr4("val")).c _str());
559 } 541 }
560 542
561 virtual void setData(const GrGLProgramDataManager& pdman, 543 virtual void setData(const GrGLProgramDataManager& pdman,
562 const GrProcessor& processor) SK_OVERRIDE { 544 const GrProcessor& processor) SK_OVERRIDE {
563 SkASSERT(fTextureSizeUni.isValid()); 545 SkASSERT(fTextureSizeUni.isValid());
564 SkASSERT(fTextColorUni.isValid()); 546 SkASSERT(fTextColorUni.isValid());
565 547
566 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 548 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
567 processor.cast<GrDistanceFieldLCDTextureEffect>(); 549 processor.cast<GrDistanceFieldLCDTextureEffect>();
568 GrTexture* texture = processor.texture(0); 550 GrTexture* texture = processor.texture(0);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 random->nextULessThan(256), 653 random->nextULessThan(256),
672 random->nextULessThan(256)); 654 random->nextULessThan(256));
673 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 655 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
674 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 656 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
675 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 657 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
676 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 658 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
677 textures[texIdx2], params2, 659 textures[texIdx2], params2,
678 textColor, 660 textColor,
679 flags); 661 flags);
680 } 662 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDashingEffect.cpp ('k') | src/gpu/gl/GrGLGeometryProcessor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698