Index: src/gpu/GrDistanceFieldTextContext.cpp |
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp |
index 2d2f9a14432dd7aae4a719e6469858f30bb8ef84..a7299393bdaa729da726e916e97e86c29d43b2e0 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; |