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

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

Issue 1776383002: Use correct gradient calculation for rotated distance fields. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix android error Created 4 years, 9 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/GrDistanceFieldGeoProc.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 "GrDistanceFieldGeoProc.h" 8 #include "GrDistanceFieldGeoProc.h"
9 #include "GrInvariantOutput.h" 9 #include "GrInvariantOutput.h"
10 #include "GrTexture.h" 10 #include "GrTexture.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 varyingHandler, 72 varyingHandler,
73 uniformHandler, 73 uniformHandler,
74 gpArgs->fPositionVar, 74 gpArgs->fPositionVar,
75 dfTexEffect.inPosition()->fName, 75 dfTexEffect.inPosition()->fName,
76 args.fTransformsIn, 76 args.fTransformsIn,
77 args.fTransformsOut); 77 args.fTransformsOut);
78 78
79 // add varyings 79 // add varyings
80 GrGLSLVertToFrag recipScale(kFloat_GrSLType); 80 GrGLSLVertToFrag recipScale(kFloat_GrSLType);
81 GrGLSLVertToFrag uv(kVec2f_GrSLType); 81 GrGLSLVertToFrag uv(kVec2f_GrSLType);
82 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) ==
83 kUniformScale_DistanceFieldEffectMask;
82 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); 84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag);
83 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 85 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
84 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); 86 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName);
85 87
86 // 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 f loat to int
87 SkASSERT(dfTexEffect.numTextures() == 1); 89 SkASSERT(dfTexEffect.numTextures() == 1);
88 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); 90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
89 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; 91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ;
90 92
91 GrGLSLVertToFrag st(kVec2f_GrSLType); 93 GrGLSLVertToFrag st(kVec2f_GrSLType);
92 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ; 94 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ;
93 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), 95 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(),
94 atlas->width(), atlas->height(), 96 atlas->width(), atlas->height(),
95 dfTexEffect.inTextureCoords()->fName); 97 dfTexEffect.inTextureCoords()->fName);
96 98
97 // Use highp to work around aliasing issues 99 // Use highp to work around aliasing issues
98 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, 100 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
99 kHigh_GrSLPreci sion)); 101 kHigh_GrSLPreci sion));
100 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 102 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
101 103
102 fragBuilder->codeAppend("\tfloat texColor = "); 104 fragBuilder->codeAppend("\tfloat texColor = ");
103 fragBuilder->appendTextureLookup(args.fSamplers[0], 105 fragBuilder->appendTextureLookup(args.fSamplers[0],
104 "uv", 106 "uv",
105 kVec2f_GrSLType); 107 kVec2f_GrSLType);
106 fragBuilder->codeAppend(".r;\n"); 108 fragBuilder->codeAppend(".r;\n");
107 fragBuilder->codeAppend("\tfloat distance = " 109 fragBuilder->codeAppend("\tfloat distance = "
108 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");"); 110 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie ldThreshold ");");
109 #ifdef SK_GAMMA_APPLY_TO_A8 111 #ifdef SK_GAMMA_APPLY_TO_A8
110 // adjust width based on gamma 112 // adjust width based on gamma
111 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 113 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
112 #endif 114 #endif
113 115
114 fragBuilder->codeAppend("float afwidth;"); 116 fragBuilder->codeAppend("float afwidth;");
115 if (isSimilarity) { 117 if (isUniformScale) {
116 // For uniform scale, we adjust for the effect of the transformation on the distance 118 // For uniform scale, we adjust for the effect of the transformation on the distance
119 // by using the length of the gradient of the t coordinate in the y direction.
120 // We use st coordinates to ensure we're mapping 1:1 from texel spac e to pixel space.
121 // We use the y gradient because there is a bug in the Mali 400 in t he x direction.
122
123 // this gives us a smooth step across approximately one fragment
124 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor " *dFdy(%s.y));",
125 st.fsIn());
126 } else if (isSimilarity) {
127 // For similarity transform, we adjust the effect of the transformat ion on the distance
117 // by using the length of the gradient of the texture coordinates. W e use st coordinates 128 // by using the length of the gradient of the texture coordinates. W e use st coordinates
118 // to ensure we're mapping 1:1 from texel space to pixel space. 129 // to ensure we're mapping 1:1 from texel space to pixel space.
130 // We use the y gradient because there is a bug in the Mali 400 in t he x direction.
119 131
120 // this gives us a smooth step across approximately one fragment 132 // this gives us a smooth step across approximately one fragment
121 // we use y to work around a Mali400 bug in the x direction 133 fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st .fsIn());
122 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor " *dFdy(%s.y));", 134 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "* st_grad_len);");
123 st.fsIn());
124 } else { 135 } else {
125 // For general transforms, to determine the amount of correction we multiply a unit 136 // For general transforms, to determine the amount of correction we multiply a unit
126 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 137 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
127 // (which is the inverse transform for this fragment) and take the l ength of the result. 138 // (which is the inverse transform for this fragment) and take the l ength of the result.
128 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));"); 139 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));");
129 // the length of the gradient may be 0, so we need to check for this 140 // the length of the gradient may be 0, so we need to check for this
130 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 141 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
131 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" ); 142 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
132 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 143 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
133 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 144 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 SkShader::kRepeat_TileMode, 258 SkShader::kRepeat_TileMode,
248 SkShader::kMirror_TileMode, 259 SkShader::kMirror_TileMode,
249 }; 260 };
250 SkShader::TileMode tileModes[] = { 261 SkShader::TileMode tileModes[] = {
251 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 262 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
252 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 263 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
253 }; 264 };
254 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode : 265 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode :
255 GrTextureParams::kNon e_FilterMode); 266 GrTextureParams::kNon e_FilterMode);
256 267
268 uint32_t flags = 0;
269 flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
270 if (flags & kSimilarity_DistanceFieldEffectFlag) {
271 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0 ;
272 }
273
257 return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(d->fRandom), 274 return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(d->fRandom),
258 GrTest::TestMatrix(d->fRandom), 275 GrTest::TestMatrix(d->fRandom),
259 d->fTextures[texIdx], params, 276 d->fTextures[texIdx], params,
260 #ifdef SK_GAMMA_APPLY_TO_A8 277 #ifdef SK_GAMMA_APPLY_TO_A8
261 d->fRandom->nextF(), 278 d->fRandom->nextF(),
262 #endif 279 #endif
263 d->fRandom->nextBool() ? 280 flags,
264 kSimilarity_DistanceFieldEff ectFlag : 0, 281 d->fRandom->nextBool());
265 d->fRandom->nextBool());
266 } 282 }
267 283
268 /////////////////////////////////////////////////////////////////////////////// 284 ///////////////////////////////////////////////////////////////////////////////
269 285
270 class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor { 286 class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor {
271 public: 287 public:
272 GrGLDistanceFieldPathGeoProc() 288 GrGLDistanceFieldPathGeoProc()
273 : fViewMatrix(SkMatrix::InvalidMatrix()) 289 : fViewMatrix(SkMatrix::InvalidMatrix())
274 , fTextureSize(SkISize::Make(-1, -1)) {} 290 , fTextureSize(SkISize::Make(-1, -1)) {}
275 291
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 "uv", 344 "uv",
329 kVec2f_GrSLType); 345 kVec2f_GrSLType);
330 fragBuilder->codeAppend(".r;"); 346 fragBuilder->codeAppend(".r;");
331 fragBuilder->codeAppend("float distance = " 347 fragBuilder->codeAppend("float distance = "
332 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 348 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
333 349
334 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, 350 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
335 kHigh_GrSLPreci sion)); 351 kHigh_GrSLPreci sion));
336 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 352 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
337 fragBuilder->codeAppend("float afwidth;"); 353 fragBuilder->codeAppend("float afwidth;");
338 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 354 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) ==
355 kUniformScale_DistanceFieldEffectMask;
356 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag);
357 if (isUniformScale) {
339 // 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
340 // 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 t coordinate in the y direction.
341 // to ensure we're mapping 1:1 from texel space to pixel space. 360 // We use st coordinates to ensure we're mapping 1:1 from texel spac e to pixel space.
361 // We use the y gradient because there is a bug in the Mali 400 in t he x direction.
342 362
343 // this gives us a smooth step across approximately one fragment 363 // this gives us a smooth step across approximately one fragment
344 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "* dFdy(st.y));"); 364 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "* dFdy(st.y));");
365
366 } else if (isSimilarity) {
367 // For similarity transform, we adjust the effect of the transformat ion on the distance
368 // by using the length of the gradient of the texture coordinates. W e use st coordinates
369 // to ensure we're mapping 1:1 from texel space to pixel space.
370 // We use the y gradient because there is a bug in the Mali 400 in t he x direction.
371
372 // this gives us a smooth step across approximately one fragment
373 fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));");
374 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "* st_grad_len);");
345 } else { 375 } else {
346 // For general transforms, to determine the amount of correction we multiply a unit 376 // For general transforms, to determine the amount of correction we multiply a unit
347 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 377 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
348 // (which is the inverse transform for this fragment) and take the l ength of the result. 378 // (which is the inverse transform for this fragment) and take the l ength of the result.
349 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));"); 379 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy( distance));");
350 // the length of the gradient may be 0, so we need to check for this 380 // the length of the gradient may be 0, so we need to check for this
351 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 381 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
352 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" ); 382 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
353 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 383 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
354 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 384 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 SkShader::kRepeat_TileMode, 487 SkShader::kRepeat_TileMode,
458 SkShader::kMirror_TileMode, 488 SkShader::kMirror_TileMode,
459 }; 489 };
460 SkShader::TileMode tileModes[] = { 490 SkShader::TileMode tileModes[] = {
461 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 491 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
462 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 492 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
463 }; 493 };
464 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode 494 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode
465 : GrTextureParams:: kNone_FilterMode); 495 : GrTextureParams:: kNone_FilterMode);
466 496
497 uint32_t flags = 0;
498 flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
499 if (flags & kSimilarity_DistanceFieldEffectFlag) {
500 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0 ;
501 }
502
467 return GrDistanceFieldPathGeoProc::Create(GrRandomColor(d->fRandom), 503 return GrDistanceFieldPathGeoProc::Create(GrRandomColor(d->fRandom),
468 GrTest::TestMatrix(d->fRandom), 504 GrTest::TestMatrix(d->fRandom),
469 d->fTextures[texIdx], 505 d->fTextures[texIdx],
470 params, 506 params,
471 d->fRandom->nextBool() ? 507 flags,
472 kSimilarity_DistanceFieldE ffectFlag : 0, 508 d->fRandom->nextBool());
473 d->fRandom->nextBool());
474 } 509 }
475 510
476 /////////////////////////////////////////////////////////////////////////////// 511 ///////////////////////////////////////////////////////////////////////////////
477 512
478 class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor { 513 class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor {
479 public: 514 public:
480 GrGLDistanceFieldLCDTextGeoProc() 515 GrGLDistanceFieldLCDTextGeoProc()
481 : fViewMatrix(SkMatrix::InvalidMatrix()) { 516 : fViewMatrix(SkMatrix::InvalidMatrix()) {
482 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1. 0f, 1.0f, 1.0f); 517 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1. 0f, 1.0f, 1.0f);
483 } 518 }
(...skipping 27 matching lines...) Expand all
511 // emit transforms 546 // emit transforms
512 this->emitTransforms(vertBuilder, 547 this->emitTransforms(vertBuilder,
513 varyingHandler, 548 varyingHandler,
514 uniformHandler, 549 uniformHandler,
515 gpArgs->fPositionVar, 550 gpArgs->fPositionVar,
516 dfTexEffect.inPosition()->fName, 551 dfTexEffect.inPosition()->fName,
517 args.fTransformsIn, 552 args.fTransformsIn,
518 args.fTransformsOut); 553 args.fTransformsOut);
519 554
520 // set up varyings 555 // set up varyings
521 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di stanceFieldEffectMask); 556 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) ==
557 kUniformScale_DistanceFieldEffectMask;
558 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag);
522 GrGLSLVertToFrag recipScale(kFloat_GrSLType); 559 GrGLSLVertToFrag recipScale(kFloat_GrSLType);
523 GrGLSLVertToFrag uv(kVec2f_GrSLType); 560 GrGLSLVertToFrag uv(kVec2f_GrSLType);
524 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 561 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
525 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); 562 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName);
526 563
527 // compute numbers to be hardcoded to convert texture coordinates from i nt to float 564 // compute numbers to be hardcoded to convert texture coordinates from f loat to int
528 SkASSERT(dfTexEffect.numTextures() == 1); 565 SkASSERT(dfTexEffect.numTextures() == 1);
529 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); 566 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
530 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; 567 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ;
531 568
532 GrGLSLVertToFrag st(kVec2f_GrSLType); 569 GrGLSLVertToFrag st(kVec2f_GrSLType);
533 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ; 570 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ;
534 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), 571 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(),
535 atlas->width(), atlas->height(), 572 atlas->width(), atlas->height(),
536 dfTexEffect.inTextureCoords()->fName); 573 dfTexEffect.inTextureCoords()->fName);
537 574
(...skipping 10 matching lines...) Expand all
548 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, 585 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
549 kHigh_GrSLPreci sion)); 586 kHigh_GrSLPreci sion));
550 587
551 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); 588 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
552 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 589 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
553 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI G, lcdDelta); 590 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI G, lcdDelta);
554 } else { 591 } else {
555 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG , lcdDelta); 592 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG , lcdDelta);
556 } 593 }
557 if (isUniformScale) { 594 if (isUniformScale) {
558 fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn()); 595 fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st. fsIn());
559 fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); 596 fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0); ");
597 } else if (isSimilarity) {
598 // For a similarity matrix with rotation, the gradient will not be a ligned
599 // with the texel coordinate axes, so we need to calculate it.
600 // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
601 // get the gradient in the x direction.
602 fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn());
603 fragBuilder->codeAppend("float st_grad_len = length(st_grad);");
604 fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_gra d.x);");
560 } else { 605 } else {
561 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); 606 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
562 607
563 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 608 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
564 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 609 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
565 fragBuilder->codeAppend("vec2 offset = delta*Jdx;"); 610 fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
566 } 611 }
567 612
568 // green is distance to uv center 613 // green is distance to uv center
569 fragBuilder->codeAppend("\tvec4 texColor = "); 614 fragBuilder->codeAppend("\tvec4 texColor = ");
(...skipping 22 matching lines...) Expand all
592 fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 637 fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
593 kVec3f_GrSLType, kDefaul t_GrSLPrecision, 638 kVec3f_GrSLType, kDefaul t_GrSLPrecision,
594 "DistanceAdjust", &dista nceAdjustUniName); 639 "DistanceAdjust", &dista nceAdjustUniName);
595 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 640 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
596 641
597 // To be strictly correct, we should compute the anti-aliasing factor se parately 642 // To be strictly correct, we should compute the anti-aliasing factor se parately
598 // for each color component. However, this is only important when using perspective 643 // for each color component. However, this is only important when using perspective
599 // transformations, and even then using a single factor seems like a rea sonable 644 // transformations, and even then using a single factor seems like a rea sonable
600 // trade-off between quality and speed. 645 // trade-off between quality and speed.
601 fragBuilder->codeAppend("float afwidth;"); 646 fragBuilder->codeAppend("float afwidth;");
602 if (isUniformScale) { 647 if (isSimilarity) {
603 // For uniform scale, we adjust for the effect of the transformation on the distance 648 // For similarity transform (uniform scale-only is a subset of this) , we adjust for the
604 // by using the length of the gradient of the texture coordinates. W e use st coordinates 649 // effect of the transformation on the distance by using the length of the gradient of
605 // to ensure we're mapping 1:1 from texel space to pixel space. 650 // the texture coordinates. We use st coordinates to ensure we're ma pping 1:1 from texel
651 // space to pixel space.
606 652
607 // this gives us a smooth step across approximately one fragment 653 // this gives us a smooth step across approximately one fragment
608 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;" ); 654 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_g rad_len;");
609 } else { 655 } else {
610 // For general transforms, to determine the amount of correction we multiply a unit 656 // For general transforms, to determine the amount of correction we multiply a unit
611 // vector pointing along the SDF gradient direction by the Jacobian of the st coords 657 // vector pointing along the SDF gradient direction by the Jacobian of the st coords
612 // (which is the inverse transform for this fragment) and take the l ength of the result. 658 // (which is the inverse transform for this fragment) and take the l ength of the result.
613 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd y(distance.r));"); 659 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd y(distance.r));");
614 // the length of the gradient may be 0, so we need to check for this 660 // the length of the gradient may be 0, so we need to check for this
615 // this also compensates for the Adreno, which likes to drop tiles o n division by 0 661 // this also compensates for the Adreno, which likes to drop tiles o n division by 0
616 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" ); 662 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);" );
617 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 663 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
618 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 664 fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 SkShader::kMirror_TileMode, 776 SkShader::kMirror_TileMode,
731 }; 777 };
732 SkShader::TileMode tileModes[] = { 778 SkShader::TileMode tileModes[] = {
733 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 779 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
734 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 780 kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
735 }; 781 };
736 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode : 782 GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams:: kBilerp_FilterMode :
737 GrTextureParams::kNone_FilterMode); 783 GrTextureParams::kNone_FilterMode);
738 DistanceAdjust wa = { 0.0f, 0.1f, -0.1f }; 784 DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
739 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 785 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
740 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 786 flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
787 if (flags & kSimilarity_DistanceFieldEffectFlag) {
788 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0 ;
789 }
741 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 790 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
742 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), 791 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom),
743 GrTest::TestMatrix(d->fRandom), 792 GrTest::TestMatrix(d->fRandom),
744 d->fTextures[texIdx], params, 793 d->fTextures[texIdx], params,
745 wa, 794 wa,
746 flags, 795 flags,
747 d->fRandom->nextBool()); 796 d->fRandom->nextBool());
748 } 797 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDistanceFieldGeoProc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698