OLD | NEW |
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 43 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
44 const GrDistanceFieldTextureEffect& dfTexEffect = | 44 const GrDistanceFieldTextureEffect& dfTexEffect = |
45 args.fGP.cast<GrDistanceFieldTextureEffect>(); | 45 args.fGP.cast<GrDistanceFieldTextureEffect>(); |
46 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); | 46 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); |
47 | 47 |
48 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 48 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
49 SkAssertResult(fsBuilder->enableFeature( | 49 SkAssertResult(fsBuilder->enableFeature( |
50 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 50 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
51 | 51 |
52 GrGLVertToFrag v(kVec2f_GrSLType); | 52 SkString fsCoordName; |
53 args.fPB->addVarying("TextureCoords", &v); | 53 const char* vsCoordName; |
| 54 const char* fsCoordNamePtr; |
| 55 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs
CoordNamePtr); |
| 56 fsCoordName = fsCoordNamePtr; |
54 | 57 |
55 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 58 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
56 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureC
oords().c_str()); | 59 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur
eCoords().c_str()); |
57 | 60 |
58 const char* textureSizeUniName = NULL; | 61 const char* textureSizeUniName = NULL; |
59 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 62 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
60 kVec2f_GrSLType, "TextureSize", | 63 kVec2f_GrSLType, "TextureSize", |
61 &textureSizeUniName); | 64 &textureSizeUniName); |
62 | 65 |
63 fsBuilder->codeAppend("\tvec4 texColor = "); | 66 fsBuilder->codeAppend("\tvec4 texColor = "); |
64 fsBuilder->appendTextureLookup(args.fSamplers[0], | 67 fsBuilder->appendTextureLookup(args.fSamplers[0], |
65 v.fsIn(), | 68 fsCoordName.c_str(), |
66 kVec2f_GrSLType); | 69 kVec2f_GrSLType); |
67 fsBuilder->codeAppend(";\n"); | 70 fsBuilder->codeAppend(";\n"); |
68 fsBuilder->codeAppend("\tfloat distance = " | 71 fsBuilder->codeAppend("\tfloat distance = " |
69 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan
ceFieldThreshold ")" | 72 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan
ceFieldThreshold ")" |
70 "+ " SK_DistanceFieldNonLCDFactor ";\n"); | 73 "+ " SK_DistanceFieldNonLCDFactor ";\n"); |
71 | 74 |
72 // 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 |
73 // 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 |
74 // 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. |
75 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); | 78 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
76 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); | 79 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); |
77 fsBuilder->codeAppend("\tfloat afwidth;\n"); | 80 fsBuilder->codeAppend("\tfloat afwidth;\n"); |
78 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 81 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
79 // this gives us a smooth step across approximately one fragment | 82 // this gives us a smooth step across approximately one fragment |
80 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*
dFdx(st.x));\n"); | 83 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*
dFdx(st.x));\n"); |
81 } else { | 84 } else { |
82 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); | 85 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
83 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); | 86 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
84 | 87 |
85 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); | 88 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 | 257 |
255 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 258 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
256 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = | 259 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
257 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); | 260 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); |
258 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); | 261 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); |
259 | 262 |
260 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 263 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
261 SkAssertResult(fsBuilder->enableFeature( | 264 SkAssertResult(fsBuilder->enableFeature( |
262 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); | 265 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); |
263 | 266 |
264 GrGLVertToFrag v(kVec2f_GrSLType); | 267 SkString fsCoordName; |
265 args.fPB->addVarying("TextureCoords", &v); | 268 const char* vsCoordName; |
| 269 const char* fsCoordNamePtr; |
| 270 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs
CoordNamePtr); |
| 271 fsCoordName = fsCoordNamePtr; |
266 | 272 |
267 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 273 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
268 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s().c_str()); | 274 vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoo
rds().c_str()); |
269 | 275 |
270 const char* textureSizeUniName = NULL; | 276 const char* textureSizeUniName = NULL; |
271 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 277 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
272 kVec2f_GrSLType, "TextureSize", | 278 kVec2f_GrSLType, "TextureSize", |
273 &textureSizeUniName); | 279 &textureSizeUniName); |
274 | 280 |
275 fsBuilder->codeAppend("vec4 texColor = "); | 281 fsBuilder->codeAppend("vec4 texColor = "); |
276 fsBuilder->appendTextureLookup(args.fSamplers[0], | 282 fsBuilder->appendTextureLookup(args.fSamplers[0], |
277 v.fsIn(), | 283 fsCoordName.c_str(), |
278 kVec2f_GrSLType); | 284 kVec2f_GrSLType); |
279 fsBuilder->codeAppend(";"); | 285 fsBuilder->codeAppend(";"); |
280 fsBuilder->codeAppend("float distance = " | 286 fsBuilder->codeAppend("float distance = " |
281 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho
ld ");"); | 287 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho
ld ");"); |
282 | 288 |
283 // 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 |
284 // 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 |
285 // 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. |
286 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 292 fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str()); |
287 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); | 293 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); |
288 fsBuilder->codeAppend("float afwidth;"); | 294 fsBuilder->codeAppend("float afwidth;"); |
289 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 295 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
290 // this gives us a smooth step across approximately one fragment | 296 // this gives us a smooth step across approximately one fragment |
291 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF
dx(st.x));"); | 297 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF
dx(st.x));"); |
292 } else { | 298 } else { |
293 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 299 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
294 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 300 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
295 | 301 |
296 fsBuilder->codeAppend("vec2 uv_grad;"); | 302 fsBuilder->codeAppend("vec2 uv_grad;"); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 const GrProcessor&) | 414 const GrProcessor&) |
409 : INHERITED (factory) | 415 : INHERITED (factory) |
410 , fTextureSize(SkISize::Make(-1,-1)) | 416 , fTextureSize(SkISize::Make(-1,-1)) |
411 , fTextColor(GrColor_ILLEGAL) {} | 417 , fTextColor(GrColor_ILLEGAL) {} |
412 | 418 |
413 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 419 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
414 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 420 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
415 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); | 421 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); |
416 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); | 422 SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); |
417 | 423 |
418 GrGLVertToFrag v(kVec2f_GrSLType); | 424 SkString fsCoordName; |
419 args.fPB->addVarying("TextureCoords", &v); | 425 const char* vsCoordName; |
| 426 const char* fsCoordNamePtr; |
| 427 args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fs
CoordNamePtr); |
| 428 fsCoordName = fsCoordNamePtr; |
420 | 429 |
421 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 430 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
422 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureC
oords().c_str()); | 431 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextur
eCoords().c_str()); |
423 | 432 |
424 const char* textureSizeUniName = NULL; | 433 const char* textureSizeUniName = NULL; |
425 // width, height, 1/(3*width) | 434 // width, height, 1/(3*width) |
426 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 435 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
427 kVec3f_GrSLType, "TextureSize", | 436 kVec3f_GrSLType, "TextureSize", |
428 &textureSizeUniName); | 437 &textureSizeUniName); |
429 | 438 |
430 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 439 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
431 | 440 |
432 SkAssertResult(fsBuilder->enableFeature( | 441 SkAssertResult(fsBuilder->enableFeature( |
433 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 442 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
434 | 443 |
435 // create LCD offset adjusted by inverse of transform | 444 // create LCD offset adjusted by inverse of transform |
436 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); | 445 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
437 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); | 446 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); |
438 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); | 447 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); |
439 if (isUniformScale) { | 448 if (isUniformScale) { |
440 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); | 449 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); |
441 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); |
442 } else { | 451 } else { |
443 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); | 452 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
444 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); | 453 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
445 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); | 454 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); |
446 } | 455 } |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 random->nextULessThan(256), | 653 random->nextULessThan(256), |
645 random->nextULessThan(256)); | 654 random->nextULessThan(256)); |
646 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 655 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
647 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 656 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
648 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 657 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
649 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, | 658 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, |
650 textures[texIdx2], params2, | 659 textures[texIdx2], params2, |
651 textColor, | 660 textColor, |
652 flags); | 661 flags); |
653 } | 662 } |
OLD | NEW |