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

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: Some fixes and clean up 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
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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 #ifdef SK_GAMMA_APPLY_TO_A8 254 #ifdef SK_GAMMA_APPLY_TO_A8
255 textures[texIdx2], params2, 255 textures[texIdx2], params2,
256 random->nextF(), 256 random->nextF(),
257 #endif 257 #endif
258 random->nextBool() ? 258 random->nextBool() ?
259 kSimilarity_DistanceFieldEff ectFlag : 0); 259 kSimilarity_DistanceFieldEff ectFlag : 0);
260 } 260 }
261 261
262 /////////////////////////////////////////////////////////////////////////////// 262 ///////////////////////////////////////////////////////////////////////////////
263 263
264 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
265 public:
266 GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& facto ry,
267 const GrProcessor& effect)
268 : INHERITED(factory)
269 , fTextureSize(SkISize::Make(-1, -1)) {}
270
271 virtual void emitCode(GrGLFullProgramBuilder* builder,
272 const GrGeometryProcessor& effect,
273 const GrProcessorKey& key,
274 const char* outputColor,
275 const char* inputColor,
276 const TransformedCoordsArray&,
277 const TextureSamplerArray& samplers) SK_OVERRIDE {
278 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
279 effect.cast<GrDistanceFieldNoGam maTextureEffect>();
280 SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
281
282 GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShad erBuilder();
283 SkAssertResult(fsBuilder->enableFeature(
284 GrGLFragmentShaderBuilder::kStandardDerivat ives_GLSLFeature));
285
286 SkString fsCoordName;
287 const char* vsCoordName;
288 const char* fsCoordNamePtr;
289 builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsC oordNamePtr);
290 fsCoordName = fsCoordNamePtr;
291
292 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
293 vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoo rds().c_str());
294
295 const char* textureSizeUniName = NULL;
296 fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visi bility,
297 kVec2f_GrSLType, "TextureSize",
298 &textureSizeUniName);
299
300 fsBuilder->codeAppend("vec4 texColor = ");
301 fsBuilder->appendTextureLookup(samplers[0],
302 fsCoordName.c_str(),
303 kVec2f_GrSLType);
304 fsBuilder->codeAppend(";");
305 fsBuilder->codeAppend("float distance = "
306 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho ld ");");
307
308 // we adjust for the effect of the transformation on the distance by usi ng
309 // the length of the gradient of the texture coordinates. We use st coor dinates
310 // to ensure we're mapping 1:1 from texel space to pixel space.
311 fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str());
312 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
313 fsBuilder->codeAppend("float afwidth;");
314 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
315 // this gives us a smooth step across approximately one fragment
316 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF dx(st.x));");
317 }
robertphillips 2014/10/03 19:23:40 move to prior line ?
318 else {
319 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
320 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
321
322 fsBuilder->codeAppend("vec2 uv_grad;");
323 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
324 // this is to compensate for the Adreno, which likes to drop til es on division by 0
325 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
326 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
327 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
328 fsBuilder->codeAppend("} else {");
329 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
330 fsBuilder->codeAppend("}");
331 }
robertphillips 2014/10/03 19:23:40 move to prior line ?
332 else {
333 fsBuilder->codeAppend("uv_grad = normalize(uv);");
334 }
335 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y* Jdy.x,");
336 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y* Jdy.y);");
337
338 // this gives us a smooth step across approximately one fragment
339 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length (grad);");
340 }
341 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc e);");
342
343 fsBuilder->codeAppendf("%s = %s;", outputColor,
344 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str());
345 }
346
347 virtual void setData(const GrGLProgramDataManager& pdman,
robertphillips 2014/10/03 19:23:40 add ' ' before '{' ?
348 const GrProcessor& effect) SK_OVERRIDE{
349 SkASSERT(fTextureSizeUni.isValid());
350
351 GrTexture* texture = effect.texture(0);
352 if (texture->width() != fTextureSize.width() ||
353 texture->height() != fTextureSize.height()) {
354 fTextureSize = SkISize::Make(texture->width(), texture->height());
355 pdman.set2f(fTextureSizeUni,
356 SkIntToScalar(fTextureSize.width()),
357 SkIntToScalar(fTextureSize.height()));
358 }
359 }
360
361 static inline void GenKey(const GrProcessor& effect, const GrGLCaps&,
362 GrProcessorKeyBuilder* b) {
363 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
364 effect.cast<GrDistanceFieldNoGammaTextureEffect>();
365
366 b->add32(dfTexEffect.getFlags());
367 }
368
369 private:
370 GrGLProgramDataManager::UniformHandle fTextureSizeUni;
371 SkISize fTextureSize;
372
373 typedef GrGLGeometryProcessor INHERITED;
374 };
375
376 ///////////////////////////////////////////////////////////////////////////////
377
378 GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTextu re* texture,
379 const GrText ureParams& params,
380 uint32_t fla gs)
381 : fTextureAccess(texture, params)
382 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
383 , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
384 kVec2f_GrSLType,
385 GrShaderVar::kAttribute_TypeModifier))) {
386 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
387 this->addTextureAccess(&fTextureAccess);
388 }
389
390 bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrProcessor& other) co nst {
391 const GrDistanceFieldNoGammaTextureEffect& cte =
392 other.cast<GrDistanceFieldNoGam maTextureEffect>();
393 return fTextureAccess == cte.fTextureAccess && fFlags == cte.fFlags;
394 }
395
396 void GrDistanceFieldNoGammaTextureEffect::getConstantColorComponents(GrColor* co lor,
397 uint32_t* v alidFlags) const {
398 if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color ) &&
399 GrPixelConfigIsOpaque(this->texture(0)->config())) {
400 *validFlags = kA_GrColorComponentFlag;
401 } else {
402 *validFlags = 0;
403 }
404 }
405
406 const GrBackendGeometryProcessorFactory& GrDistanceFieldNoGammaTextureEffect::ge tFactory() const {
407 return GrTBackendGeometryProcessorFactory<GrDistanceFieldNoGammaTextureEffec t>::getInstance();
408 }
409
410 ///////////////////////////////////////////////////////////////////////////////
411
412 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect);
413
414 GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r andom,
415 GrContext*,
416 const GrDra wTargetCaps&,
417 GrTexture* textures[]) {
418 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
419 : GrProcessorUnitTest::kAlphaTextureIdx;
420 static const SkShader::TileMode kTileModes[] = {
421 SkShader::kClamp_TileMode,
422 SkShader::kRepeat_TileMode,
423 SkShader::kMirror_TileMode,
424 };
425 SkShader::TileMode tileModes[] = {
426 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
427 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
428 };
429 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil erp_FilterMode
430 : GrTextureParams::kNon e_FilterMode);
431
432 return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params,
robertphillips 2014/10/03 19:23:40 fix indent here ?
433 random->nextBool() ?
434 kSimilarity_DistanceFieldEffectFlag : 0);
435 }
436
437 ///////////////////////////////////////////////////////////////////////////////
438
264 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 439 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
265 public: 440 public:
266 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, 441 GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory,
267 const GrProcessor&) 442 const GrProcessor&)
268 : INHERITED (factory) 443 : INHERITED (factory)
269 , fTextureSize(SkISize::Make(-1,-1)) 444 , fTextureSize(SkISize::Make(-1,-1))
270 , fTextColor(GrColor_ILLEGAL) {} 445 , fTextColor(GrColor_ILLEGAL) {}
271 446
272 virtual void emitCode(GrGLFullProgramBuilder* builder, 447 virtual void emitCode(GrGLFullProgramBuilder* builder,
273 const GrGeometryProcessor& geometryProcessor, 448 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 515 // 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. 516 // to ensure we're mapping 1:1 from texel space to pixel space.
342 517
343 // To be strictly correct, we should compute the anti-aliasing factor se parately 518 // 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 519 // 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 520 // transformations, and even then using a single factor seems like a rea sonable
346 // trade-off between quality and speed. 521 // trade-off between quality and speed.
347 fsBuilder->codeAppend("\tfloat afwidth;\n"); 522 fsBuilder->codeAppend("\tfloat afwidth;\n");
348 if (isUniformScale) { 523 if (isUniformScale) {
349 // this gives us a smooth step across approximately one fragment 524 // this gives us a smooth step across approximately one fragment
350 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\ n"); 525 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "* dx);\n");
351 } else { 526 } else {
352 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 527 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
353 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 528 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
354 // this is to compensate for the Adreno, which likes to drop til es on division by 0 529 // 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"); 530 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
356 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 531 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
357 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 532 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
358 fsBuilder->codeAppend("\t} else {\n"); 533 fsBuilder->codeAppend("\t} else {\n");
359 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" ); 534 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n" );
360 fsBuilder->codeAppend("\t}\n"); 535 fsBuilder->codeAppend("\t}\n");
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 random->nextULessThan(256), 695 random->nextULessThan(256),
521 random->nextULessThan(256)); 696 random->nextULessThan(256));
522 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 697 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
523 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 698 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
524 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 699 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
525 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 700 return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
526 textures[texIdx2], params2, 701 textures[texIdx2], params2,
527 textColor, 702 textColor,
528 flags); 703 flags);
529 } 704 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698