diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp index c864edf1d9..6eb94cdbb3 100644 --- a/src/core/SkGlyphRunPainter.cpp +++ b/src/core/SkGlyphRunPainter.cpp @@ -300,21 +300,29 @@ void GrTextContext::drawGlyphRunList( const SkMaskFilter* mf = blobPaint.getMaskFilter(); bool canCache = glyphRunList.canCache() && !(blobPaint.getPathEffect() || (mf && !as_MFB(mf)->asABlur(&blurRec))); + SkScalerContextFlags scalerContextFlags = ComputeScalerContextFlags(colorInfo); + sk_sp cachedBlob; GrTextBlob::Key key; if (canCache) { bool hasLCD = glyphRunList.anyRunsLCD(); + // We canonicalize all non-lcd draws to use kUnknown_SkPixelGeometry + SkPixelGeometry pixelGeometry = hasLCD ? props.pixelGeometry() : + kUnknown_SkPixelGeometry; + // TODO we want to figure out a way to be able to use the canonical color on LCD text, // see the note on ComputeCanonicalColor above. We pick a dummy value for LCD text to // ensure we always match the same key GrColor canonicalColor = hasLCD ? SK_ColorTRANSPARENT : ComputeCanonicalColor(blobPaint, hasLCD); + key.fPixelGeometry = pixelGeometry; key.fUniqueID = glyphRunList.uniqueID(); key.fStyle = blobPaint.getStyle(); key.fHasBlur = SkToBool(mf); key.fCanonicalColor = canonicalColor; + key.fScalerContextFlags = scalerContextFlags; cachedBlob = textBlobCache->find(key); } diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h index 5e3b612a1b..7b4083aec5 100644 --- a/src/gpu/text/GrTextBlob.h +++ b/src/gpu/text/GrTextBlob.h @@ -75,7 +75,9 @@ public: // represents the bucket. This functionality is currently only supported for A8 SkColor fCanonicalColor; SkPaint::Style fStyle; + SkPixelGeometry fPixelGeometry; bool fHasBlur; + uint32_t fScalerContextFlags; bool operator==(const Key& other) const; }; diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index 8924b21881..909ace84f5 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -75,6 +75,17 @@ SkColor GrTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) { return canonicalColor; } +SkScalerContextFlags GrTextContext::ComputeScalerContextFlags(const GrColorInfo& colorInfo) { + // If we're doing linear blending, then we can disable the gamma hacks. + // Otherwise, leave them on. In either case, we still want the contrast boost: + // TODO: Can we be even smarter about mask gamma based on the dest transfer function? + if (colorInfo.isLinearlyBlended()) { + return SkScalerContextFlags::kBoostContrast; + } else { + return SkScalerContextFlags::kFakeGammaAndBoostContrast; + } +} + void GrTextContext::SanitizeOptions(Options* options) { if (options->fMaxDistanceFieldFontSize < 0.f) { options->fMaxDistanceFieldFontSize = kDefaultMaxDistanceFieldFontSize; diff --git a/src/gpu/text/GrTextContext.h b/src/gpu/text/GrTextContext.h index b4640af32e..9d08e3d5dc 100644 --- a/src/gpu/text/GrTextContext.h +++ b/src/gpu/text/GrTextContext.h @@ -79,6 +79,8 @@ private: // sets up the descriptor on the blob and returns a detached cache. Client must attach static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd); + // Determines if we need to use fake gamma (and contrast boost): + static SkScalerContextFlags ComputeScalerContextFlags(const GrColorInfo&); const GrDistanceFieldAdjustTable* dfAdjustTable() const { return fDistanceAdjustTable.get(); }