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

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

Issue 589103004: Add GrAASmallPathRenderer. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address nits Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDistanceFieldTextureEffect.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrDistanceFieldTextureEffect.h" 8 #include "GrDistanceFieldTextureEffect.h"
9 #include "gl/builders/GrGLFullProgramBuilder.h" 9 #include "gl/builders/GrGLFullProgramBuilder.h"
10 #include "gl/GrGLProcessor.h" 10 #include "gl/GrGLProcessor.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 "+ " SK_DistanceFieldNonLCDFactor ";\n"); 79 "+ " SK_DistanceFieldNonLCDFactor ";\n");
80 80
81 // we adjust for the effect of the transformation on the distance by usi ng 81 // we adjust for the effect of the transformation on the distance by usi ng
82 // the length of the gradient of the texture coordinates. We use st coor dinates 82 // the length of the gradient of the texture coordinates. We use st coor dinates
83 // to ensure we're mapping 1:1 from texel space to pixel space. 83 // to ensure we're mapping 1:1 from texel space to pixel space.
84 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 84 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
85 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 85 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
86 fsBuilder->codeAppend("\tfloat afwidth;\n"); 86 fsBuilder->codeAppend("\tfloat afwidth;\n");
87 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 87 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
88 // this gives us a smooth step across approximately one fragment 88 // this gives us a smooth step across approximately one fragment
89 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx (st.x);\n"); 89 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dFdx(st.x));\n");
90 } else { 90 } else {
91 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 91 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
92 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 92 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
93 93
94 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 94 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
95 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 95 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
96 // this is to compensate for the Adreno, which likes to drop til es on division by 0 96 // this is to compensate for the Adreno, which likes to drop til es on division by 0
97 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 97 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
98 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 98 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
99 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 99 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 bool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const { 199 bool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const {
200 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureE ffect>(); 200 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureE ffect>();
201 return fTextureAccess == cte.fTextureAccess && 201 return fTextureAccess == cte.fTextureAccess &&
202 #ifdef SK_GAMMA_APPLY_TO_A8 202 #ifdef SK_GAMMA_APPLY_TO_A8
203 fGammaTextureAccess == cte.fGammaTextureAccess && 203 fGammaTextureAccess == cte.fGammaTextureAccess &&
204 fLuminance == cte.fLuminance && 204 fLuminance == cte.fLuminance &&
205 #endif 205 #endif
206 fFlags == cte.fFlags; 206 fFlags == cte.fFlags;
207 } 207 }
208 208
209 void GrDistanceFieldTextureEffect::onComputeInvariantOutput( 209 void GrDistanceFieldTextureEffect::onComputeInvariantOutput(InvariantOutput* ino ut) const {
210 InvariantOutput* inout) const {
211 if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { 210 if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
212 inout->fValidFlags = kA_GrColorComponentFlag; 211 inout->fValidFlags = kA_GrColorComponentFlag;
213 } else { 212 } else {
214 inout->fValidFlags = 0; 213 inout->fValidFlags = 0;
215 } 214 }
216 inout->fIsSingleComponent = false; 215 inout->fIsSingleComponent = false;
217 } 216 }
218 217
219 const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactor y() const { 218 const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactor y() const {
220 return GrTBackendGeometryProcessorFactory<GrDistanceFieldTextureEffect>::get Instance(); 219 return GrTBackendGeometryProcessorFactory<GrDistanceFieldTextureEffect>::get Instance();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 #ifdef SK_GAMMA_APPLY_TO_A8 253 #ifdef SK_GAMMA_APPLY_TO_A8
255 textures[texIdx2], params2, 254 textures[texIdx2], params2,
256 random->nextF(), 255 random->nextF(),
257 #endif 256 #endif
258 random->nextBool() ? 257 random->nextBool() ?
259 kSimilarity_DistanceFieldEff ectFlag : 0); 258 kSimilarity_DistanceFieldEff ectFlag : 0);
260 } 259 }
261 260
262 /////////////////////////////////////////////////////////////////////////////// 261 ///////////////////////////////////////////////////////////////////////////////
263 262
263 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
264 public:
265 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto ry,
266 const GrProcessor& effect)
267 : INHERITED(factory)
268 , fTextureSize(SkISize::Make(-1, -1)) {}
269
270 virtual void emitCode(GrGLFullProgramBuilder* builder,
271 const GrGeometryProcessor& effect,
272 const GrProcessorKey& key,
273 const char* outputColor,
274 const char* inputColor,
275 const TransformedCoordsArray&,
276 const TextureSamplerArray& samplers) SK_OVERRIDE {
277 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
278 effect.cast<GrDistanceFieldNoGam maTextureEffect>();
279 SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
280
281 GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShad erBuilder();
282 SkAssertResult(fsBuilder->enableFeature(
283 GrGLFragmentShaderBuilder::kStandardDerivat ives_GLSLFeature));
284
285 SkString fsCoordName;
286 const char* vsCoordName;
287 const char* fsCoordNamePtr;
288 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr);
289 fsCoordName = fsCoordNamePtr;
290
291 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
292 vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoo rds().c_str());
293
294 const char* textureSizeUniName = NULL;
295 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi bility,
296 kVec2f_GrSLType, "TextureSize",
297 &textureSizeUniName);
298
299 fsBuilder->codeAppend("vec4 texColor = ");
300 fsBuilder->appendTextureLookup(samplers[0],
301 fsCoordName.c_str(),
302 kVec2f_GrSLType);
303 fsBuilder->codeAppend(";");
304 fsBuilder->codeAppend("float distance = "
305 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho ld ");");
306
307 // we adjust for the effect of the transformation on the distance by usi ng
308 // the length of the gradient of the texture coordinates. We use st coor dinates
309 // to ensure we're mapping 1:1 from texel space to pixel space.
310 fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str());
311 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
312 fsBuilder->codeAppend("float afwidth;");
313 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
314 // this gives us a smooth step across approximately one fragment
315 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF dx(st.x));");
316 } else {
317 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
318 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
319
320 fsBuilder->codeAppend("vec2 uv_grad;");
321 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
322 // this is to compensate for the Adreno, which likes to drop til es on division by 0
323 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
324 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
325 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
326 fsBuilder->codeAppend("} else {");
327 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
328 fsBuilder->codeAppend("}");
329 } else {
330 fsBuilder->codeAppend("uv_grad = normalize(uv);");
331 }
332 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y* Jdy.x,");
333 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y* Jdy.y);");
334
335 // this gives us a smooth step across approximately one fragment
336 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);");
337 }
338 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);");
339
340 fsBuilder->codeAppendf("%s = %s;", outputColor,
341 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str());
342 }
343
344 virtual void setData(const GrGLProgramDataManager& pdman,
345 const GrProcessor& effect) SK_OVERRIDE {
346 SkASSERT(fTextureSizeUni.isValid());
347
348 GrTexture* texture = effect.texture(0);
349 if (texture->width() != fTextureSize.width() ||
350 texture->height() != fTextureSize.height()) {
351 fTextureSize = SkISize::Make(texture->width(), texture->height());
352 pdman.set2f(fTextureSizeUni,
353 SkIntToScalar(fTextureSize.width()),
354 SkIntToScalar(fTextureSize.height()));
355 }
356 }
357
358 static inline void GenKey(const GrProcessor& effect, const GrGLCaps&,
359 GrProcessorKeyBuilder* b) {
360 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
361 effect.cast<GrDistanceFieldNoGammaTextureEffect>();
362
363 b->add32(dfTexEffect.getFlags());
364 }
365
366 private:
367 GrGLProgramDataManager::UniformHandle fTextureSizeUni;
368 SkISize fTextureSize;
369
370 typedef GrGLGeometryProcessor INHERITED;
371 };
372
373 ///////////////////////////////////////////////////////////////////////////////
374
375 GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTextu re* texture,
376 const GrText ureParams& params,
377 uint32_t fla gs)
378 : fTextureAccess(texture, params)
379 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
380 , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
381 kVec2f_GrSLType,
382 GrShaderVar::kAttribute_TypeModifier))) {
383 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
384 this->addTextureAccess(&fTextureAccess);
385 }
386
387 bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrProcessor& other) co nst {
388 const GrDistanceFieldNoGammaTextureEffect& cte =
389 other.cast<GrDistanceFieldNoGam maTextureEffect>();
390 return fTextureAccess == cte.fTextureAccess && fFlags == cte.fFlags;
391 }
392
393 void GrDistanceFieldNoGammaTextureEffect::onComputeInvariantOutput(InvariantOutp ut* inout) const {
394 if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
395 inout->fValidFlags = kA_GrColorComponentFlag;
396 } else {
397 inout->fValidFlags = 0;
398 }
399 inout->fIsSingleComponent = false;
400 }
401
402 const GrBackendGeometryProcessorFactory& GrDistanceFieldNoGammaTextureEffect::ge tFactory() const {
403 return GrTBackendGeometryProcessorFactory<GrDistanceFieldNoGammaTextureEffec t>::getInstance();
404 }
405
406 ///////////////////////////////////////////////////////////////////////////////
407
408 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect);
409
410 GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r andom,
411 GrContext*,
412 const GrDra wTargetCaps&,
413 GrTexture* textures[]) {
414 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
415 : GrProcessorUnitTest::kAlphaTextureIdx;
416 static const SkShader::TileMode kTileModes[] = {
417 SkShader::kClamp_TileMode,
418 SkShader::kRepeat_TileMode,
419 SkShader::kMirror_TileMode,
420 };
421 SkShader::TileMode tileModes[] = {
422 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
423 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
424 };
425 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode
426 : GrTextureParams::kNon e_FilterMode);
427
428 return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params,
429 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0);
430 }
431
432 ///////////////////////////////////////////////////////////////////////////////
433
264 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 434 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
265 public: 435 public:
266 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, 436 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory,
267 const GrProcessor&) 437 const GrProcessor&)
268 : INHERITED (factory) 438 : INHERITED (factory)
269 , fTextureSize(SkISize::Make(-1,-1)) 439 , fTextureSize(SkISize::Make(-1,-1))
270 , fTextColor(GrColor_ILLEGAL) {} 440 , fTextColor(GrColor_ILLEGAL) {}
271 441
272 virtual void emitCode(GrGLFullProgramBuilder* builder, 442 virtual void emitCode(GrGLFullProgramBuilder* builder,
273 const GrGeometryProcessor& geometryProcessor, 443 const GrGeometryProcessor& geometryProcessor,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // the length of the gradient of the texture coordinates. We use st coor dinates 510 // the length of the gradient of the texture coordinates. We use st coor dinates
341 // to ensure we're mapping 1:1 from texel space to pixel space. 511 // to ensure we're mapping 1:1 from texel space to pixel space.
342 512
343 // To be strictly correct, we should compute the anti-aliasing factor se parately 513 // To be strictly correct, we should compute the anti-aliasing factor se parately
344 // for each color component. However, this is only important when using perspective 514 // for each color component. However, this is only important when using perspective
345 // transformations, and even then using a single factor seems like a rea sonable 515 // transformations, and even then using a single factor seems like a rea sonable
346 // trade-off between quality and speed. 516 // trade-off between quality and speed.
347 fsBuilder->codeAppend("\tfloat afwidth;\n"); 517 fsBuilder->codeAppend("\tfloat afwidth;\n");
348 if (isUniformScale) { 518 if (isUniformScale) {
349 // this gives us a smooth step across approximately one fragment 519 // this gives us a smooth step across approximately one fragment
350 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\ n"); 520 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dx);\n");
351 } else { 521 } else {
352 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 522 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
353 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 523 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
354 // this is to compensate for the Adreno, which likes to drop til es on division by 0 524 // this is to compensate for the Adreno, which likes to drop til es on division by 0
355 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 525 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
356 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 526 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
357 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 527 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
358 fsBuilder->codeAppend("\t} else {\n"); 528 fsBuilder->codeAppend("\t} else {\n");
359 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 529 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
360 fsBuilder->codeAppend("\t}\n"); 530 fsBuilder->codeAppend("\t}\n");
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 639 }
470 640
471 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const { 641 bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const {
472 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTe xtureEffect>(); 642 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTe xtureEffect>();
473 return (fTextureAccess == cte.fTextureAccess && 643 return (fTextureAccess == cte.fTextureAccess &&
474 fGammaTextureAccess == cte.fGammaTextureAccess && 644 fGammaTextureAccess == cte.fGammaTextureAccess &&
475 fTextColor == cte.fTextColor && 645 fTextColor == cte.fTextColor &&
476 fFlags == cte.fFlags); 646 fFlags == cte.fFlags);
477 } 647 }
478 648
479 void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput( 649 void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
480 InvariantOutput* inout) const {
481 if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { 650 if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
482 inout->fValidFlags = kA_GrColorComponentFlag; 651 inout->fValidFlags = kA_GrColorComponentFlag;
483 } else { 652 } else {
484 inout->fValidFlags = 0; 653 inout->fValidFlags = 0;
485 } 654 }
486 inout->fIsSingleComponent = false; 655 inout->fIsSingleComponent = false;
487 } 656 }
488 657
489 const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFac tory() const { 658 const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFac tory() const {
490 return GrTBackendGeometryProcessorFactory<GrDistanceFieldLCDTextureEffect>:: getInstance(); 659 return GrTBackendGeometryProcessorFactory<GrDistanceFieldLCDTextureEffect>:: getInstance();
(...skipping 29 matching lines...) Expand all
520 random->nextULessThan(256), 689 random->nextULessThan(256),
521 random->nextULessThan(256)); 690 random->nextULessThan(256));
522 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 691 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
523 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 692 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
524 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 693 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
525 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 694 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
526 textures[texIdx2], params2, 695 textures[texIdx2], params2,
527 textColor, 696 textColor,
528 flags); 697 flags);
529 } 698 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDistanceFieldTextureEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698