diff options
Diffstat (limited to 'src/gpu/GrDistanceFieldTextContext.cpp')
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 91 |
1 files changed, 82 insertions, 9 deletions
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 2d2f9a1443..a7299393bd 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -7,10 +7,12 @@ #include "GrDistanceFieldTextContext.h" #include "GrAtlas.h" +#include "SkColorFilter.h" #include "GrDrawTarget.h" #include "GrDrawTargetCaps.h" #include "GrFontScaler.h" #include "SkGlyphCache.h" +#include "GrGpu.h" #include "GrIndexBuffer.h" #include "GrTextStrike.h" #include "GrTextStrike_impl.h" @@ -43,6 +45,7 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, fEnableDFRendering = enable; #endif fStrike = NULL; + fGammaTexture = NULL; fCurrTexture = NULL; fCurrVertex = 0; @@ -53,6 +56,7 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { this->flushGlyphs(); + SkSafeSetNull(fGammaTexture); } bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { @@ -107,14 +111,26 @@ void GrDistanceFieldTextContext::flushGlyphs() { SkASSERT(SkIsAlign4(fCurrVertex)); SkASSERT(fCurrTexture); 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?) + SkColor filteredColor; + SkColorFilter* colorFilter = fSkPaint.getColorFilter(); + if (NULL != colorFilter) { + filteredColor = colorFilter->filterColor(fSkPaint.getColor()); + } else { + filteredColor = fSkPaint.getColor(); + } if (fUseLCDText) { + GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout == fDeviceProperties.fGeometry.getLayout(); drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create( fCurrTexture, params, + fGammaTexture, + gammaParams, + colorNoPreMul, fContext->getMatrix().rectStaysRect() && fContext->getMatrix().isSimilarity(), useBGR), @@ -133,13 +149,24 @@ void GrDistanceFieldTextContext::flushGlyphs() { // paintAlpha drawState->setColor(SkColorSetARGB(a, a, a, a)); // paintColor - drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor())); + drawState->setBlendConstant(colorNoPreMul); drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); } else { - drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(fCurrTexture, params, +#ifdef SK_GAMMA_APPLY_TO_A8 + U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma, + filteredColor); + drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( + fCurrTexture, params, + fGammaTexture, gammaParams, + lum/255.f, fContext->getMatrix().isSimilarity()), kGlyphCoordsAttributeIndex)->unref(); - +#else + drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( + fCurrTexture, params, + fContext->getMatrix().isSimilarity()), + kGlyphCoordsAttributeIndex)->unref(); +#endif // set back to normal in case we took LCD path previously. drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); drawState->setColor(fPaint.getColor()); @@ -356,7 +383,9 @@ inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint fSkPaint.setLCDRenderText(false); fSkPaint.setAutohinted(false); + fSkPaint.setHinting(SkPaint::kNormal_Hinting); fSkPaint.setSubpixelText(true); + } inline void GrDistanceFieldTextContext::finish() { @@ -365,6 +394,46 @@ inline void GrDistanceFieldTextContext::finish() { GrTextContext::finish(); } +static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, + const SkDeviceProperties& deviceProperties, + GrTexture** gammaTexture) { + if (NULL == *gammaTexture) { + int width, height; + size_t size; + +#ifdef SK_GAMMA_CONTRAST + SkScalar contrast = SK_GAMMA_CONTRAST; +#else + SkScalar contrast = 0.5f; +#endif + SkScalar paintGamma = deviceProperties.fGamma; + SkScalar deviceGamma = deviceProperties.fGamma; + + size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma, + &width, &height); + + SkAutoTArray<uint8_t> data((int)size); + SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get()); + + // TODO: Update this to use the cache rather than directly creating a texture. + GrTextureDesc desc; + desc.fFlags = kDynamicUpdate_GrTextureFlagBit; + desc.fWidth = width; + desc.fHeight = height; + desc.fConfig = kAlpha_8_GrPixelConfig; + + *gammaTexture = context->getGpu()->createTexture(desc, NULL, 0); + if (NULL == *gammaTexture) { + return; + } + + context->writeTexturePixels(*gammaTexture, + 0, 0, width, height, + (*gammaTexture)->config(), data.get(), 0, + GrContext::kDontFlush_PixelOpsFlag); + } +} + void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, SkScalar x, SkScalar y) { @@ -382,9 +451,11 @@ void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); - SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL); - SkGlyphCache* cache = autoCache.getCache(); - GrFontScaler* fontScaler = GetGrFontScaler(cache); + SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); + SkGlyphCache* cache = autoCache.getCache(); + GrFontScaler* fontScaler = GetGrFontScaler(cache); + + setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); // need to measure first // TODO - generate positions and pre-load cache as well? @@ -455,9 +526,11 @@ void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); - SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL); - SkGlyphCache* cache = autoCache.getCache(); - GrFontScaler* fontScaler = GetGrFontScaler(cache); + SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); + SkGlyphCache* cache = autoCache.getCache(); + GrFontScaler* fontScaler = GetGrFontScaler(cache); + + setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); const char* stop = text + byteLength; |