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

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

Issue 1042373002: Emulate gamma fix by making glyphs thicker or thinner (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase to ToT Created 5 years, 8 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 "GrFontAtlasSizes.h" 9 #include "GrFontAtlasSizes.h"
10 #include "GrInvariantOutput.h" 10 #include "GrInvariantOutput.h"
11 #include "GrTexture.h" 11 #include "GrTexture.h"
12
12 #include "SkDistanceFieldGen.h" 13 #include "SkDistanceFieldGen.h"
14
15 #include "../utils/SkCamera.h"
bungeman-skia 2015/04/01 15:38:56 Seems like you can remove this?
jvanverth1 2015/04/01 15:42:13 Done.
16
13 #include "gl/GrGLProcessor.h" 17 #include "gl/GrGLProcessor.h"
14 #include "gl/GrGLSL.h" 18 #include "gl/GrGLSL.h"
15 #include "gl/GrGLTexture.h" 19 #include "gl/GrGLTexture.h"
16 #include "gl/GrGLGeometryProcessor.h" 20 #include "gl/GrGLGeometryProcessor.h"
17 #include "gl/builders/GrGLProgramBuilder.h" 21 #include "gl/builders/GrGLProgramBuilder.h"
18 22
19 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/ 2 23 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/ 2
20 #define SK_DistanceFieldAAFactor "0.65" 24 #define SK_DistanceFieldAAFactor "0.65"
21 25
22 struct DistanceFieldBatchTracker { 26 struct DistanceFieldBatchTracker {
23 GrGPInput fInputColorType; 27 GrGPInput fInputColorType;
24 GrColor fColor; 28 GrColor fColor;
25 bool fUsesLocalCoords; 29 bool fUsesLocalCoords;
26 }; 30 };
27 31
28 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { 32 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor {
29 public: 33 public:
30 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&, 34 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&,
31 const GrBatchTracker&) 35 const GrBatchTracker&)
32 : fColor(GrColor_ILLEGAL) 36 : fColor(GrColor_ILLEGAL)
33 #ifdef SK_GAMMA_APPLY_TO_A8 37 #ifdef SK_GAMMA_APPLY_TO_A8
34 , fLuminance(-1.0f) 38 , fWidthAdjust(-1.0f)
35 #endif 39 #endif
36 {} 40 {}
37 41
38 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 42 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
39 const GrDistanceFieldTextureEffect& dfTexEffect = 43 const GrDistanceFieldTextureEffect& dfTexEffect =
40 args.fGP.cast<GrDistanceFieldTextureEffect>(); 44 args.fGP.cast<GrDistanceFieldTextureEffect>();
41 const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatc hTracker>(); 45 const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatc hTracker>();
42 GrGLGPBuilder* pb = args.fPB; 46 GrGLGPBuilder* pb = args.fPB;
43 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 47 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
44 SkAssertResult(fsBuilder->enableFeature( 48 SkAssertResult(fsBuilder->enableFeature(
45 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 49 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
46 50
47 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 51 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
48 52
49 // emit attributes 53 // emit attributes
50 vsBuilder->emitAttributes(dfTexEffect); 54 vsBuilder->emitAttributes(dfTexEffect);
51 55
52 GrGLVertToFrag st(kVec2f_GrSLType); 56 GrGLVertToFrag st(kVec2f_GrSLType);
53 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 57 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
54 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor ds()->fName); 58 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor ds()->fName);
55 59
56 GrGLVertToFrag uv(kVec2f_GrSLType); 60 GrGLVertToFrag uv(kVec2f_GrSLType);
57 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 61 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
58 // this is only used with text, so our texture bounds always match the g lyph atlas 62 // this is only used with text, so our texture bounds always match the g lyph atlas
59 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " 63 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
60 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), 64 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
61 dfTexEffect.inTextureCoords()->fName); 65 dfTexEffect.inTextureCoords()->fName);
66 #ifdef SK_GAMMA_APPLY_TO_A8
67 // adjust based on gamma
68 const char* widthAdjustUniName = NULL;
69 // width, height, 1/(3*width)
70 fWidthAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis ibility,
71 kFloat_GrSLType, kDefault_GrSLPrecision,
72 "WidthAdjust", &widthAdjustUniName);
73 #endif
62 74
63 // Setup pass through color 75 // Setup pass through color
64 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor , 76 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor ,
65 dfTexEffect.inColor(), &fColorUniform); 77 dfTexEffect.inColor(), &fColorUniform);
66 78
67 // Setup position 79 // Setup position
68 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf fect.viewMatrix()); 80 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf fect.viewMatrix());
69 81
70 // emit transforms 82 // emit transforms
71 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit ion()->fName, 83 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit ion()->fName,
72 dfTexEffect.localMatrix(), args.fTransformsIn, args .fTransformsOut); 84 dfTexEffect.localMatrix(), args.fTransformsIn, args .fTransformsOut);
73 85
74 // Use highp to work around aliasing issues 86 // Use highp to work around aliasing issues
75 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision , 87 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision ,
76 pb->ctxInfo().stand ard())); 88 pb->ctxInfo().stand ard()));
77 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 89 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
78 90
79 fsBuilder->codeAppend("\tfloat texColor = "); 91 fsBuilder->codeAppend("\tfloat texColor = ");
80 fsBuilder->appendTextureLookup(args.fSamplers[0], 92 fsBuilder->appendTextureLookup(args.fSamplers[0],
81 "uv", 93 "uv",
82 kVec2f_GrSLType); 94 kVec2f_GrSLType);
83 fsBuilder->codeAppend(".r;\n"); 95 fsBuilder->codeAppend(".r;\n");
84 fsBuilder->codeAppend("\tfloat distance = " 96 fsBuilder->codeAppend("\tfloat distance = "
85 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");"); 97 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");");
98 #ifdef SK_GAMMA_APPLY_TO_A8
99 // adjust width based on gamma
100 fsBuilder->codeAppendf("distance -= %s;", widthAdjustUniName);
101 #endif
86 102
87 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision , 103 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision ,
88 pb->ctxInfo().stand ard())); 104 pb->ctxInfo().stand ard()));
89 fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn()); 105 fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn());
90 fsBuilder->codeAppend("float afwidth;"); 106 fsBuilder->codeAppend("float afwidth;");
91 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 107 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
92 // For uniform scale, we adjust for the effect of the transformation on the distance 108 // For uniform scale, we adjust for the effect of the transformation on the distance
93 // by using the length of the gradient of the texture coordinates. W e use st coordinates 109 // by using the length of the gradient of the texture coordinates. W e use st coordinates
94 // to ensure we're mapping 1:1 from texel space to pixel space. 110 // to ensure we're mapping 1:1 from texel space to pixel space.
95 111
(...skipping 16 matching lines...) Expand all
112 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 128 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
113 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 129 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
114 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,"); 130 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,");
115 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);"); 131 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);");
116 132
117 // this gives us a smooth step across approximately one fragment 133 // this gives us a smooth step across approximately one fragment
118 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 134 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);");
119 } 135 }
120 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);"); 136 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);");
121 137
122 #ifdef SK_GAMMA_APPLY_TO_A8
123 // adjust based on gamma
124 const char* luminanceUniName = NULL;
125 // width, height, 1/(3*width)
126 fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib ility,
127 kFloat_GrSLType, kDefault_GrSLPreci sion,
128 "Luminance", &luminanceUniName);
129
130 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
131 fsBuilder->codeAppend("\tvec4 gammaColor = ");
132 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
133 fsBuilder->codeAppend(";\n");
134 fsBuilder->codeAppend("\tval = gammaColor.r;\n");
135 #endif
136
137 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 138 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
138 } 139 }
139 140
140 virtual void setData(const GrGLProgramDataManager& pdman, 141 virtual void setData(const GrGLProgramDataManager& pdman,
141 const GrPrimitiveProcessor& proc, 142 const GrPrimitiveProcessor& proc,
142 const GrBatchTracker& bt) override { 143 const GrBatchTracker& bt) override {
143 #ifdef SK_GAMMA_APPLY_TO_A8 144 #ifdef SK_GAMMA_APPLY_TO_A8
144 const GrDistanceFieldTextureEffect& dfTexEffect = 145 const GrDistanceFieldTextureEffect& dfTexEffect =
145 proc.cast<GrDistanceFieldTextureEffect>(); 146 proc.cast<GrDistanceFieldTextureEffect>();
146 float luminance = dfTexEffect.getLuminance(); 147 float widthAdjust = dfTexEffect.getWidthAdjust();
147 if (luminance != fLuminance) { 148 if (widthAdjust != fWidthAdjust) {
148 pdman.set1f(fLuminanceUni, luminance); 149 pdman.set1f(fWidthAdjustUni, widthAdjust);
149 fLuminance = luminance; 150 fWidthAdjust = widthAdjust;
150 } 151 }
151 #endif 152 #endif
152 153
153 this->setUniformViewMatrix(pdman, proc.viewMatrix()); 154 this->setUniformViewMatrix(pdman, proc.viewMatrix());
154 155
155 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack er>(); 156 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack er>();
156 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo r) { 157 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo r) {
157 GrGLfloat c[4]; 158 GrGLfloat c[4];
158 GrColorToRGBAFloat(local.fColor, c); 159 GrColorToRGBAFloat(local.fColor, c);
159 pdman.set4fv(fColorUniform, 1, c); 160 pdman.set4fv(fColorUniform, 1, c);
(...skipping 11 matching lines...) Expand all
171 key |= local.fInputColorType << 16; 172 key |= local.fInputColorType << 16;
172 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 173 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
173 key |= ComputePosKey(gp.viewMatrix()) << 25; 174 key |= ComputePosKey(gp.viewMatrix()) << 25;
174 b->add32(key); 175 b->add32(key);
175 } 176 }
176 177
177 private: 178 private:
178 GrColor fColor; 179 GrColor fColor;
179 UniformHandle fColorUniform; 180 UniformHandle fColorUniform;
180 #ifdef SK_GAMMA_APPLY_TO_A8 181 #ifdef SK_GAMMA_APPLY_TO_A8
181 UniformHandle fLuminanceUni; 182 float fWidthAdjust;
182 float fLuminance; 183 UniformHandle fWidthAdjustUni;
183 #endif 184 #endif
184 185
185 typedef GrGLGeometryProcessor INHERITED; 186 typedef GrGLGeometryProcessor INHERITED;
186 }; 187 };
187 188
188 /////////////////////////////////////////////////////////////////////////////// 189 ///////////////////////////////////////////////////////////////////////////////
189 190
190 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, 191 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
191 const SkMatrix& viewM atrix, 192 const SkMatrix& viewM atrix,
192 GrTexture* texture, 193 GrTexture* texture,
193 const GrTextureParams & params, 194 const GrTextureParams & params,
194 #ifdef SK_GAMMA_APPLY_TO_A8 195 #ifdef SK_GAMMA_APPLY_TO_A8
195 GrTexture* gamma, 196 float widthAdjust,
196 const GrTextureParams & gammaParams,
197 float luminance,
198 #endif 197 #endif
199 uint32_t flags, bool opaqueVertexColors) 198 uint32_t flags, bool opaqueVertexColors)
200 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) 199 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
201 , fTextureAccess(texture, params) 200 , fTextureAccess(texture, params)
202 #ifdef SK_GAMMA_APPLY_TO_A8 201 #ifdef SK_GAMMA_APPLY_TO_A8
203 , fGammaTextureAccess(gamma, gammaParams) 202 , fWidthAdjust(widthAdjust)
204 , fLuminance(luminance)
205 #endif 203 #endif
206 , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 204 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
207 , fInColor(NULL) { 205 , fInColor(NULL) {
208 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 206 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
209 this->initClassID<GrDistanceFieldTextureEffect>(); 207 this->initClassID<GrDistanceFieldTextureEffect>();
210 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); 208 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType));
211 if (flags & kColorAttr_DistanceFieldEffectFlag) { 209 if (flags & kColorAttr_DistanceFieldEffectFlag) {
212 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexA ttribType)); 210 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexA ttribType));
213 this->setHasVertexColor(); 211 this->setHasVertexColor();
214 } 212 }
215 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 213 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
216 kVec2s_GrVertexAttribT ype)); 214 kVec2s_GrVertexAttribT ype));
217 this->addTextureAccess(&fTextureAccess); 215 this->addTextureAccess(&fTextureAccess);
218 #ifdef SK_GAMMA_APPLY_TO_A8
219 this->addTextureAccess(&fGammaTextureAccess);
220 #endif
221 } 216 }
222 217
223 bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) c onst { 218 bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) c onst {
224 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureE ffect>(); 219 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureE ffect>();
225 return 220 return
226 #ifdef SK_GAMMA_APPLY_TO_A8 221 #ifdef SK_GAMMA_APPLY_TO_A8
227 fLuminance == cte.fLuminance && 222 fWidthAdjust == cte.fWidthAdjust &&
228 #endif 223 #endif
229 fFlags == cte.fFlags; 224 fFlags == cte.fFlags;
230 } 225 }
231 226
232 void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantO utput* out) const { 227 void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantO utput* out) const {
233 out->setUnknownSingleComponent(); 228 out->setUnknownSingleComponent();
234 } 229 }
235 230
236 void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt, 231 void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
237 const GrGLCaps& caps, 232 const GrGLCaps& caps,
(...skipping 28 matching lines...) Expand all
266 /////////////////////////////////////////////////////////////////////////////// 261 ///////////////////////////////////////////////////////////////////////////////
267 262
268 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect); 263 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect);
269 264
270 GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 265 GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
271 GrContext*, 266 GrContext*,
272 const GrDrawTarget Caps&, 267 const GrDrawTarget Caps&,
273 GrTexture* texture s[]) { 268 GrTexture* texture s[]) {
274 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 269 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
275 GrProcessorUnitTest::kAlphaTextureIdx; 270 GrProcessorUnitTest::kAlphaTextureIdx;
276 #ifdef SK_GAMMA_APPLY_TO_A8
277 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
278 GrProcessorUnitTest::kAlphaTextureIdx;
279 #endif
280 static const SkShader::TileMode kTileModes[] = { 271 static const SkShader::TileMode kTileModes[] = {
281 SkShader::kClamp_TileMode, 272 SkShader::kClamp_TileMode,
282 SkShader::kRepeat_TileMode, 273 SkShader::kRepeat_TileMode,
283 SkShader::kMirror_TileMode, 274 SkShader::kMirror_TileMode,
284 }; 275 };
285 SkShader::TileMode tileModes[] = { 276 SkShader::TileMode tileModes[] = {
286 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 277 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
287 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 278 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
288 }; 279 };
289 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode : 280 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode :
290 GrTextureParams::kNon e_FilterMode); 281 GrTextureParams::kNon e_FilterMode);
291 #ifdef SK_GAMMA_APPLY_TO_A8
292 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBi lerp_FilterMode :
293 GrTextureParams::kNo ne_FilterMode);
294 #endif
295 282
296 return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), 283 return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
297 GrProcessorUnitTest::TestMatrix( random), 284 GrProcessorUnitTest::TestMatrix( random),
298 textures[texIdx], params, 285 textures[texIdx], params,
299 #ifdef SK_GAMMA_APPLY_TO_A8 286 #ifdef SK_GAMMA_APPLY_TO_A8
300 textures[texIdx2], params2,
301 random->nextF(), 287 random->nextF(),
302 #endif 288 #endif
303 random->nextBool() ? 289 random->nextBool() ?
304 kSimilarity_DistanceFieldEff ectFlag : 0, 290 kSimilarity_DistanceFieldEff ectFlag : 0,
305 random->nextBool()); 291 random->nextBool());
306 } 292 }
307 293
308 /////////////////////////////////////////////////////////////////////////////// 294 ///////////////////////////////////////////////////////////////////////////////
309 295
310 struct DistanceFieldNoGammaBatchTracker { 296 struct DistanceFieldNoGammaBatchTracker {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 struct DistanceFieldLCDBatchTracker { 542 struct DistanceFieldLCDBatchTracker {
557 GrGPInput fInputColorType; 543 GrGPInput fInputColorType;
558 GrColor fColor; 544 GrColor fColor;
559 bool fUsesLocalCoords; 545 bool fUsesLocalCoords;
560 }; 546 };
561 547
562 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 548 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
563 public: 549 public:
564 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&, 550 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&,
565 const GrBatchTracker&) 551 const GrBatchTracker&)
566 : fColor(GrColor_ILLEGAL) 552 : fColor(GrColor_ILLEGAL) {
567 , fTextColor(GrColor_ILLEGAL) {} 553 fWidthAdjust = GrDistanceFieldLCDTextureEffect::WidthAdjust::Make(1.0f, 1.0f, 1.0f);
554 }
568 555
569 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 556 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
570 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 557 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
571 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); 558 args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
572 const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldL CDBatchTracker>(); 559 const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldL CDBatchTracker>();
573 GrGLGPBuilder* pb = args.fPB; 560 GrGLGPBuilder* pb = args.fPB;
574 561
575 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 562 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
576 563
577 // emit attributes 564 // emit attributes
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 // blue is distance to right offset 630 // blue is distance to right offset
644 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 631 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
645 fsBuilder->codeAppend("\ttexColor = "); 632 fsBuilder->codeAppend("\ttexColor = ");
646 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType); 633 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType);
647 fsBuilder->codeAppend(";\n"); 634 fsBuilder->codeAppend(";\n");
648 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 635 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
649 636
650 fsBuilder->codeAppend("\tdistance = " 637 fsBuilder->codeAppend("\tdistance = "
651 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF ieldThreshold"));"); 638 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF ieldThreshold"));");
652 639
640 // adjust width based on gamma
641 const char* widthAdjustUniName = NULL;
642 fWidthAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis ibility,
643 kVec3f_GrSLType, kDefault_GrSLPrecision,
644 "WidthAdjust", &widthAdjustUniName);
645 fsBuilder->codeAppendf("distance -= %s;", widthAdjustUniName);
646
653 // To be strictly correct, we should compute the anti-aliasing factor se parately 647 // To be strictly correct, we should compute the anti-aliasing factor se parately
654 // for each color component. However, this is only important when using perspective 648 // for each color component. However, this is only important when using perspective
655 // transformations, and even then using a single factor seems like a rea sonable 649 // transformations, and even then using a single factor seems like a rea sonable
656 // trade-off between quality and speed. 650 // trade-off between quality and speed.
657 fsBuilder->codeAppend("float afwidth;"); 651 fsBuilder->codeAppend("float afwidth;");
658 if (isUniformScale) { 652 if (isUniformScale) {
659 // For uniform scale, we adjust for the effect of the transformation on the distance 653 // For uniform scale, we adjust for the effect of the transformation on the distance
660 // by using the length of the gradient of the texture coordinates. W e use st coordinates 654 // by using the length of the gradient of the texture coordinates. W e use st coordinates
661 // to ensure we're mapping 1:1 from texel space to pixel space. 655 // to ensure we're mapping 1:1 from texel space to pixel space.
662 656
(...skipping 14 matching lines...) Expand all
677 fsBuilder->codeAppend("}"); 671 fsBuilder->codeAppend("}");
678 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,"); 672 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,");
679 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);"); 673 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);");
680 674
681 // this gives us a smooth step across approximately one fragment 675 // this gives us a smooth step across approximately one fragment
682 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 676 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);");
683 } 677 }
684 678
685 fsBuilder->codeAppend("vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(a fwidth), distance), 1.0);"); 679 fsBuilder->codeAppend("vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(a fwidth), distance), 1.0);");
686 680
687 // adjust based on gamma
688 const char* textColorUniName = NULL;
689 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib ility,
690 kVec3f_GrSLType, kDefault_GrSLPreci sion,
691 "TextColor", &textColorUniName);
692
693 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
694 fsBuilder->codeAppend("float gammaColor = ");
695 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
696 fsBuilder->codeAppend(".r;\n");
697 fsBuilder->codeAppend("\tval.x = gammaColor;\n");
698
699 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
700 fsBuilder->codeAppend("\tgammaColor = ");
701 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
702 fsBuilder->codeAppend(".r;\n");
703 fsBuilder->codeAppend("\tval.y = gammaColor;\n");
704
705 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
706 fsBuilder->codeAppend("\tgammaColor = ");
707 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType) ;
708 fsBuilder->codeAppend(".r;\n");
709 fsBuilder->codeAppend("\tval.z = gammaColor;\n");
710
711 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 681 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
712 } 682 }
713 683
714 virtual void setData(const GrGLProgramDataManager& pdman, 684 virtual void setData(const GrGLProgramDataManager& pdman,
715 const GrPrimitiveProcessor& processor, 685 const GrPrimitiveProcessor& processor,
716 const GrBatchTracker& bt) override { 686 const GrBatchTracker& bt) override {
717 SkASSERT(fTextColorUni.isValid()); 687 SkASSERT(fWidthAdjustUni.isValid());
718 688
719 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 689 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
720 processor.cast<GrDistanceFieldLCDTextureEffect>(); 690 processor.cast<GrDistanceFieldLCDTextureEffect>();
721 GrColor textColor = dfTexEffect.getTextColor(); 691 GrDistanceFieldLCDTextureEffect::WidthAdjust wa = dfTexEffect.getWidthAd just();
722 if (textColor != fTextColor) { 692 if (wa != fWidthAdjust) {
723 static const float ONE_OVER_255 = 1.f / 255.f; 693 static const float ONE_OVER_255 = 1.f / 255.f;
724 pdman.set3f(fTextColorUni, 694 pdman.set3f(fWidthAdjustUni,
725 GrColorUnpackR(textColor) * ONE_OVER_255, 695 wa.fR,
726 GrColorUnpackG(textColor) * ONE_OVER_255, 696 wa.fG,
727 GrColorUnpackB(textColor) * ONE_OVER_255); 697 wa.fB);
728 fTextColor = textColor; 698 fWidthAdjust = wa;
729 } 699 }
730 700
731 this->setUniformViewMatrix(pdman, processor.viewMatrix()); 701 this->setUniformViewMatrix(pdman, processor.viewMatrix());
732 702
733 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc hTracker>(); 703 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc hTracker>();
734 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo r) { 704 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo r) {
735 GrGLfloat c[4]; 705 GrGLfloat c[4];
736 GrColorToRGBAFloat(local.fColor, c); 706 GrColorToRGBAFloat(local.fColor, c);
737 pdman.set4fv(fColorUniform, 1, c); 707 pdman.set4fv(fColorUniform, 1, c);
738 fColor = local.fColor; 708 fColor = local.fColor;
739 } 709 }
740 } 710 }
741 711
742 static inline void GenKey(const GrGeometryProcessor& gp, 712 static inline void GenKey(const GrGeometryProcessor& gp,
743 const GrBatchTracker& bt, 713 const GrBatchTracker& bt,
744 const GrGLCaps&, 714 const GrGLCaps&,
745 GrProcessorKeyBuilder* b) { 715 GrProcessorKeyBuilder* b) {
746 const GrDistanceFieldLCDTextureEffect& dfTexEffect = 716 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
747 gp.cast<GrDistanceFieldLCDTextureEffect>(); 717 gp.cast<GrDistanceFieldLCDTextureEffect>();
748 718
749 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc hTracker>(); 719 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc hTracker>();
750 uint32_t key = dfTexEffect.getFlags(); 720 uint32_t key = dfTexEffect.getFlags();
751 key |= local.fInputColorType << 16; 721 key |= local.fInputColorType << 16;
752 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 722 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
753 key |= ComputePosKey(gp.viewMatrix()) << 25; 723 key |= ComputePosKey(gp.viewMatrix()) << 25;
754 b->add32(key); 724 b->add32(key);
755 } 725 }
756 726
757 private: 727 private:
758 GrColor fColor; 728 GrColor fColor;
759 UniformHandle fColorUniform; 729 UniformHandle fColorUniform;
760 UniformHandle fTextColorUni; 730 GrDistanceFieldLCDTextureEffect::WidthAdjust fWidthAdjust;
761 SkColor fTextColor; 731 UniformHandle fWidthAdjustUni;
762 732
763 typedef GrGLGeometryProcessor INHERITED; 733 typedef GrGLGeometryProcessor INHERITED;
764 }; 734 };
765 735
766 /////////////////////////////////////////////////////////////////////////////// 736 ///////////////////////////////////////////////////////////////////////////////
767 737
768 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 738 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
769 GrColor color, const SkMatrix& viewMatrix, 739 GrColor color, const SkMatrix& viewMatrix,
770 GrTexture* texture, const GrTe xtureParams& params, 740 GrTexture* texture, const GrTe xtureParams& params,
771 GrTexture* gamma, const GrText ureParams& gParams, 741 WidthAdjust widthAdjust,
772 SkColor textColor,
773 uint32_t flags) 742 uint32_t flags)
774 : INHERITED(color, viewMatrix, SkMatrix::I()) 743 : INHERITED(color, viewMatrix, SkMatrix::I())
775 , fTextureAccess(texture, params) 744 , fTextureAccess(texture, params)
776 , fGammaTextureAccess(gamma, gParams) 745 , fWidthAdjust(widthAdjust)
777 , fTextColor(textColor)
778 , fFlags(flags & kLCD_DistanceFieldEffectMask){ 746 , fFlags(flags & kLCD_DistanceFieldEffectMask){
779 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_Distan ceFieldEffectFlag)); 747 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_Distan ceFieldEffectFlag));
780 this->initClassID<GrDistanceFieldLCDTextureEffect>(); 748 this->initClassID<GrDistanceFieldLCDTextureEffect>();
781 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); 749 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType));
782 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 750 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
783 kVec2s_GrVertexAttribT ype)); 751 kVec2s_GrVertexAttribT ype));
784 this->addTextureAccess(&fTextureAccess); 752 this->addTextureAccess(&fTextureAccess);
785 this->addTextureAccess(&fGammaTextureAccess);
786 } 753 }
787 754
788 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other ) const { 755 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other ) const {
789 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTe xtureEffect>(); 756 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTe xtureEffect>();
790 return (fTextColor == cte.fTextColor && 757 return (fWidthAdjust == cte.fWidthAdjust &&
791 fFlags == cte.fFlags); 758 fFlags == cte.fFlags);
792 } 759 }
793 760
794 void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvaria ntOutput* out) const { 761 void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvaria ntOutput* out) const {
795 out->setUnknownFourComponents(); 762 out->setUnknownFourComponents();
796 out->setUsingLCDCoverage(); 763 out->setUsingLCDCoverage();
797 } 764 }
798 765
799 void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt , 766 void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt ,
800 const GrGLCaps& caps, 767 const GrGLCaps& caps,
(...skipping 28 matching lines...) Expand all
829 /////////////////////////////////////////////////////////////////////////////// 796 ///////////////////////////////////////////////////////////////////////////////
830 797
831 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect); 798 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect);
832 799
833 GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando m, 800 GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando m,
834 GrContext*, 801 GrContext*,
835 const GrDrawTar getCaps&, 802 const GrDrawTar getCaps&,
836 GrTexture* text ures[]) { 803 GrTexture* text ures[]) {
837 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 804 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
838 GrProcessorUnitTest::kAlphaTextureIdx; 805 GrProcessorUnitTest::kAlphaTextureIdx;
839 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
840 GrProcessorUnitTest::kAlphaTextureIdx;
841 static const SkShader::TileMode kTileModes[] = { 806 static const SkShader::TileMode kTileModes[] = {
842 SkShader::kClamp_TileMode, 807 SkShader::kClamp_TileMode,
843 SkShader::kRepeat_TileMode, 808 SkShader::kRepeat_TileMode,
844 SkShader::kMirror_TileMode, 809 SkShader::kMirror_TileMode,
845 }; 810 };
846 SkShader::TileMode tileModes[] = { 811 SkShader::TileMode tileModes[] = {
847 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 812 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
848 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 813 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
849 }; 814 };
850 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode : 815 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode :
851 GrTextureParams::kNone_FilterMode); 816 GrTextureParams::kNone_FilterMode);
852 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBi lerp_FilterMode : 817 WidthAdjust wa = { 0.0f, 0.1f, -0.1f };
853 GrTextureParams::kNone_FilterMode);
854 GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
855 random->nextULessThan(256),
856 random->nextULessThan(256),
857 random->nextULessThan(256));
858 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 818 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
859 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 819 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
860 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 820 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
861 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), 821 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
862 GrProcessorUnitTest::TestMatr ix(random), 822 GrProcessorUnitTest::TestMatr ix(random),
863 textures[texIdx], params, 823 textures[texIdx], params,
864 textures[texIdx2], params2, 824 wa,
865 textColor,
866 flags); 825 flags);
867 } 826 }
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