From 90e89b366a7dc90111c861ba76c492ce1743a0d1 Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Thu, 6 Jul 2017 16:36:55 -0400 Subject: Add proper aliased support for SDF text Previously, when asked to render aliased text with distance fields, we would get the aliased glyph from the cache and then try to anti-alias the edge. This change instead grabs the anti-aliased glyph, then deliberately aliases the edge. Bug: chromium:707979 Change-Id: I05766af17d7ae58bca27aaffd9e08e5c586e789c Reviewed-on: https://skia-review.googlesource.com/21728 Commit-Queue: Jim Van Verth Reviewed-by: Brian Salomon --- src/gpu/effects/GrDistanceFieldGeoProc.cpp | 12 ++++++++---- src/gpu/effects/GrDistanceFieldGeoProc.h | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/gpu/effects') diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index f0f4ec4fa3..c8dd4ebd77 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -77,6 +77,8 @@ public: bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); bool isGammaCorrect = SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag); + bool isAliased = + SkToBool(dfTexEffect.getFlags() & kAliased_DistanceFieldEffectFlag); varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName); @@ -158,10 +160,12 @@ public: fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); } - // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are - // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want distance - // mapped linearly to coverage, so use a linear step: - if (isGammaCorrect) { + if (isAliased) { + fragBuilder->codeAppend("float val = distance > 0 ? 1.0 : 0.0;"); + } else if (isGammaCorrect) { + // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are + // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want + // distance mapped linearly to coverage, so use a linear step: fragBuilder->codeAppend( "float val = clamp((distance + afwidth) / (2.0 * afwidth), 0.0, 1.0);"); } else { diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h index 3f616e9480..344ac4a092 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.h +++ b/src/gpu/effects/GrDistanceFieldGeoProc.h @@ -23,6 +23,7 @@ enum GrDistanceFieldEffectFlags { kBGR_DistanceFieldEffectFlag = 0x08, // lcd display has bgr order kPortrait_DistanceFieldEffectFlag = 0x10, // lcd display is in portrait mode (not used yet) kGammaCorrect_DistanceFieldEffectFlag = 0x20, // assume gamma-correct output (linear blending) + kAliased_DistanceFieldEffectFlag = 0x40, // monochrome output kInvalid_DistanceFieldEffectFlag = 0x80, // invalid state (for initialization) @@ -31,7 +32,8 @@ enum GrDistanceFieldEffectFlags { // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc kNonLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | kScaleOnly_DistanceFieldEffectFlag | - kGammaCorrect_DistanceFieldEffectFlag, + kGammaCorrect_DistanceFieldEffectFlag | + kAliased_DistanceFieldEffectFlag, // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc kLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | kScaleOnly_DistanceFieldEffectFlag | -- cgit v1.2.3