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 |