Add effect caching to distance field text.
This also is a step towards unifying GrDistanceFieldTextureEffect and GrDistanceFieldLCDTextureEffect.
Committed: https://skia.googlesource.com/skia/+/137bac067306c5446bc4f9797bedc3bbaf302822
R=robertphillips@google.com
Author: jvanverth@google.com
Review URL: https://codereview.chromium.org/424103002
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 0ef596a..32d8f0c 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -66,7 +66,10 @@
fGammaTexture = NULL;
fCurrVertex = 0;
-
+ fEffectTextureUniqueID = SK_InvalidUniqueID;
+ fEffectColor = GrColor_ILLEGAL;
+ fEffectFlags = 0;
+
fVertices = NULL;
}
@@ -111,6 +114,58 @@
return GrColorPackRGBA(r, g, b, 0xff);
}
+void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColor) {
+ GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
+ GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
+
+ GrTexture* currTexture = fStrike->getTexture();
+ SkASSERT(currTexture);
+ uint32_t textureUniqueID = currTexture->getUniqueID();
+
+ // set up any flags
+ uint32_t flags = 0;
+ flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0;
+ flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ?
+ kRectToRect_DistanceFieldEffectFlag : 0;
+ bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
+ fDeviceProperties.fGeometry.getLayout();
+ flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0;
+
+ // see if we need to create a new effect
+ if (textureUniqueID != fEffectTextureUniqueID ||
+ filteredColor != fEffectColor ||
+ flags != fEffectFlags) {
+ if (fUseLCDText) {
+ GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
+ fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(currTexture,
+ params,
+ fGammaTexture,
+ gammaParams,
+ colorNoPreMul,
+ flags));
+ } else {
+#ifdef SK_GAMMA_APPLY_TO_A8
+ U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma,
+ filteredColor);
+ fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture,
+ params,
+ fGammaTexture,
+ gammaParams,
+ lum/255.f,
+ flags));
+#else
+ fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture,
+ params, flags));
+#endif
+ }
+ fEffectTextureUniqueID = textureUniqueID;
+ fEffectColor = filteredColor;
+ fEffectFlags = flags;
+ }
+
+}
+
void GrDistanceFieldTextContext::flushGlyphs() {
if (NULL == fDrawTarget) {
return;
@@ -123,14 +178,8 @@
if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas
SkASSERT(SkIsAlign4(fCurrVertex));
- GrTexture* currTexture = fStrike->getTexture();
- SkASSERT(currTexture);
- GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
- GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
- // Effects could be stored with one of the cache objects (atlas?)
- int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex :
- kGlyphCoordsNoColorAttributeIndex;
+ // get our current color
SkColor filteredColor;
SkColorFilter* colorFilter = fSkPaint.getColorFilter();
if (NULL != colorFilter) {
@@ -138,21 +187,16 @@
} else {
filteredColor = fSkPaint.getColor();
}
+ this->setupCoverageEffect(filteredColor);
+
+ // Effects could be stored with one of the cache objects (atlas?)
+ int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex :
+ kGlyphCoordsNoColorAttributeIndex;
+ drawState->addCoverageEffect(fCachedEffect.get(), coordsIdx);
+
+ // Set draw state
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
- bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
- fDeviceProperties.fGeometry.getLayout();
- drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create(
- currTexture,
- params,
- fGammaTexture,
- gammaParams,
- colorNoPreMul,
- fContext->getMatrix().rectStaysRect() &&
- fContext->getMatrix().isSimilarity(),
- useBGR),
- coordsIdx)->unref();
-
if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
fPaint.numColorStages()) {
@@ -170,21 +214,6 @@
drawState->setBlendConstant(colorNoPreMul);
drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
} else {
-#ifdef SK_GAMMA_APPLY_TO_A8
- U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma,
- filteredColor);
- drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
- currTexture, params,
- fGammaTexture, gammaParams,
- lum/255.f,
- fContext->getMatrix().isSimilarity()),
- coordsIdx)->unref();
-#else
- drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
- currTexture, params,
- fContext->getMatrix().isSimilarity()),
- coordsIdx)->unref();
-#endif
// set back to normal in case we took LCD path previously.
drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
//drawState->setColor(fPaint.getColor());