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/GrGLEffect.h" | 9 #include "gl/GrGLEffect.h" |
10 #include "gl/GrGLSL.h" | 10 #include "gl/GrGLSL.h" |
11 #include "gl/GrGLTexture.h" | 11 #include "gl/GrGLTexture.h" |
12 #include "gl/GrGLVertexEffect.h" | 12 #include "gl/GrGLVertexEffect.h" |
13 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
14 #include "GrTexture.h" | 14 #include "GrTexture.h" |
15 | 15 |
16 // The distance field is constructed as unsigned char values, so that the zero v
alue is at 128, | 16 #include "SkDistanceFieldGen.h" |
17 // and the range is [-4, 4 - 1/255). Hence our multiplier is 8 - 1/32 and zero t
hreshold is 128/255. | |
18 #define MULTIPLIER "7.96875" | |
19 #define THRESHOLD "0.50196078431" | |
20 | 17 |
21 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { | 18 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { |
22 public: | 19 public: |
23 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, | 20 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, |
24 const GrDrawEffect& drawEffect) | 21 const GrDrawEffect& drawEffect) |
25 : INHERITED (factory) | 22 : INHERITED (factory) |
26 , fTextureSize(SkISize::Make(-1,-1)) {} | 23 , fTextureSize(SkISize::Make(-1,-1)) {} |
27 | 24 |
28 virtual void emitCode(GrGLFullShaderBuilder* builder, | 25 virtual void emitCode(GrGLFullShaderBuilder* builder, |
29 const GrDrawEffect& drawEffect, | 26 const GrDrawEffect& drawEffect, |
(...skipping 21 matching lines...) Expand all Loading... |
51 const char* textureSizeUniName = NULL; | 48 const char* textureSizeUniName = NULL; |
52 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib
ility, | 49 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib
ility, |
53 kVec2f_GrSLType, "TextureSize", | 50 kVec2f_GrSLType, "TextureSize", |
54 &textureSizeUniName); | 51 &textureSizeUniName); |
55 | 52 |
56 builder->fsCodeAppend("\tvec4 texColor = "); | 53 builder->fsCodeAppend("\tvec4 texColor = "); |
57 builder->fsAppendTextureLookup(samplers[0], | 54 builder->fsAppendTextureLookup(samplers[0], |
58 fsCoordName.c_str(), | 55 fsCoordName.c_str(), |
59 kVec2f_GrSLType); | 56 kVec2f_GrSLType); |
60 builder->fsCodeAppend(";\n"); | 57 builder->fsCodeAppend(";\n"); |
61 builder->fsCodeAppend("\tfloat distance = " MULTIPLIER "*(texColor.r - "
THRESHOLD ");\n"); | 58 builder->fsCodeAppend("\tfloat distance = " |
| 59 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie
ldThreshold ");\n"); |
62 | 60 |
63 // we adjust for the effect of the transformation on the distance by usi
ng | 61 // we adjust for the effect of the transformation on the distance by usi
ng |
64 // the length of the gradient of the texture coordinates. We use st coor
dinates | 62 // the length of the gradient of the texture coordinates. We use st coor
dinates |
65 // to ensure we're mapping 1:1 from texel space to pixel space. | 63 // to ensure we're mapping 1:1 from texel space to pixel space. |
66 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); | 64 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
67 builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); | 65 builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); |
68 builder->fsCodeAppend("\tfloat afwidth;\n"); | 66 builder->fsCodeAppend("\tfloat afwidth;\n"); |
69 if (dfTexEffect.isSimilarity()) { | 67 if (dfTexEffect.isSimilarity()) { |
70 // this gives us a smooth step across approximately one fragment | 68 // this gives us a smooth step across approximately one fragment |
71 // (assuming a radius of the diagonal of the fragment, hence a facto
r of sqrt(2)/2) | 69 // (assuming a radius of the diagonal of the fragment, hence a facto
r of sqrt(2)/2) |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); | 230 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); |
233 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); | 231 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); |
234 builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); | 232 builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); |
235 } | 233 } |
236 | 234 |
237 // green is distance to uv center | 235 // green is distance to uv center |
238 builder->fsCodeAppend("\tvec4 texColor = "); | 236 builder->fsCodeAppend("\tvec4 texColor = "); |
239 builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); | 237 builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); |
240 builder->fsCodeAppend(";\n"); | 238 builder->fsCodeAppend(";\n"); |
241 builder->fsCodeAppend("\tvec3 distance;\n"); | 239 builder->fsCodeAppend("\tvec3 distance;\n"); |
242 builder->fsCodeAppend("\tdistance.y = " MULTIPLIER "*(texColor.r - " THR
ESHOLD ");\n"); | 240 builder->fsCodeAppend("\tdistance.y = " |
| 241 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie
ldThreshold ");\n"); |
243 // red is distance to left offset | 242 // red is distance to left offset |
244 builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); | 243 builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); |
245 builder->fsCodeAppend("\ttexColor = "); | 244 builder->fsCodeAppend("\ttexColor = "); |
246 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); | 245 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); |
247 builder->fsCodeAppend(";\n"); | 246 builder->fsCodeAppend(";\n"); |
248 builder->fsCodeAppend("\tdistance.x = " MULTIPLIER "*(texColor.r - " THR
ESHOLD ");\n"); | 247 builder->fsCodeAppend("\tdistance.x = " |
| 248 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie
ldThreshold ");\n"); |
249 // blue is distance to right offset | 249 // blue is distance to right offset |
250 builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); | 250 builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); |
251 builder->fsCodeAppend("\ttexColor = "); | 251 builder->fsCodeAppend("\ttexColor = "); |
252 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); | 252 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy
pe); |
253 builder->fsCodeAppend(";\n"); | 253 builder->fsCodeAppend(";\n"); |
254 builder->fsCodeAppend("\tdistance.z = " MULTIPLIER "*(texColor.r - " THR
ESHOLD ");\n"); | 254 builder->fsCodeAppend("\tdistance.z = " |
255 | 255 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie
ldThreshold ");\n"); |
256 // we adjust for the effect of the transformation on the distance by usi
ng | 256 // we adjust for the effect of the transformation on the distance by usi
ng |
257 // the length of the gradient of the texture coordinates. We use st coor
dinates | 257 // the length of the gradient of the texture coordinates. We use st coor
dinates |
258 // to ensure we're mapping 1:1 from texel space to pixel space. | 258 // to ensure we're mapping 1:1 from texel space to pixel space. |
259 | 259 |
260 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 260 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
261 // for each color component. However, this is only important when using
perspective | 261 // for each color component. However, this is only important when using
perspective |
262 // transformations, and even then using a single factor seems like a rea
sonable | 262 // transformations, and even then using a single factor seems like a rea
sonable |
263 // trade-off between quality and speed. | 263 // trade-off between quality and speed. |
264 builder->fsCodeAppend("\tfloat afwidth;\n"); | 264 builder->fsCodeAppend("\tfloat afwidth;\n"); |
265 if (dfTexEffect.isUniformScale()) { | 265 if (dfTexEffect.isUniformScale()) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 SkShader::TileMode tileModes[] = { | 380 SkShader::TileMode tileModes[] = { |
381 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 381 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
382 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 382 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
383 }; | 383 }; |
384 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : | 384 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : |
385 GrTextureParams::kNone_FilterMode); | 385 GrTextureParams::kNone_FilterMode); |
386 | 386 |
387 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, | 387 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, |
388 random->nextBool(), random->n
extBool()); | 388 random->nextBool(), random->n
extBool()); |
389 } | 389 } |
OLD | NEW |