| 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 "gl/builders/GrGLProgramBuilder.h" |
| 8 #include "GrDistanceFieldTextureEffect.h" | 9 #include "GrDistanceFieldTextureEffect.h" |
| 9 #include "gl/GrGLEffect.h" | 10 #include "gl/GrGLEffect.h" |
| 10 #include "gl/GrGLShaderBuilder.h" | |
| 11 #include "gl/GrGLSL.h" | 11 #include "gl/GrGLSL.h" |
| 12 #include "gl/GrGLTexture.h" | 12 #include "gl/GrGLTexture.h" |
| 13 #include "gl/GrGLVertexEffect.h" | 13 #include "gl/GrGLVertexEffect.h" |
| 14 #include "GrTBackendEffectFactory.h" | 14 #include "GrTBackendEffectFactory.h" |
| 15 #include "GrTexture.h" | 15 #include "GrTexture.h" |
| 16 | 16 |
| 17 #include "SkDistanceFieldGen.h" | 17 #include "SkDistanceFieldGen.h" |
| 18 | 18 |
| 19 // To get optical sizes people don't complain about when we blit correctly, | 19 // To get optical sizes people don't complain about when we blit correctly, |
| 20 // we need to slightly bold each glyph. On the Mac, we need a larger bold value. | 20 // we need to slightly bold each glyph. On the Mac, we need a larger bold value. |
| 21 #if defined(SK_BUILD_FOR_MAC) | 21 #if defined(SK_BUILD_FOR_MAC) |
| 22 #define SK_DistanceFieldLCDFactor "0.33" | 22 #define SK_DistanceFieldLCDFactor "0.33" |
| 23 #define SK_DistanceFieldNonLCDFactor "0.25" | 23 #define SK_DistanceFieldNonLCDFactor "0.25" |
| 24 #else | 24 #else |
| 25 #define SK_DistanceFieldLCDFactor "0.05" | 25 #define SK_DistanceFieldLCDFactor "0.05" |
| 26 #define SK_DistanceFieldNonLCDFactor "0.05" | 26 #define SK_DistanceFieldNonLCDFactor "0.05" |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 | 29 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 |
| 30 #define SK_DistanceFieldAAFactor "0.7071" | 30 #define SK_DistanceFieldAAFactor "0.7071" |
| 31 | 31 |
| 32 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { | 32 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { |
| 33 public: | 33 public: |
| 34 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, | 34 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, |
| 35 const GrDrawEffect& drawEffect) | 35 const GrDrawEffect& drawEffect) |
| 36 : INHERITED (factory) | 36 : INHERITED (factory) |
| 37 , fTextureSize(SkISize::Make(-1,-1)) {} | 37 , fTextureSize(SkISize::Make(-1,-1)) {} |
| 38 | 38 |
| 39 virtual void emitCode(GrGLFullShaderBuilder* builder, | 39 virtual void emitCode(GrGLFullProgramBuilder* builder, |
| 40 const GrDrawEffect& drawEffect, | 40 const GrDrawEffect& drawEffect, |
| 41 const GrEffectKey& key, | 41 const GrEffectKey& key, |
| 42 const char* outputColor, | 42 const char* outputColor, |
| 43 const char* inputColor, | 43 const char* inputColor, |
| 44 const TransformedCoordsArray&, | 44 const TransformedCoordsArray&, |
| 45 const TextureSamplerArray& samplers) SK_OVERRIDE { | 45 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 46 SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numV
ertexAttribs()); | 46 SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numV
ertexAttribs()); |
| 47 | 47 |
| 48 SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDeriva
tives_GLSLFeature)); | 48 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder
(); |
| 49 SkAssertResult(fsBuilder->enableFeature( |
| 50 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
| 49 const GrDistanceFieldTextureEffect& dfTexEffect = | 51 const GrDistanceFieldTextureEffect& dfTexEffect = |
| 50 drawEffect.castEffect<GrDistanceFi
eldTextureEffect>(); | 52 drawEffect.castEffect<GrDistanceFi
eldTextureEffect>(); |
| 51 | 53 |
| 52 SkString fsCoordName; | 54 SkString fsCoordName; |
| 53 const char* vsCoordName; | 55 const char* vsCoordName; |
| 54 const char* fsCoordNamePtr; | 56 const char* fsCoordNamePtr; |
| 55 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC
oordNamePtr); | 57 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC
oordNamePtr); |
| 56 fsCoordName = fsCoordNamePtr; | 58 fsCoordName = fsCoordNamePtr; |
| 57 | 59 |
| 58 const char* attrName0 = | 60 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); |
| 59 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[
0])->c_str(); | 61 const SkString* attr0Name = |
| 60 builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); | 62 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices(
)[0]); |
| 63 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); |
| 61 | 64 |
| 62 const char* textureSizeUniName = NULL; | 65 const char* textureSizeUniName = NULL; |
| 63 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib
ility, | 66 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi
bility, |
| 64 kVec2f_GrSLType, "TextureSize", | 67 kVec2f_GrSLType, "TextureSize", |
| 65 &textureSizeUniName); | 68 &textureSizeUniName); |
| 66 | 69 |
| 67 builder->fsCodeAppend("\tvec4 texColor = "); | 70 fsBuilder->codeAppend("\tvec4 texColor = "); |
| 68 builder->fsAppendTextureLookup(samplers[0], | 71 fsBuilder->appendTextureLookup(samplers[0], |
| 69 fsCoordName.c_str(), | 72 fsCoordName.c_str(), |
| 70 kVec2f_GrSLType); | 73 kVec2f_GrSLType); |
| 71 builder->fsCodeAppend(";\n"); | 74 fsBuilder->codeAppend(";\n"); |
| 72 builder->fsCodeAppend("\tfloat distance = " | 75 fsBuilder->codeAppend("\tfloat distance = " |
| 73 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan
ceFieldThreshold ")" | 76 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan
ceFieldThreshold ")" |
| 74 "+ " SK_DistanceFieldNonLCDFactor ";\n"); | 77 "+ " SK_DistanceFieldNonLCDFactor ";\n"); |
| 75 | 78 |
| 76 // we adjust for the effect of the transformation on the distance by usi
ng | 79 // we adjust for the effect of the transformation on the distance by usi
ng |
| 77 // the length of the gradient of the texture coordinates. We use st coor
dinates | 80 // the length of the gradient of the texture coordinates. We use st coor
dinates |
| 78 // to ensure we're mapping 1:1 from texel space to pixel space. | 81 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 79 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); | 82 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
| 80 builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); | 83 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); |
| 81 builder->fsCodeAppend("\tfloat afwidth;\n"); | 84 fsBuilder->codeAppend("\tfloat afwidth;\n"); |
| 82 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 85 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
| 83 // this gives us a smooth step across approximately one fragment | 86 // this gives us a smooth step across approximately one fragment |
| 84 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx
(st.x);\n"); | 87 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx
(st.x);\n"); |
| 85 } else { | 88 } else { |
| 86 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); | 89 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
| 87 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); | 90 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
| 88 | 91 |
| 89 builder->fsCodeAppend("\tvec2 uv_grad;\n"); | 92 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); |
| 90 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { | 93 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { |
| 91 // this is to compensate for the Adreno, which likes to drop til
es on division by 0 | 94 // this is to compensate for the Adreno, which likes to drop til
es on division by 0 |
| 92 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); | 95 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); |
| 93 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); | 96 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); |
| 94 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); | 97 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); |
| 95 builder->fsCodeAppend("\t} else {\n"); | 98 fsBuilder->codeAppend("\t} else {\n"); |
| 96 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"
); | 99 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"
); |
| 97 builder->fsCodeAppend("\t}\n"); | 100 fsBuilder->codeAppend("\t}\n"); |
| 98 } else { | 101 } else { |
| 99 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); | 102 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); |
| 100 } | 103 } |
| 101 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.
y*Jdy.x,\n"); | 104 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.
y*Jdy.x,\n"); |
| 102 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.
y*Jdy.y);\n"); | 105 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.
y*Jdy.y);\n"); |
| 103 | 106 |
| 104 // this gives us a smooth step across approximately one fragment | 107 // this gives us a smooth step across approximately one fragment |
| 105 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);\n"); | 108 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);\n"); |
| 106 } | 109 } |
| 107 builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista
nce);\n"); | 110 fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista
nce);\n"); |
| 108 | 111 |
| 109 #ifdef SK_GAMMA_APPLY_TO_A8 | 112 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 110 // adjust based on gamma | 113 // adjust based on gamma |
| 111 const char* luminanceUniName = NULL; | 114 const char* luminanceUniName = NULL; |
| 112 // width, height, 1/(3*width) | 115 // width, height, 1/(3*width) |
| 113 fLuminanceUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil
ity, | 116 fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 114 kFloat_GrSLType, "Luminance", | 117 kFloat_GrSLType, "Luminance", |
| 115 &luminanceUniName); | 118 &luminanceUniName); |
| 116 | 119 |
| 117 builder->fsCodeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); | 120 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); |
| 118 builder->fsCodeAppend("\tvec4 gammaColor = "); | 121 fsBuilder->codeAppend("\tvec4 gammaColor = "); |
| 119 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); | 122 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); |
| 120 builder->fsCodeAppend(";\n"); | 123 fsBuilder->codeAppend(";\n"); |
| 121 builder->fsCodeAppend("\tval = gammaColor.r;\n"); | 124 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); |
| 122 #endif | 125 #endif |
| 123 | 126 |
| 124 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 127 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
| 125 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")
).c_str()); | 128 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")
).c_str()); |
| 126 } | 129 } |
| 127 | 130 |
| 128 virtual void setData(const GrGLProgramDataManager& pdman, | 131 virtual void setData(const GrGLProgramDataManager& pdman, |
| 129 const GrDrawEffect& drawEffect) SK_OVERRIDE { | 132 const GrDrawEffect& drawEffect) SK_OVERRIDE { |
| 130 SkASSERT(fTextureSizeUni.isValid()); | 133 SkASSERT(fTextureSizeUni.isValid()); |
| 131 | 134 |
| 132 GrTexture* texture = drawEffect.effect()->texture(0); | 135 GrTexture* texture = drawEffect.effect()->texture(0); |
| 133 if (texture->width() != fTextureSize.width() || | 136 if (texture->width() != fTextureSize.width() || |
| 134 texture->height() != fTextureSize.height()) { | 137 texture->height() != fTextureSize.height()) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 | 257 |
| 255 /////////////////////////////////////////////////////////////////////////////// | 258 /////////////////////////////////////////////////////////////////////////////// |
| 256 | 259 |
| 257 class GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect { | 260 class GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect { |
| 258 public: | 261 public: |
| 259 GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory, | 262 GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory, |
| 260 const GrDrawEffect& drawEffect) | 263 const GrDrawEffect& drawEffect) |
| 261 : INHERITED (factory) | 264 : INHERITED (factory) |
| 262 , fTextureSize(SkISize::Make(-1,-1)) {} | 265 , fTextureSize(SkISize::Make(-1,-1)) {} |
| 263 | 266 |
| 264 virtual void emitCode(GrGLFullShaderBuilder* builder, | 267 virtual void emitCode(GrGLFullProgramBuilder* builder, |
| 265 const GrDrawEffect& drawEffect, | 268 const GrDrawEffect& drawEffect, |
| 266 const GrEffectKey& key, | 269 const GrEffectKey& key, |
| 267 const char* outputColor, | 270 const char* outputColor, |
| 268 const char* inputColor, | 271 const char* inputColor, |
| 269 const TransformedCoordsArray&, | 272 const TransformedCoordsArray&, |
| 270 const TextureSamplerArray& samplers) SK_OVERRIDE { | 273 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 271 SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().n
umVertexAttribs()); | 274 SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().n
umVertexAttribs()); |
| 272 | 275 |
| 273 SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDeriva
tives_GLSLFeature)); | |
| 274 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 276 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
| 275 drawEffect.castEffect<GrDistanceField
LCDTextureEffect>(); | 277 drawEffect.castEffect<GrDistanceField
LCDTextureEffect>(); |
| 276 | 278 |
| 277 SkString fsCoordName; | 279 SkString fsCoordName; |
| 278 const char* vsCoordName; | 280 const char* vsCoordName; |
| 279 const char* fsCoordNamePtr; | 281 const char* fsCoordNamePtr; |
| 280 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC
oordNamePtr); | 282 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC
oordNamePtr); |
| 281 fsCoordName = fsCoordNamePtr; | 283 fsCoordName = fsCoordNamePtr; |
| 282 | 284 |
| 283 const char* attrName0 = | 285 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); |
| 284 builder->getEffectAttributeName(drawEffect.getVertexAttribInd
ices()[0])->c_str(); | 286 const SkString* attr0Name = |
| 285 builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); | 287 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices(
)[0]); |
| 288 vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); |
| 286 | 289 |
| 287 const char* textureSizeUniName = NULL; | 290 const char* textureSizeUniName = NULL; |
| 288 // width, height, 1/(3*width) | 291 // width, height, 1/(3*width) |
| 289 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib
ility, | 292 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi
bility, |
| 290 kVec3f_GrSLType, "TextureSize", | 293 kVec3f_GrSLType, "TextureSize", |
| 291 &textureSizeUniName); | 294 &textureSizeUniName); |
| 292 | 295 |
| 296 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder
(); |
| 297 |
| 298 SkAssertResult(fsBuilder->enableFeature( |
| 299 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
| 300 |
| 293 // create LCD offset adjusted by inverse of transform | 301 // create LCD offset adjusted by inverse of transform |
| 294 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); | 302 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
| 295 builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); | 303 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); |
| 296 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); | 304 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); |
| 297 if (isUniformScale) { | 305 if (isUniformScale) { |
| 298 builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n"); | 306 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); |
| 299 builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text
ureSizeUniName); | 307 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text
ureSizeUniName); |
| 300 } else { | 308 } else { |
| 301 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); | 309 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
| 302 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); | 310 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
| 303 builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); | 311 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); |
| 304 } | 312 } |
| 305 | 313 |
| 306 // green is distance to uv center | 314 // green is distance to uv center |
| 307 builder->fsCodeAppend("\tvec4 texColor = "); | 315 fsBuilder->codeAppend("\tvec4 texColor = "); |
| 308 builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); | 316 fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); |
| 309 builder->fsCodeAppend(";\n"); | 317 fsBuilder->codeAppend(";\n"); |
| 310 builder->fsCodeAppend("\tvec3 distance;\n"); | 318 fsBuilder->codeAppend("\tvec3 distance;\n"); |
| 311 builder->fsCodeAppend("\tdistance.y = texColor.r;\n"); | 319 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); |
| 312 // red is distance to left offset | 320 // red is distance to left offset |
| 313 builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); | 321 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); |
| 314 builder->fsCodeAppend("\ttexColor = "); | 322 fsBuilder->codeAppend("\ttexColor = "); |
| 315 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); | 323 fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); |
| 316 builder->fsCodeAppend(";\n"); | 324 fsBuilder->codeAppend(";\n"); |
| 317 builder->fsCodeAppend("\tdistance.x = texColor.r;\n"); | 325 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); |
| 318 // blue is distance to right offset | 326 // blue is distance to right offset |
| 319 builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); | 327 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); |
| 320 builder->fsCodeAppend("\ttexColor = "); | 328 fsBuilder->codeAppend("\ttexColor = "); |
| 321 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); | 329 fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); |
| 322 builder->fsCodeAppend(";\n"); | 330 fsBuilder->codeAppend(";\n"); |
| 323 builder->fsCodeAppend("\tdistance.z = texColor.r;\n"); | 331 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); |
| 324 | 332 |
| 325 builder->fsCodeAppend("\tdistance = " | 333 fsBuilder->codeAppend("\tdistance = " |
| 326 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_Distance
FieldThreshold"))" | 334 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_Distance
FieldThreshold"))" |
| 327 "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); | 335 "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); |
| 328 | 336 |
| 329 // we adjust for the effect of the transformation on the distance by usi
ng | 337 // we adjust for the effect of the transformation on the distance by usi
ng |
| 330 // the length of the gradient of the texture coordinates. We use st coor
dinates | 338 // the length of the gradient of the texture coordinates. We use st coor
dinates |
| 331 // to ensure we're mapping 1:1 from texel space to pixel space. | 339 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 332 | 340 |
| 333 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 341 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
| 334 // for each color component. However, this is only important when using
perspective | 342 // for each color component. However, this is only important when using
perspective |
| 335 // transformations, and even then using a single factor seems like a rea
sonable | 343 // transformations, and even then using a single factor seems like a rea
sonable |
| 336 // trade-off between quality and speed. | 344 // trade-off between quality and speed. |
| 337 builder->fsCodeAppend("\tfloat afwidth;\n"); | 345 fsBuilder->codeAppend("\tfloat afwidth;\n"); |
| 338 if (isUniformScale) { | 346 if (isUniformScale) { |
| 339 // this gives us a smooth step across approximately one fragment | 347 // this gives us a smooth step across approximately one fragment |
| 340 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\
n"); | 348 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\
n"); |
| 341 } else { | 349 } else { |
| 342 builder->fsCodeAppend("\tvec2 uv_grad;\n"); | 350 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); |
| 343 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { | 351 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { |
| 344 // this is to compensate for the Adreno, which likes to drop til
es on division by 0 | 352 // this is to compensate for the Adreno, which likes to drop til
es on division by 0 |
| 345 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); | 353 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); |
| 346 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); | 354 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); |
| 347 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); | 355 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); |
| 348 builder->fsCodeAppend("\t} else {\n"); | 356 fsBuilder->codeAppend("\t} else {\n"); |
| 349 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"
); | 357 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"
); |
| 350 builder->fsCodeAppend("\t}\n"); | 358 fsBuilder->codeAppend("\t}\n"); |
| 351 } else { | 359 } else { |
| 352 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); | 360 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); |
| 353 } | 361 } |
| 354 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.
y*Jdy.x,\n"); | 362 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.
y*Jdy.x,\n"); |
| 355 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.
y*Jdy.y);\n"); | 363 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.
y*Jdy.y);\n"); |
| 356 | 364 |
| 357 // this gives us a smooth step across approximately one fragment | 365 // this gives us a smooth step across approximately one fragment |
| 358 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);\n"); | 366 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng
th(grad);\n"); |
| 359 } | 367 } |
| 360 | 368 |
| 361 builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3
(afwidth), distance), 1.0);\n"); | 369 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3
(afwidth), distance), 1.0);\n"); |
| 362 | 370 |
| 363 // adjust based on gamma | 371 // adjust based on gamma |
| 364 const char* textColorUniName = NULL; | 372 const char* textColorUniName = NULL; |
| 365 // width, height, 1/(3*width) | 373 // width, height, 1/(3*width) |
| 366 fTextColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil
ity, | 374 fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 367 kVec3f_GrSLType, "TextColor", | 375 kVec3f_GrSLType, "TextColor", |
| 368 &textColorUniName); | 376 &textColorUniName); |
| 369 | 377 |
| 370 builder->fsCodeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); | 378 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); |
| 371 builder->fsCodeAppend("\tvec4 gammaColor = "); | 379 fsBuilder->codeAppend("\tvec4 gammaColor = "); |
| 372 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); | 380 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); |
| 373 builder->fsCodeAppend(";\n"); | 381 fsBuilder->codeAppend(";\n"); |
| 374 builder->fsCodeAppend("\tval.x = gammaColor.r;\n"); | 382 fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); |
| 375 | 383 |
| 376 builder->fsCodeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); | 384 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); |
| 377 builder->fsCodeAppend("\tgammaColor = "); | 385 fsBuilder->codeAppend("\tgammaColor = "); |
| 378 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); | 386 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); |
| 379 builder->fsCodeAppend(";\n"); | 387 fsBuilder->codeAppend(";\n"); |
| 380 builder->fsCodeAppend("\tval.y = gammaColor.r;\n"); | 388 fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); |
| 381 | 389 |
| 382 builder->fsCodeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); | 390 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); |
| 383 builder->fsCodeAppend("\tgammaColor = "); | 391 fsBuilder->codeAppend("\tgammaColor = "); |
| 384 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); | 392 fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); |
| 385 builder->fsCodeAppend(";\n"); | 393 fsBuilder->codeAppend(";\n"); |
| 386 builder->fsCodeAppend("\tval.z = gammaColor.r;\n"); | 394 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); |
| 387 | 395 |
| 388 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 396 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
| 389 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_
str()); | 397 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_
str()); |
| 390 } | 398 } |
| 391 | 399 |
| 392 virtual void setData(const GrGLProgramDataManager& pdman, | 400 virtual void setData(const GrGLProgramDataManager& pdman, |
| 393 const GrDrawEffect& drawEffect) SK_OVERRIDE { | 401 const GrDrawEffect& drawEffect) SK_OVERRIDE { |
| 394 SkASSERT(fTextureSizeUni.isValid()); | 402 SkASSERT(fTextureSizeUni.isValid()); |
| 395 SkASSERT(fTextColorUni.isValid()); | 403 SkASSERT(fTextColorUni.isValid()); |
| 396 | 404 |
| 397 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 405 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
| 398 drawEffect.castEffect<GrDistanceFieldLCDText
ureEffect>(); | 406 drawEffect.castEffect<GrDistanceFieldLCDText
ureEffect>(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 random->nextULessThan(256), | 517 random->nextULessThan(256), |
| 510 random->nextULessThan(256)); | 518 random->nextULessThan(256)); |
| 511 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 519 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
| 512 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 520 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
| 513 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 521 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| 514 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, | 522 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, |
| 515 textures[texIdx2], params2, | 523 textures[texIdx2], params2, |
| 516 textColor, | 524 textColor, |
| 517 flags); | 525 flags); |
| 518 } | 526 } |
| OLD | NEW |