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