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

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

Issue 1457543003: Add ShaderBuilders to EmitArgs and remove gettings from ProgBuilder. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 1 month 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/GrDisableColorXP.cpp ('k') | src/gpu/effects/GrDitherEffect.cpp » ('j') | 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 "GrDistanceFieldGeoProc.h" 8 #include "GrDistanceFieldGeoProc.h"
9 #include "GrInvariantOutput.h" 9 #include "GrInvariantOutput.h"
10 #include "GrTexture.h" 10 #include "GrTexture.h"
(...skipping 17 matching lines...) Expand all
28 , fColor(GrColor_ILLEGAL) 28 , fColor(GrColor_ILLEGAL)
29 #ifdef SK_GAMMA_APPLY_TO_A8 29 #ifdef SK_GAMMA_APPLY_TO_A8
30 , fDistanceAdjust(-1.0f) 30 , fDistanceAdjust(-1.0f)
31 #endif 31 #endif
32 {} 32 {}
33 33
34 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 34 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
35 const GrDistanceFieldA8TextGeoProc& dfTexEffect = 35 const GrDistanceFieldA8TextGeoProc& dfTexEffect =
36 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); 36 args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
37 GrGLSLGPBuilder* pb = args.fPB; 37 GrGLSLGPBuilder* pb = args.fPB;
38 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); 38 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
39 SkAssertResult(fsBuilder->enableFeature( 39 SkAssertResult(fragBuilder->enableFeature(
40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
41 41
42 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); 42 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
43 43
44 // emit attributes 44 // emit attributes
45 vsBuilder->emitAttributes(dfTexEffect); 45 vertBuilder->emitAttributes(dfTexEffect);
46 46
47 #ifdef SK_GAMMA_APPLY_TO_A8 47 #ifdef SK_GAMMA_APPLY_TO_A8
48 // adjust based on gamma 48 // adjust based on gamma
49 const char* distanceAdjustUniName = nullptr; 49 const char* distanceAdjustUniName = nullptr;
50 // width, height, 1/(3*width) 50 // width, height, 1/(3*width)
51 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi bility, 51 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi bility,
52 kFloat_GrSLType, kDefault_GrSLPrecision, 52 kFloat_GrSLType, kDefault_GrSLPrecision,
53 "DistanceAdjust", &distanceAdjustUniName); 53 "DistanceAdjust", &distanceAdjustUniName);
54 #endif 54 #endif
55 55
56 // Setup pass through color 56 // Setup pass through color
57 if (!dfTexEffect.colorIgnored()) { 57 if (!dfTexEffect.colorIgnored()) {
58 if (dfTexEffect.hasVertexColor()) { 58 if (dfTexEffect.hasVertexColor()) {
59 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC olor); 59 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC olor);
60 } else { 60 } else {
61 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); 61 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo lorUniform);
62 } 62 }
63 } 63 }
64 64
65 // Setup position 65 // Setup position
66 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf fect.viewMatrix(), 66 this->setupPosition(pb,
67 vertBuilder,
68 gpArgs,
69 dfTexEffect.inPosition()->fName,
70 dfTexEffect.viewMatrix(),
67 &fViewMatrixUniform); 71 &fViewMatrixUniform);
68 72
69 // emit transforms 73 // emit transforms
70 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()- >fName, 74 this->emitTransforms(pb,
71 args.fTransformsIn, args.fTransformsOut); 75 vertBuilder,
76 gpArgs->fPositionVar,
77 dfTexEffect.inPosition()->fName,
78 args.fTransformsIn,
79 args.fTransformsOut);
72 80
73 // add varyings 81 // add varyings
74 GrGLSLVertToFrag recipScale(kFloat_GrSLType); 82 GrGLSLVertToFrag recipScale(kFloat_GrSLType);
75 GrGLSLVertToFrag st(kVec2f_GrSLType); 83 GrGLSLVertToFrag st(kVec2f_GrSLType);
76 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); 84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag);
77 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 85 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
78 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor ds()->fName); 86 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo ords()->fName);
79 87
80 // compute numbers to be hardcoded to convert texture coordinates from i nt to float 88 // compute numbers to be hardcoded to convert texture coordinates from i nt to float
81 SkASSERT(dfTexEffect.numTextures() == 1); 89 SkASSERT(dfTexEffect.numTextures() == 1);
82 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); 90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
83 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; 91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ;
84 SkScalar recipWidth = 1.0f / atlas->width(); 92 SkScalar recipWidth = 1.0f / atlas->width();
85 SkScalar recipHeight = 1.0f / atlas->height(); 93 SkScalar recipHeight = 1.0f / atlas->height();
86 94
87 GrGLSLVertToFrag uv(kVec2f_GrSLType); 95 GrGLSLVertToFrag uv(kVec2f_GrSLType);
88 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 96 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
89 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), 97 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
90 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, 98 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
91 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, 99 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
92 dfTexEffect.inTextureCoords()->fName); 100 dfTexEffect.inTextureCoords()->fName);
93 101
94 // Use highp to work around aliasing issues 102 // Use highp to work around aliasing issues
95 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), 103 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
96 kHigh_GrSLPrecisi on)); 104 kHigh_GrSLPreci sion));
97 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 105 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
98 106
99 fsBuilder->codeAppend("\tfloat texColor = "); 107 fragBuilder->codeAppend("\tfloat texColor = ");
100 fsBuilder->appendTextureLookup(args.fSamplers[0], 108 fragBuilder->appendTextureLookup(args.fSamplers[0],
101 "uv", 109 "uv",
102 kVec2f_GrSLType); 110 kVec2f_GrSLType);
103 fsBuilder->codeAppend(".r;\n"); 111 fragBuilder->codeAppend(".r;\n");
104 fsBuilder->codeAppend("\tfloat distance = " 112 fragBuilder->codeAppend("\tfloat distance = "
105 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");"); 113 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");");
106 #ifdef SK_GAMMA_APPLY_TO_A8 114 #ifdef SK_GAMMA_APPLY_TO_A8
107 // adjust width based on gamma 115 // adjust width based on gamma
108 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 116 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
109 #endif 117 #endif
110 118
111 fsBuilder->codeAppend("float afwidth;"); 119 fragBuilder->codeAppend("float afwidth;");
112 if (isSimilarity) { 120 if (isSimilarity) {
113 // For uniform scale, we adjust for the effect of the transformation on the distance 121 // For uniform scale, we adjust for the effect of the transformation on the distance
114 // by using the length of the gradient of the texture coordinates. W e use st coordinates 122 // by using the length of the gradient of the texture coordinates. W e use st coordinates
115 // to ensure we're mapping 1:1 from texel space to pixel space. 123 // to ensure we're mapping 1:1 from texel space to pixel space.
116 124
117 // this gives us a smooth step across approximately one fragment 125 // this gives us a smooth step across approximately one fragment
118 // we use y to work around a Mali400 bug in the x direction 126 // we use y to work around a Mali400 bug in the x direction
119 fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*d Fdy(%s.y));", 127 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor " *dFdy(%s.y));",
120 st.fsIn()); 128 st.fsIn());
121 } else { 129 } else {
122 // For general transforms, to determine the amount of correction we multiply a unit 130 // For general transforms, to determine the amount of correction we multiply a unit
123 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 131 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
124 // (which is the inverse transform for this fragment) and take the l ength of the result. 132 // (which is the inverse transform for this fragment) and take the l ength of the result.
125 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di stance));"); 133 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));");
126 // the length of the gradient may be 0, so we need to check for this 134 // the length of the gradient may be 0, so we need to check for this
127 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 135 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
128 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 136 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
129 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 137 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
130 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 138 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
131 fsBuilder->codeAppend("} else {"); 139 fragBuilder->codeAppend("} else {");
132 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);") ; 140 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2); ");
133 fsBuilder->codeAppend("}"); 141 fragBuilder->codeAppend("}");
134 142
135 fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); 143 fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
136 fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); 144 fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
137 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,"); 145 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,");
138 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);"); 146 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);");
139 147
140 // this gives us a smooth step across approximately one fragment 148 // this gives us a smooth step across approximately one fragment
141 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 149 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);");
142 } 150 }
143 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);"); 151 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista nce);");
144 152
145 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 153 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
146 } 154 }
147 155
148 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { 156 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override {
149 #ifdef SK_GAMMA_APPLY_TO_A8 157 #ifdef SK_GAMMA_APPLY_TO_A8
150 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi eldA8TextGeoProc>(); 158 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi eldA8TextGeoProc>();
151 float distanceAdjust = dfTexEffect.getDistanceAdjust(); 159 float distanceAdjust = dfTexEffect.getDistanceAdjust();
152 if (distanceAdjust != fDistanceAdjust) { 160 if (distanceAdjust != fDistanceAdjust) {
153 pdman.set1f(fDistanceAdjustUni, distanceAdjust); 161 pdman.set1f(fDistanceAdjustUni, distanceAdjust);
154 fDistanceAdjust = distanceAdjust; 162 fDistanceAdjust = distanceAdjust;
155 } 163 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 public: 287 public:
280 GrGLDistanceFieldPathGeoProc() 288 GrGLDistanceFieldPathGeoProc()
281 : fViewMatrix(SkMatrix::InvalidMatrix()) 289 : fViewMatrix(SkMatrix::InvalidMatrix())
282 , fColor(GrColor_ILLEGAL) 290 , fColor(GrColor_ILLEGAL)
283 , fTextureSize(SkISize::Make(-1, -1)) {} 291 , fTextureSize(SkISize::Make(-1, -1)) {}
284 292
285 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 293 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
286 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance FieldPathGeoProc>(); 294 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance FieldPathGeoProc>();
287 295
288 GrGLSLGPBuilder* pb = args.fPB; 296 GrGLSLGPBuilder* pb = args.fPB;
289 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); 297 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
290 SkAssertResult(fsBuilder->enableFeature( 298 SkAssertResult(fragBuilder->enableFeature(
291 GrGLSLFragmentShaderBuilder::kStandardDeriv atives_GLSLFeature)); 299 GrGLSLFragmentShaderBuilder::kStandardDeriv atives_GLSLFeature));
292 300
293 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); 301 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
294 302
295 // emit attributes 303 // emit attributes
296 vsBuilder->emitAttributes(dfTexEffect); 304 vertBuilder->emitAttributes(dfTexEffect);
297 305
298 GrGLSLVertToFrag v(kVec2f_GrSLType); 306 GrGLSLVertToFrag v(kVec2f_GrSLType);
299 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); 307 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
300 308
301 // setup pass through color 309 // setup pass through color
302 if (!dfTexEffect.colorIgnored()) { 310 if (!dfTexEffect.colorIgnored()) {
303 if (dfTexEffect.hasVertexColor()) { 311 if (dfTexEffect.hasVertexColor()) {
304 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC olor); 312 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC olor);
305 } else { 313 } else {
306 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); 314 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo lorUniform);
307 } 315 }
308 } 316 }
309 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord s()->fName); 317 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo rds()->fName);
310 318
311 // Setup position 319 // Setup position
312 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf fect.viewMatrix(), 320 this->setupPosition(pb,
321 vertBuilder,
322 gpArgs,
323 dfTexEffect.inPosition()->fName,
324 dfTexEffect.viewMatrix(),
313 &fViewMatrixUniform); 325 &fViewMatrixUniform);
314 326
315 // emit transforms 327 // emit transforms
316 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()- >fName, 328 this->emitTransforms(pb,
317 args.fTransformsIn, args.fTransformsOut); 329 vertBuilder,
330 gpArgs->fPositionVar,
331 dfTexEffect.inPosition()->fName,
332 args.fTransformsIn,
333 args.fTransformsOut);
318 334
319 const char* textureSizeUniName = nullptr; 335 const char* textureSizeUniName = nullptr;
320 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil ity, 336 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil ity,
321 kVec2f_GrSLType, kDefault_GrSLPrecision , 337 kVec2f_GrSLType, kDefault_GrSLPrecision ,
322 "TextureSize", &textureSizeUniName); 338 "TextureSize", &textureSizeUniName);
323 339
324 // Use highp to work around aliasing issues 340 // Use highp to work around aliasing issues
325 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), 341 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
326 kHigh_GrSLPrecisi on)); 342 kHigh_GrSLPreci sion));
327 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); 343 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
328 344
329 fsBuilder->codeAppend("float texColor = "); 345 fragBuilder->codeAppend("float texColor = ");
330 fsBuilder->appendTextureLookup(args.fSamplers[0], 346 fragBuilder->appendTextureLookup(args.fSamplers[0],
331 "uv", 347 "uv",
332 kVec2f_GrSLType); 348 kVec2f_GrSLType);
333 fsBuilder->codeAppend(".r;"); 349 fragBuilder->codeAppend(".r;");
334 fsBuilder->codeAppend("float distance = " 350 fragBuilder->codeAppend("float distance = "
335 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 351 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
336 352
337 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), 353 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
338 kHigh_GrSLPrecisi on)); 354 kHigh_GrSLPreci sion));
339 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 355 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
340 fsBuilder->codeAppend("float afwidth;"); 356 fragBuilder->codeAppend("float afwidth;");
341 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 357 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
342 // For uniform scale, we adjust for the effect of the transformation on the distance 358 // For uniform scale, we adjust for the effect of the transformation on the distance
343 // by using the length of the gradient of the texture coordinates. W e use st coordinates 359 // by using the length of the gradient of the texture coordinates. W e use st coordinates
344 // to ensure we're mapping 1:1 from texel space to pixel space. 360 // to ensure we're mapping 1:1 from texel space to pixel space.
345 361
346 // this gives us a smooth step across approximately one fragment 362 // this gives us a smooth step across approximately one fragment
347 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF dy(st.y));"); 363 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "* dFdy(st.y));");
348 } else { 364 } else {
349 // For general transforms, to determine the amount of correction we multiply a unit 365 // For general transforms, to determine the amount of correction we multiply a unit
350 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 366 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
351 // (which is the inverse transform for this fragment) and take the l ength of the result. 367 // (which is the inverse transform for this fragment) and take the l ength of the result.
352 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di stance));"); 368 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));");
353 // the length of the gradient may be 0, so we need to check for this 369 // the length of the gradient may be 0, so we need to check for this
354 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 370 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
355 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 371 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
356 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 372 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
357 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 373 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
358 fsBuilder->codeAppend("} else {"); 374 fragBuilder->codeAppend("} else {");
359 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);") ; 375 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2); ");
360 fsBuilder->codeAppend("}"); 376 fragBuilder->codeAppend("}");
361 377
362 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 378 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
363 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 379 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
364 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,"); 380 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,");
365 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);"); 381 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);");
366 382
367 // this gives us a smooth step across approximately one fragment 383 // this gives us a smooth step across approximately one fragment
368 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 384 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);");
369 } 385 }
370 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);"); 386 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista nce);");
371 387
372 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 388 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
373 } 389 }
374 390
375 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { 391 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override {
376 SkASSERT(fTextureSizeUni.isValid()); 392 SkASSERT(fTextureSizeUni.isValid());
377 393
378 GrTexture* texture = proc.texture(0); 394 GrTexture* texture = proc.texture(0);
379 if (texture->width() != fTextureSize.width() || 395 if (texture->width() != fTextureSize.width() ||
380 texture->height() != fTextureSize.height()) { 396 texture->height() != fTextureSize.height()) {
381 fTextureSize = SkISize::Make(texture->width(), texture->height()); 397 fTextureSize = SkISize::Make(texture->width(), texture->height());
382 pdman.set2f(fTextureSizeUni, 398 pdman.set2f(fTextureSizeUni,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 GrGLDistanceFieldLCDTextGeoProc() 511 GrGLDistanceFieldLCDTextGeoProc()
496 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { 512 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) {
497 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1. 0f, 1.0f, 1.0f); 513 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1. 0f, 1.0f, 1.0f);
498 } 514 }
499 515
500 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 516 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
501 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = 517 const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
502 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); 518 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
503 GrGLSLGPBuilder* pb = args.fPB; 519 GrGLSLGPBuilder* pb = args.fPB;
504 520
505 GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); 521 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
506 522
507 // emit attributes 523 // emit attributes
508 vsBuilder->emitAttributes(dfTexEffect); 524 vertBuilder->emitAttributes(dfTexEffect);
525
526 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
509 527
510 // setup pass through color 528 // setup pass through color
511 if (!dfTexEffect.colorIgnored()) { 529 if (!dfTexEffect.colorIgnored()) {
512 this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); 530 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorU niform);
513 } 531 }
514 532
515 // Setup position 533 // Setup position
516 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEf fect.viewMatrix(), 534 this->setupPosition(pb,
535 vertBuilder,
536 gpArgs,
537 dfTexEffect.inPosition()->fName,
538 dfTexEffect.viewMatrix(),
517 &fViewMatrixUniform); 539 &fViewMatrixUniform);
518 540
519 // emit transforms 541 // emit transforms
520 this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()- >fName, 542 this->emitTransforms(pb,
521 args.fTransformsIn, args.fTransformsOut); 543 vertBuilder,
544 gpArgs->fPositionVar,
545 dfTexEffect.inPosition()->fName,
546 args.fTransformsIn,
547 args.fTransformsOut);
522 548
523 // set up varyings 549 // set up varyings
524 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di stanceFieldEffectMask); 550 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di stanceFieldEffectMask);
525 GrGLSLVertToFrag recipScale(kFloat_GrSLType); 551 GrGLSLVertToFrag recipScale(kFloat_GrSLType);
526 GrGLSLVertToFrag st(kVec2f_GrSLType); 552 GrGLSLVertToFrag st(kVec2f_GrSLType);
527 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 553 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
528 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor ds()->fName); 554 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo ords()->fName);
529 555
530 // compute numbers to be hardcoded to convert texture coordinates from i nt to float 556 // compute numbers to be hardcoded to convert texture coordinates from i nt to float
531 SkASSERT(dfTexEffect.numTextures() == 1); 557 SkASSERT(dfTexEffect.numTextures() == 1);
532 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); 558 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
533 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; 559 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ;
534 SkScalar recipWidth = 1.0f / atlas->width(); 560 SkScalar recipWidth = 1.0f / atlas->width();
535 SkScalar recipHeight = 1.0f / atlas->height(); 561 SkScalar recipHeight = 1.0f / atlas->height();
536 562
537 GrGLSLVertToFrag uv(kVec2f_GrSLType); 563 GrGLSLVertToFrag uv(kVec2f_GrSLType);
538 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 564 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
539 vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), 565 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
540 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, 566 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
541 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, 567 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
542 dfTexEffect.inTextureCoords()->fName); 568 dfTexEffect.inTextureCoords()->fName);
543 569
544 // add frag shader code 570 // add frag shader code
545 GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
546 571
547 SkAssertResult(fsBuilder->enableFeature( 572 SkAssertResult(fragBuilder->enableFeature(
548 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 573 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
549 574
550 // create LCD offset adjusted by inverse of transform 575 // create LCD offset adjusted by inverse of transform
551 // Use highp to work around aliasing issues 576 // Use highp to work around aliasing issues
552 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), 577 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
553 kHigh_GrSLPrecisi on)); 578 kHigh_GrSLPreci sion));
554 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 579 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
555 fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(), 580 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
556 kHigh_GrSLPrecisi on)); 581 kHigh_GrSLPreci sion));
557 582
558 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); 583 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
559 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 584 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
560 fsBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta); 585 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI G, lcdDelta);
561 } else { 586 } else {
562 fsBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta); 587 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG , lcdDelta);
563 } 588 }
564 if (isUniformScale) { 589 if (isUniformScale) {
565 fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn()); 590 fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
566 fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); 591 fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
567 } else { 592 } else {
568 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); 593 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
569 594
570 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 595 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
571 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 596 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
572 fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); 597 fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
573 } 598 }
574 599
575 // green is distance to uv center 600 // green is distance to uv center
576 fsBuilder->codeAppend("\tvec4 texColor = "); 601 fragBuilder->codeAppend("\tvec4 texColor = ");
577 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType) ; 602 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLTyp e);
578 fsBuilder->codeAppend(";\n"); 603 fragBuilder->codeAppend(";\n");
579 fsBuilder->codeAppend("\tvec3 distance;\n"); 604 fragBuilder->codeAppend("\tvec3 distance;\n");
580 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 605 fragBuilder->codeAppend("\tdistance.y = texColor.r;\n");
581 // red is distance to left offset 606 // red is distance to left offset
582 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 607 fragBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
583 fsBuilder->codeAppend("\ttexColor = "); 608 fragBuilder->codeAppend("\ttexColor = ");
584 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType); 609 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2 f_GrSLType);
585 fsBuilder->codeAppend(";\n"); 610 fragBuilder->codeAppend(";\n");
586 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 611 fragBuilder->codeAppend("\tdistance.x = texColor.r;\n");
587 // blue is distance to right offset 612 // blue is distance to right offset
588 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 613 fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
589 fsBuilder->codeAppend("\ttexColor = "); 614 fragBuilder->codeAppend("\ttexColor = ");
590 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_ GrSLType); 615 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2 f_GrSLType);
591 fsBuilder->codeAppend(";\n"); 616 fragBuilder->codeAppend(";\n");
592 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 617 fragBuilder->codeAppend("\tdistance.z = texColor.r;\n");
593 618
594 fsBuilder->codeAppend("\tdistance = " 619 fragBuilder->codeAppend("\tdistance = "
595 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF ieldThreshold"));"); 620 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF ieldThreshold"));");
596 621
597 // adjust width based on gamma 622 // adjust width based on gamma
598 const char* distanceAdjustUniName = nullptr; 623 const char* distanceAdjustUniName = nullptr;
599 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi bility, 624 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi bility,
600 kVec3f_GrSLType, kDefault_GrSLPrecision, 625 kVec3f_GrSLType, kDefault_GrSLPrecision,
601 "DistanceAdjust", &distanceAdjustUniName); 626 "DistanceAdjust", &distanceAdjustUniName);
602 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 627 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
603 628
604 // To be strictly correct, we should compute the anti-aliasing factor se parately 629 // To be strictly correct, we should compute the anti-aliasing factor se parately
605 // for each color component. However, this is only important when using perspective 630 // for each color component. However, this is only important when using perspective
606 // transformations, and even then using a single factor seems like a rea sonable 631 // transformations, and even then using a single factor seems like a rea sonable
607 // trade-off between quality and speed. 632 // trade-off between quality and speed.
608 fsBuilder->codeAppend("float afwidth;"); 633 fragBuilder->codeAppend("float afwidth;");
609 if (isUniformScale) { 634 if (isUniformScale) {
610 // For uniform scale, we adjust for the effect of the transformation on the distance 635 // For uniform scale, we adjust for the effect of the transformation on the distance
611 // by using the length of the gradient of the texture coordinates. W e use st coordinates 636 // by using the length of the gradient of the texture coordinates. W e use st coordinates
612 // to ensure we're mapping 1:1 from texel space to pixel space. 637 // to ensure we're mapping 1:1 from texel space to pixel space.
613 638
614 // this gives us a smooth step across approximately one fragment 639 // this gives us a smooth step across approximately one fragment
615 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;"); 640 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;" );
616 } else { 641 } else {
617 // For general transforms, to determine the amount of correction we multiply a unit 642 // For general transforms, to determine the amount of correction we multiply a unit
618 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 643 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
619 // (which is the inverse transform for this fragment) and take the l ength of the result. 644 // (which is the inverse transform for this fragment) and take the l ength of the result.
620 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy( distance.r));"); 645 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd y(distance.r));");
621 // the length of the gradient may be 0, so we need to check for this 646 // the length of the gradient may be 0, so we need to check for this
622 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 647 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
623 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 648 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
624 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 649 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
625 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 650 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
626 fsBuilder->codeAppend("} else {"); 651 fragBuilder->codeAppend("} else {");
627 fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);") ; 652 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2); ");
628 fsBuilder->codeAppend("}"); 653 fragBuilder->codeAppend("}");
629 fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_gra d.y*Jdy.x,"); 654 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,");
630 fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_gra d.y*Jdy.y);"); 655 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);");
631 656
632 // this gives us a smooth step across approximately one fragment 657 // this gives us a smooth step across approximately one fragment
633 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);"); 658 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);");
634 } 659 }
635 660
636 fsBuilder->codeAppend( 661 fragBuilder->codeAppend(
637 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);"); 662 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
638 // set alpha to be max of rgb coverage 663 // set alpha to be max of rgb coverage
639 fsBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); 664 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
640 665
641 fsBuilder->codeAppendf("%s = val;", args.fOutputCoverage); 666 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
642 } 667 }
643 668
644 void setData(const GrGLSLProgramDataManager& pdman, 669 void setData(const GrGLSLProgramDataManager& pdman,
645 const GrPrimitiveProcessor& processor) override { 670 const GrPrimitiveProcessor& processor) override {
646 SkASSERT(fDistanceAdjustUni.isValid()); 671 SkASSERT(fDistanceAdjustUni.isValid());
647 672
648 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi eldLCDTextGeoProc>(); 673 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi eldLCDTextGeoProc>();
649 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju st(); 674 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju st();
650 if (wa != fDistanceAdjust) { 675 if (wa != fDistanceAdjust) {
651 pdman.set3f(fDistanceAdjustUni, 676 pdman.set3f(fDistanceAdjustUni,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 777 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
753 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 778 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
754 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 779 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
755 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), 780 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom),
756 GrTest::TestMatrix(d->fRandom), 781 GrTest::TestMatrix(d->fRandom),
757 d->fTextures[texIdx], params, 782 d->fTextures[texIdx], params,
758 wa, 783 wa,
759 flags, 784 flags,
760 d->fRandom->nextBool()); 785 d->fRandom->nextBool());
761 } 786 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDisableColorXP.cpp ('k') | src/gpu/effects/GrDitherEffect.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698