| 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 |