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

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

Powered by Google App Engine
This is Rietveld 408576698