Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: src/gpu/effects/GrDistanceFieldTextureEffect.cpp

Issue 323513005: Revert of Gamma correction for distance field text. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDistanceFieldTextureEffect.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "SkDistanceFieldGen.h" 16 #include "SkDistanceFieldGen.h"
17 17
18 // To get optical sizes people don't complain about when we blit correctly,
19 // we need to slightly bold each glyph. On the Mac, we need a larger bold value.
20 #if defined(SK_BUILD_FOR_MAC)
21 #define SK_DistanceFieldLCDFactor "0.33"
22 #define SK_DistanceFieldNonLCDFactor "0.25"
23 #else
24 #define SK_DistanceFieldLCDFactor "0.05"
25 #define SK_DistanceFieldNonLCDFactor "0.05"
26 #endif
27
28 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/ 2
29 #define SK_DistanceFieldAAFactor "0.7071"
30
31 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { 18 class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect {
32 public: 19 public:
33 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, 20 GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory,
34 const GrDrawEffect& drawEffect) 21 const GrDrawEffect& drawEffect)
35 : INHERITED (factory) 22 : INHERITED (factory)
36 , fTextureSize(SkISize::Make(-1,-1)) {} 23 , fTextureSize(SkISize::Make(-1,-1)) {}
37 24
38 virtual void emitCode(GrGLFullShaderBuilder* builder, 25 virtual void emitCode(GrGLFullShaderBuilder* builder,
39 const GrDrawEffect& drawEffect, 26 const GrDrawEffect& drawEffect,
40 EffectKey key, 27 EffectKey key,
(...skipping 21 matching lines...) Expand all
62 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib ility, 49 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib ility,
63 kVec2f_GrSLType, "TextureSize", 50 kVec2f_GrSLType, "TextureSize",
64 &textureSizeUniName); 51 &textureSizeUniName);
65 52
66 builder->fsCodeAppend("\tvec4 texColor = "); 53 builder->fsCodeAppend("\tvec4 texColor = ");
67 builder->fsAppendTextureLookup(samplers[0], 54 builder->fsAppendTextureLookup(samplers[0],
68 fsCoordName.c_str(), 55 fsCoordName.c_str(),
69 kVec2f_GrSLType); 56 kVec2f_GrSLType);
70 builder->fsCodeAppend(";\n"); 57 builder->fsCodeAppend(";\n");
71 builder->fsCodeAppend("\tfloat distance = " 58 builder->fsCodeAppend("\tfloat distance = "
72 SK_DistanceFieldMultiplier "*(texColor.r - " SK_Distan ceFieldThreshold ")" 59 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie ldThreshold ");\n");
73 "+ " SK_DistanceFieldNonLCDFactor ";\n");
74 60
75 // 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
76 // 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
77 // 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.
78 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 64 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
79 builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 65 builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
80 builder->fsCodeAppend("\tfloat afwidth;\n"); 66 builder->fsCodeAppend("\tfloat afwidth;\n");
81 if (dfTexEffect.isSimilarity()) { 67 if (dfTexEffect.isSimilarity()) {
82 // this gives us a smooth step across approximately one fragment 68 // this gives us a smooth step across approximately one fragment
83 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx (st.x);\n"); 69 // (assuming a radius of the diagonal of the fragment, hence a facto r of sqrt(2)/2)
70 builder->fsCodeAppend("\tafwidth = 0.7071*dFdx(st.x);\n");
84 } else { 71 } else {
85 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); 72 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
86 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); 73 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
87 74
88 builder->fsCodeAppend("\tvec2 uv_grad;\n"); 75 builder->fsCodeAppend("\tvec2 uv_grad;\n");
89 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 76 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
90 // this is to compensate for the Adreno, which likes to drop til es on division by 0 77 // this is to compensate for the Adreno, which likes to drop til es on division by 0
91 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 78 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
92 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); 79 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
93 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 80 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
94 builder->fsCodeAppend("\t} else {\n"); 81 builder->fsCodeAppend("\t} else {\n");
95 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 82 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
96 builder->fsCodeAppend("\t}\n"); 83 builder->fsCodeAppend("\t}\n");
97 } else { 84 } else {
98 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); 85 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
99 } 86 }
100 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n"); 87 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n");
101 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n"); 88 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n");
102 89
103 // this gives us a smooth step across approximately one fragment 90 // this gives us a smooth step across approximately one fragment
104 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n"); 91 // (assuming a radius of the diagonal of the fragment, hence a facto r of sqrt(2)/2)
92 builder->fsCodeAppend("\tafwidth = 0.7071*length(grad);\n");
105 } 93 }
94
106 builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista nce);\n"); 95 builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, dista nce);\n");
107 96
108 #ifdef SK_GAMMA_APPLY_TO_A8
109 // adjust based on gamma
110 const char* luminanceUniName = NULL;
111 // width, height, 1/(3*width)
112 fLuminanceUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil ity,
113 kFloat_GrSLType, "Luminance",
114 &luminanceUniName);
115
116 builder->fsCodeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
117 builder->fsCodeAppend("\tvec4 gammaColor = ");
118 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
119 builder->fsCodeAppend(";\n");
120 builder->fsCodeAppend("\tval = gammaColor.r;\n");
121 #endif
122
123 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, 97 builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
124 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val") ).c_str()); 98 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val") ).c_str());
125 } 99 }
126 100
127 virtual void setData(const GrGLUniformManager& uman, 101 virtual void setData(const GrGLUniformManager& uman,
128 const GrDrawEffect& drawEffect) SK_OVERRIDE { 102 const GrDrawEffect& drawEffect) SK_OVERRIDE {
129 SkASSERT(fTextureSizeUni.isValid()); 103 SkASSERT(fTextureSizeUni.isValid());
130 104
131 GrTexture* texture = drawEffect.effect()->get()->texture(0); 105 GrTexture* texture = drawEffect.effect()->get()->texture(0);
132 if (texture->width() != fTextureSize.width() || 106 if (texture->width() != fTextureSize.width() ||
133 texture->height() != fTextureSize.height()) { 107 texture->height() != fTextureSize.height()) {
134 fTextureSize = SkISize::Make(texture->width(), texture->height()); 108 fTextureSize = SkISize::Make(texture->width(), texture->height());
135 uman.set2f(fTextureSizeUni, 109 uman.set2f(fTextureSizeUni,
136 SkIntToScalar(fTextureSize.width()), 110 SkIntToScalar(fTextureSize.width()),
137 SkIntToScalar(fTextureSize.height())); 111 SkIntToScalar(fTextureSize.height()));
138 } 112 }
139 #ifdef SK_GAMMA_APPLY_TO_A8
140 const GrDistanceFieldTextureEffect& dfTexEffect =
141 drawEffect.castEffect<GrDistanceFi eldTextureEffect>();
142 float luminance = dfTexEffect.getLuminance();
143 if (luminance != fLuminance) {
144 uman.set1f(fLuminanceUni, luminance);
145 fLuminance = luminance;
146 }
147 #endif
148 } 113 }
149 114
150 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&) { 115 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&) {
151 const GrDistanceFieldTextureEffect& dfTexEffect = 116 const GrDistanceFieldTextureEffect& dfTexEffect =
152 drawEffect.castEffect<GrDistanceFi eldTextureEffect>(); 117 drawEffect.castEffect<GrDistanceFi eldTextureEffect>();
153 118
154 return dfTexEffect.isSimilarity() ? 0x1 : 0x0; 119 return dfTexEffect.isSimilarity() ? 0x1 : 0x0;
155 } 120 }
156 121
157 private: 122 private:
158 GrGLUniformManager::UniformHandle fTextureSizeUni; 123 GrGLUniformManager::UniformHandle fTextureSizeUni;
159 SkISize fTextureSize; 124 SkISize fTextureSize;
160 GrGLUniformManager::UniformHandle fLuminanceUni;
161 float fLuminance;
162 125
163 typedef GrGLVertexEffect INHERITED; 126 typedef GrGLVertexEffect INHERITED;
164 }; 127 };
165 128
166 /////////////////////////////////////////////////////////////////////////////// 129 ///////////////////////////////////////////////////////////////////////////////
167 130
168 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, 131 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture,
169 const GrTextureParams & params, 132 const GrTextureParams & params,
170 #ifdef SK_GAMMA_APPLY_TO_A8
171 GrTexture* gamma,
172 const GrTextureParams & gammaParams,
173 float luminance,
174 #endif
175 bool similarity) 133 bool similarity)
176 : fTextureAccess(texture, params) 134 : fTextureAccess(texture, params)
177 #ifdef SK_GAMMA_APPLY_TO_A8
178 , fGammaTextureAccess(gamma, gammaParams)
179 , fLuminance(luminance)
180 #endif
181 , fIsSimilarity(similarity) { 135 , fIsSimilarity(similarity) {
182 this->addTextureAccess(&fTextureAccess); 136 this->addTextureAccess(&fTextureAccess);
183 #ifdef SK_GAMMA_APPLY_TO_A8
184 this->addTextureAccess(&fGammaTextureAccess);
185 #endif
186 this->addVertexAttrib(kVec2f_GrSLType); 137 this->addVertexAttrib(kVec2f_GrSLType);
187 } 138 }
188 139
189 bool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const { 140 bool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const {
190 const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureE ffect>(other); 141 const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureE ffect>(other);
191 return fTextureAccess == cte.fTextureAccess; 142 return fTextureAccess == cte.fTextureAccess;
192 } 143 }
193 144
194 void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, 145 void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color,
195 uint32_t* validFlag s) const { 146 uint32_t* validFlag s) const {
(...skipping 12 matching lines...) Expand all
208 /////////////////////////////////////////////////////////////////////////////// 159 ///////////////////////////////////////////////////////////////////////////////
209 160
210 GR_DEFINE_EFFECT_TEST(GrDistanceFieldTextureEffect); 161 GR_DEFINE_EFFECT_TEST(GrDistanceFieldTextureEffect);
211 162
212 GrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 163 GrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
213 GrContext*, 164 GrContext*,
214 const GrDrawTargetCaps&, 165 const GrDrawTargetCaps&,
215 GrTexture* textures[]) { 166 GrTexture* textures[]) {
216 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 167 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
217 GrEffectUnitTest::kAlphaTextureIdx; 168 GrEffectUnitTest::kAlphaTextureIdx;
218 #ifdef SK_GAMMA_APPLY_TO_A8
219 int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
220 GrEffectUnitTest::kAlphaTextureIdx;
221 #endif
222 static const SkShader::TileMode kTileModes[] = { 169 static const SkShader::TileMode kTileModes[] = {
223 SkShader::kClamp_TileMode, 170 SkShader::kClamp_TileMode,
224 SkShader::kRepeat_TileMode, 171 SkShader::kRepeat_TileMode,
225 SkShader::kMirror_TileMode, 172 SkShader::kMirror_TileMode,
226 }; 173 };
227 SkShader::TileMode tileModes[] = { 174 SkShader::TileMode tileModes[] = {
228 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 175 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
229 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 176 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
230 }; 177 };
231 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode : 178 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode :
232 GrTextureParams::kNon e_FilterMode); 179 GrTextureParams::kNon e_FilterMode);
233 #ifdef SK_GAMMA_APPLY_TO_A8
234 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBi lerp_FilterMode :
235 GrTextureParams::kNo ne_FilterMode);
236 #endif
237 180
238 return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, 181 return GrDistanceFieldTextureEffect::Create(textures[texIdx], params,
239 #ifdef SK_GAMMA_APPLY_TO_A8
240 textures[texIdx2], params2,
241 random->nextF(),
242 #endif
243 random->nextBool()); 182 random->nextBool());
244 } 183 }
245 184
246 /////////////////////////////////////////////////////////////////////////////// 185 ///////////////////////////////////////////////////////////////////////////////
247 186
248 class GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect { 187 class GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect {
249 public: 188 public:
250 GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory, 189 GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory,
251 const GrDrawEffect& drawEffect) 190 const GrDrawEffect& drawEffect)
252 : INHERITED (factory) 191 : INHERITED (factory)
(...skipping 12 matching lines...) Expand all
265 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 204 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
266 drawEffect.castEffect<GrDistanceField LCDTextureEffect>(); 205 drawEffect.castEffect<GrDistanceField LCDTextureEffect>();
267 206
268 SkString fsCoordName; 207 SkString fsCoordName;
269 const char* vsCoordName; 208 const char* vsCoordName;
270 const char* fsCoordNamePtr; 209 const char* fsCoordNamePtr;
271 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr); 210 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr);
272 fsCoordName = fsCoordNamePtr; 211 fsCoordName = fsCoordNamePtr;
273 212
274 const char* attrName0 = 213 const char* attrName0 =
275 builder->getEffectAttributeName(drawEffect.getVertexAttribInd ices()[0])->c_str(); 214 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])- >c_str();
276 builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); 215 builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0);
277 216
278 const char* textureSizeUniName = NULL; 217 const char* textureSizeUniName = NULL;
279 // width, height, 1/(3*width) 218 // width, height, 1/(3*width)
280 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib ility, 219 fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visib ility,
281 kVec3f_GrSLType, "TextureSize", 220 kVec3f_GrSLType, "TextureSize",
282 &textureSizeUniName); 221 &textureSizeUniName);
283 222
284 // create LCD offset adjusted by inverse of transform 223 // create LCD offset adjusted by inverse of transform
285 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 224 builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
286 builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 225 builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
287 if (dfTexEffect.isUniformScale()) { 226 if (dfTexEffect.isUniformScale()) {
288 builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n"); 227 builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n");
289 builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text ureSizeUniName); 228 builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text ureSizeUniName);
290 } else { 229 } else {
291 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); 230 builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
292 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); 231 builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
293 builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni Name); 232 builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni Name);
294 } 233 }
295 234
296 // green is distance to uv center 235 // green is distance to uv center
297 builder->fsCodeAppend("\tvec4 texColor = "); 236 builder->fsCodeAppend("\tvec4 texColor = ");
298 builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); 237 builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType);
299 builder->fsCodeAppend(";\n"); 238 builder->fsCodeAppend(";\n");
300 builder->fsCodeAppend("\tvec3 distance;\n"); 239 builder->fsCodeAppend("\tvec3 distance;\n");
301 builder->fsCodeAppend("\tdistance.y = texColor.r;\n"); 240 builder->fsCodeAppend("\tdistance.y = "
241 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie ldThreshold ");\n");
302 // red is distance to left offset 242 // red is distance to left offset
303 builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 243 builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n");
304 builder->fsCodeAppend("\ttexColor = "); 244 builder->fsCodeAppend("\ttexColor = ");
305 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe); 245 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe);
306 builder->fsCodeAppend(";\n"); 246 builder->fsCodeAppend(";\n");
307 builder->fsCodeAppend("\tdistance.x = texColor.r;\n"); 247 builder->fsCodeAppend("\tdistance.x = "
248 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie ldThreshold ");\n");
308 // blue is distance to right offset 249 // blue is distance to right offset
309 builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); 250 builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n");
310 builder->fsCodeAppend("\ttexColor = "); 251 builder->fsCodeAppend("\ttexColor = ");
311 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe); 252 builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLTy pe);
312 builder->fsCodeAppend(";\n"); 253 builder->fsCodeAppend(";\n");
313 builder->fsCodeAppend("\tdistance.z = texColor.r;\n"); 254 builder->fsCodeAppend("\tdistance.z = "
314 255 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFie ldThreshold ");\n");
315 builder->fsCodeAppend("\tdistance = "
316 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_Distance FieldThreshold"))"
317 "+ vec3(" SK_DistanceFieldLCDFactor ");\n");
318
319 // 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
320 // 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
321 // 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.
322 259
323 // 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
324 // 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
325 // 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
326 // trade-off between quality and speed. 263 // trade-off between quality and speed.
327 builder->fsCodeAppend("\tfloat afwidth;\n"); 264 builder->fsCodeAppend("\tfloat afwidth;\n");
328 if (dfTexEffect.isUniformScale()) { 265 if (dfTexEffect.isUniformScale()) {
329 // this gives us a smooth step across approximately one fragment 266 // this gives us a smooth step across approximately one fragment
330 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\ n"); 267 // (assuming a radius of the diagonal of the fragment, hence a facto r of sqrt(2)/2)
268 builder->fsCodeAppend("\tafwidth = 0.7071*dx;\n");
331 } else { 269 } else {
332 builder->fsCodeAppend("\tvec2 uv_grad;\n"); 270 builder->fsCodeAppend("\tvec2 uv_grad;\n");
333 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 271 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
334 // this is to compensate for the Adreno, which likes to drop til es on division by 0 272 // this is to compensate for the Adreno, which likes to drop til es on division by 0
335 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 273 builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
336 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); 274 builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
337 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 275 builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
338 builder->fsCodeAppend("\t} else {\n"); 276 builder->fsCodeAppend("\t} else {\n");
339 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 277 builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
340 builder->fsCodeAppend("\t}\n"); 278 builder->fsCodeAppend("\t}\n");
341 } else { 279 } else {
342 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); 280 builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
343 } 281 }
344 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n"); 282 builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad. y*Jdy.x,\n");
345 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n"); 283 builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad. y*Jdy.y);\n");
346 284
347 // this gives us a smooth step across approximately one fragment 285 // this gives us a smooth step across approximately one fragment
348 builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*leng th(grad);\n"); 286 // (assuming a radius of the diagonal of the fragment, hence a facto r of sqrt(2)/2)
287 builder->fsCodeAppend("\tafwidth = 0.7071*length(grad);\n");
349 } 288 }
350 289
351 builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3 (afwidth), distance), 1.0);\n"); 290 builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3 (afwidth), distance), 1.0);\n");
352 291
353 // adjust based on gamma
354 const char* textColorUniName = NULL;
355 // width, height, 1/(3*width)
356 fTextColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil ity,
357 kVec3f_GrSLType, "TextColor",
358 &textColorUniName);
359
360 builder->fsCodeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
361 builder->fsCodeAppend("\tvec4 gammaColor = ");
362 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
363 builder->fsCodeAppend(";\n");
364 builder->fsCodeAppend("\tval.x = gammaColor.r;\n");
365
366 builder->fsCodeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
367 builder->fsCodeAppend("\tgammaColor = ");
368 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
369 builder->fsCodeAppend(";\n");
370 builder->fsCodeAppend("\tval.y = gammaColor.r;\n");
371
372 builder->fsCodeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
373 builder->fsCodeAppend("\tgammaColor = ");
374 builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
375 builder->fsCodeAppend(";\n");
376 builder->fsCodeAppend("\tval.z = gammaColor.r;\n");
377
378 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, 292 builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
379 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_ str()); 293 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_ str());
380 } 294 }
381 295
382 virtual void setData(const GrGLUniformManager& uman, 296 virtual void setData(const GrGLUniformManager& uman,
383 const GrDrawEffect& drawEffect) SK_OVERRIDE { 297 const GrDrawEffect& drawEffect) SK_OVERRIDE {
384 SkASSERT(fTextureSizeUni.isValid()); 298 SkASSERT(fTextureSizeUni.isValid());
385 SkASSERT(fTextColorUni.isValid());
386 299
387 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
388 drawEffect.castEffect<GrDistanceFieldLCDText ureEffect>();
389 GrTexture* texture = drawEffect.effect()->get()->texture(0); 300 GrTexture* texture = drawEffect.effect()->get()->texture(0);
390 if (texture->width() != fTextureSize.width() || 301 if (texture->width() != fTextureSize.width() ||
391 texture->height() != fTextureSize.height()) { 302 texture->height() != fTextureSize.height()) {
303 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
304 drawEffect.castEffect<GrDistanceField LCDTextureEffect>();
392 fTextureSize = SkISize::Make(texture->width(), texture->height()); 305 fTextureSize = SkISize::Make(texture->width(), texture->height());
393 float delta = 1.0f/(3.0f*texture->width()); 306 float delta = 1.0f/(3.0f*texture->width());
394 if (dfTexEffect.useBGR()) { 307 if (dfTexEffect.useBGR()) {
395 delta = -delta; 308 delta = -delta;
396 } 309 }
397 uman.set3f(fTextureSizeUni, 310 uman.set3f(fTextureSizeUni,
398 SkIntToScalar(fTextureSize.width()), 311 SkIntToScalar(fTextureSize.width()),
399 SkIntToScalar(fTextureSize.height()), 312 SkIntToScalar(fTextureSize.height()),
400 delta); 313 delta);
401 } 314 }
402
403 GrColor textColor = dfTexEffect.getTextColor();
404 if (textColor != fTextColor) {
405 static const float ONE_OVER_255 = 1.f / 255.f;
406 uman.set3f(fTextColorUni,
407 GrColorUnpackR(textColor) * ONE_OVER_255,
408 GrColorUnpackG(textColor) * ONE_OVER_255,
409 GrColorUnpackB(textColor) * ONE_OVER_255);
410 fTextColor = textColor;
411 }
412 } 315 }
413 316
414 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&) { 317 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&) {
415 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 318 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
416 drawEffect.castEffect<GrDistanceField LCDTextureEffect>(); 319 drawEffect.castEffect<GrDistanceField LCDTextureEffect>();
417 320
418 return dfTexEffect.isUniformScale() ? 0x01 : 0x00;; 321 int uniformScale = dfTexEffect.isUniformScale() ? 0x01 : 0x00;
322 int useBGR = dfTexEffect.useBGR() ? 0x10 : 0x00;
323 return uniformScale | useBGR;
419 } 324 }
420 325
421 private: 326 private:
422 GrGLUniformManager::UniformHandle fTextureSizeUni; 327 GrGLUniformManager::UniformHandle fTextureSizeUni;
423 SkISize fTextureSize; 328 SkISize fTextureSize;
424 GrGLUniformManager::UniformHandle fTextColorUni;
425 SkColor fTextColor;
426 329
427 typedef GrGLVertexEffect INHERITED; 330 typedef GrGLVertexEffect INHERITED;
428 }; 331 };
429 332
430 /////////////////////////////////////////////////////////////////////////////// 333 ///////////////////////////////////////////////////////////////////////////////
431 334
432 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 335 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(GrTexture* text ure,
433 GrTexture* texture, const GrTe xtureParams& params, 336 const GrTexture Params& params,
434 GrTexture* gamma, const GrText ureParams& gParams, 337 bool uniformSca le,
435 SkColor textColor, 338 bool useBGR)
436 bool uniformScale, bool useBGR )
437 : fTextureAccess(texture, params) 339 : fTextureAccess(texture, params)
438 , fGammaTextureAccess(gamma, gParams)
439 , fTextColor(textColor)
440 , fUniformScale(uniformScale) 340 , fUniformScale(uniformScale)
441 , fUseBGR(useBGR) { 341 , fUseBGR(useBGR) {
442 this->addTextureAccess(&fTextureAccess); 342 this->addTextureAccess(&fTextureAccess);
443 this->addTextureAccess(&fGammaTextureAccess);
444 this->addVertexAttrib(kVec2f_GrSLType); 343 this->addVertexAttrib(kVec2f_GrSLType);
445 } 344 }
446 345
447 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrEffect& other) const { 346 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrEffect& other) const {
448 const GrDistanceFieldLCDTextureEffect& cte = 347 const GrDistanceFieldLCDTextureEffect& cte = CastEffect<GrDistanceFieldLCDTe xtureEffect>(other);
449 CastEffect<GrDistanceFieldLCDTexture Effect>(other); 348 return fTextureAccess == cte.fTextureAccess;
450 return (fTextureAccess == cte.fTextureAccess && fGammaTextureAccess == cte.f GammaTextureAccess);
451 } 349 }
452 350
453 void GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color, 351 void GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color,
454 uint32_t* valid Flags) const { 352 uint32_t* valid Flags) const {
455 if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color ) && 353 if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color ) &&
456 GrPixelConfigIsOpaque(this->texture(0)->config())) { 354 GrPixelConfigIsOpaque(this->texture(0)->config())) {
457 *validFlags = kA_GrColorComponentFlag; 355 *validFlags = kA_GrColorComponentFlag;
458 } else { 356 } else {
459 *validFlags = 0; 357 *validFlags = 0;
460 } 358 }
461 } 359 }
462 360
463 const GrBackendEffectFactory& GrDistanceFieldLCDTextureEffect::getFactory() cons t { 361 const GrBackendEffectFactory& GrDistanceFieldLCDTextureEffect::getFactory() cons t {
464 return GrTBackendEffectFactory<GrDistanceFieldLCDTextureEffect>::getInstance (); 362 return GrTBackendEffectFactory<GrDistanceFieldLCDTextureEffect>::getInstance ();
465 } 363 }
466 364
467 /////////////////////////////////////////////////////////////////////////////// 365 ///////////////////////////////////////////////////////////////////////////////
468 366
469 GR_DEFINE_EFFECT_TEST(GrDistanceFieldLCDTextureEffect); 367 GR_DEFINE_EFFECT_TEST(GrDistanceFieldLCDTextureEffect);
470 368
471 GrEffectRef* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random, 369 GrEffectRef* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
472 GrContext*, 370 GrContext*,
473 const GrDrawTargetCaps& , 371 const GrDrawTargetCaps& ,
474 GrTexture* textures[]) { 372 GrTexture* textures[]) {
475 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 373 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
476 GrEffectUnitTest::kAlphaTextureIdx; 374 GrEffectUnitTest::kAlphaTextureIdx;
477 int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
478 GrEffectUnitTest::kAlphaTextureIdx;
479 static const SkShader::TileMode kTileModes[] = { 375 static const SkShader::TileMode kTileModes[] = {
480 SkShader::kClamp_TileMode, 376 SkShader::kClamp_TileMode,
481 SkShader::kRepeat_TileMode, 377 SkShader::kRepeat_TileMode,
482 SkShader::kMirror_TileMode, 378 SkShader::kMirror_TileMode,
483 }; 379 };
484 SkShader::TileMode tileModes[] = { 380 SkShader::TileMode tileModes[] = {
485 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 381 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
486 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 382 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
487 }; 383 };
488 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode : 384 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode :
489 GrTextureParams::kNone_FilterMode); 385 GrTextureParams::kNone_FilterMode);
490 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBi lerp_FilterMode : 386
491 GrTextureParams::kNone_FilterMode);
492 GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
493 random->nextULessThan(256),
494 random->nextULessThan(256),
495 random->nextULessThan(256));
496 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 387 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
497 textures[texIdx2], params2,
498 textColor,
499 random->nextBool(), random->n extBool()); 388 random->nextBool(), random->n extBool());
500 } 389 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDistanceFieldTextureEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698