| 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 22 matching lines...) Expand all Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |