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 // The distance field is constructed as unsigned char values, so that the zero v
alue is at 128, |
17 // Hence our zero threshold is 128/255. | 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" |
18 #define THRESHOLD "0.50196078431" | 19 #define THRESHOLD "0.50196078431" |
19 | 20 |
20 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { | 21 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { |
21 public: | 22 public: |
22 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, const
GrDrawEffect& drawEffect) | 23 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, |
| 24 const GrDrawEffect& drawEffect) |
23 : INHERITED (factory) {} | 25 : INHERITED (factory) {} |
24 | 26 |
25 virtual void emitCode(GrGLFullShaderBuilder* builder, | 27 virtual void emitCode(GrGLFullShaderBuilder* builder, |
26 const GrDrawEffect& drawEffect, | 28 const GrDrawEffect& drawEffect, |
27 EffectKey key, | 29 EffectKey key, |
28 const char* outputColor, | 30 const char* outputColor, |
29 const char* inputColor, | 31 const char* inputColor, |
30 const TransformedCoordsArray&, | 32 const TransformedCoordsArray&, |
31 const TextureSamplerArray& samplers) SK_OVERRIDE { | 33 const TextureSamplerArray& samplers) SK_OVERRIDE { |
32 SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numV
ertexAttribs()); | 34 SkASSERT(2 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numV
ertexAttribs()); |
33 | 35 |
34 SkString fsCoordName; | 36 SkString fsCoordName; |
35 const char* vsVaryingName; | 37 const char* vsCoordName; |
36 const char* fsVaryingNamePtr; | 38 const char* fsCoordNamePtr; |
37 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &f
sVaryingNamePtr); | 39 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC
oordNamePtr); |
38 fsCoordName = fsVaryingNamePtr; | 40 fsCoordName = fsCoordNamePtr; |
39 | 41 |
40 const char* attrName = | 42 SkString fsSizeName; |
| 43 const char* vsSizeName; |
| 44 const char* fsSizeNamePtr; |
| 45 builder->addVarying(kVec2f_GrSLType, "size", &vsSizeName, &fsSizeNamePtr
); |
| 46 fsSizeName = fsSizeNamePtr; |
| 47 |
| 48 const char* attrName0 = |
41 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[
0])->c_str(); | 49 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[
0])->c_str(); |
42 builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName); | 50 builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); |
| 51 const char* attrName1 = |
| 52 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[
1])->c_str(); |
| 53 builder->vsCodeAppendf("\t%s = %s;\n", vsSizeName, attrName1); |
43 | 54 |
44 builder->fsCodeAppend("\tvec4 texColor = "); | 55 builder->fsCodeAppend("\tvec4 texColor = "); |
45 builder->fsAppendTextureLookup(samplers[0], | 56 builder->fsAppendTextureLookup(samplers[0], |
46 fsCoordName.c_str(), | 57 fsCoordName.c_str(), |
47 kVec2f_GrSLType); | 58 kVec2f_GrSLType); |
48 builder->fsCodeAppend(";\n"); | 59 builder->fsCodeAppend(";\n"); |
49 builder->fsCodeAppend("\tfloat distance = texColor.r;\n"); | 60 builder->fsCodeAppend("\tfloat distance = "MULTIPLIER"*(texColor.r - "TH
RESHOLD");\n"); |
| 61 |
| 62 builder->fsCodeAppendf("\tvec2 st = %s*%s;\n", fsCoordName.c_str(), fsSi
zeName.c_str()); |
| 63 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); |
| 64 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); |
| 65 builder->fsCodeAppend("\tvec2 st_grad = normalize(st);\n"); |
| 66 builder->fsCodeAppend("\tvec2 grad = vec2(st_grad.x*Jdx.x + st_grad.y*Jd
y.x,\n"); |
| 67 builder->fsCodeAppend("\t st_grad.x*Jdx.y + st_grad.y*Jd
y.y);\n"); |
| 68 |
50 // this gives us a smooth step across approximately one fragment | 69 // this gives us a smooth step across approximately one fragment |
51 // (assuming a radius of the diagonal of the fragment, hence a factor of
sqrt(2)/2) | 70 // (assuming a radius of the diagonal of the fragment, hence a factor of
sqrt(2)/2) |
52 builder->fsCodeAppend("\tfloat afwidth = 0.7071*length(vec2(dFdx(distanc
e), dFdy(distance)));\n"); | 71 builder->fsCodeAppend("\tfloat afwidth = 0.7071*length(grad);\n"); |
53 builder->fsCodeAppend("\tfloat val = smoothstep("THRESHOLD"-afwidth, "TH
RESHOLD"+afwidth, distance);\n"); | 72 builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista
nce);\n"); |
54 | 73 |
55 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 74 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, |
56 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")
).c_str()); | 75 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")
).c_str()); |
57 } | 76 } |
58 | 77 |
59 virtual void setData(const GrGLUniformManager& uman, | 78 virtual void setData(const GrGLUniformManager& uman, |
60 const GrDrawEffect& drawEffect) SK_OVERRIDE {} | 79 const GrDrawEffect& drawEffect) SK_OVERRIDE {} |
61 | 80 |
62 private: | 81 private: |
63 typedef GrGLVertexEffect INHERITED; | 82 typedef GrGLVertexEffect INHERITED; |
64 }; | 83 }; |
65 | 84 |
66 /////////////////////////////////////////////////////////////////////////////// | 85 /////////////////////////////////////////////////////////////////////////////// |
67 | 86 |
68 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, | 87 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, |
69 const GrTextureParams&
params) | 88 const GrTextureParams&
params) |
70 : fTextureAccess(texture, params) { | 89 : fTextureAccess(texture, params) { |
71 this->addTextureAccess(&fTextureAccess); | 90 this->addTextureAccess(&fTextureAccess); |
72 this->addVertexAttrib(kVec2f_GrSLType); | 91 this->addVertexAttrib(kVec2f_GrSLType); |
| 92 this->addVertexAttrib(kVec2f_GrSLType); |
73 } | 93 } |
74 | 94 |
75 bool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const { | 95 bool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const { |
76 const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureE
ffect>(other); | 96 const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureE
ffect>(other); |
77 return fTextureAccess == cte.fTextureAccess; | 97 return fTextureAccess == cte.fTextureAccess; |
78 } | 98 } |
79 | 99 |
80 void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, | 100 void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, |
81 uint32_t* validFlag
s) const { | 101 uint32_t* validFlag
s) const { |
82 if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color
) && | 102 if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color
) && |
(...skipping 25 matching lines...) Expand all Loading... |
108 }; | 128 }; |
109 SkShader::TileMode tileModes[] = { | 129 SkShader::TileMode tileModes[] = { |
110 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 130 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
111 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 131 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
112 }; | 132 }; |
113 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : | 133 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : |
114 GrTextureParams::kNon
e_FilterMode); | 134 GrTextureParams::kNon
e_FilterMode); |
115 | 135 |
116 return GrDistanceFieldTextureEffect::Create(textures[texIdx], params); | 136 return GrDistanceFieldTextureEffect::Create(textures[texIdx], params); |
117 } | 137 } |
OLD | NEW |