| 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(kVec2f_GrSLType); |
| 53 const char* vsCoordName; | 53 args.fPB->addVarying("TextureCoords", &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(kVec2f_GrSLType); |
| 268 const char* vsCoordName; | 265 args.fPB->addVarying("TextureCoords", &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(kVec2f_GrSLType); |
| 425 const char* vsCoordName; | 419 args.fPB->addVarying("TextureCoords", &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 |