Index: src/gpu/GrDistanceFieldTextContext.cpp |
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp |
index 2d2f9a14432dd7aae4a719e6469858f30bb8ef84..9634fe88db9e1abefbca6cdd8451b787831856fa 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" |
@@ -33,6 +35,8 @@ static const int kLargeDFFontSize = 128; |
SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, |
"Dump the contents of the font cache before every purge."); |
+GrTexture* gGammaTexture = NULL; |
bsalomon
2014/05/28 19:53:53
This doesn't seem safe. There can be multiple GrCo
jvanverth1
2014/05/29 18:53:49
Changed to be a member of GrDistanceFieldTextConte
|
+ |
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, |
const SkDeviceProperties& properties, |
bool enable) |
@@ -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, |
+ gGammaTexture, |
+ gammaParams, |
+ colorNoPreMul, |
fContext->getMatrix().rectStaysRect() && |
fContext->getMatrix().isSimilarity(), |
useBGR), |
@@ -133,10 +149,15 @@ 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, |
+ U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma, |
+ filteredColor); |
+ drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( |
+ fCurrTexture, params, |
+ gGammaTexture, gammaParams, |
+ lum/255.f, |
fContext->getMatrix().isSimilarity()), |
kGlyphCoordsAttributeIndex)->unref(); |
@@ -354,9 +375,7 @@ inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint |
fUseLCDText = fSkPaint.isLCDRenderText(); |
- fSkPaint.setLCDRenderText(false); |
- fSkPaint.setAutohinted(false); |
- fSkPaint.setSubpixelText(true); |
+ fSkPaint.setDistanceFieldTextTEMP(true); |
} |
inline void GrDistanceFieldTextContext::finish() { |
@@ -365,6 +384,35 @@ inline void GrDistanceFieldTextContext::finish() { |
GrTextContext::finish(); |
} |
+static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, |
+ const SkDeviceProperties& deviceProperties) { |
+ if (!gGammaTexture) { |
reed1
2014/05/28 19:45:17
Seems like we need thread-protection for writing t
jvanverth1
2014/05/29 18:53:49
There should be only one GrDistanceFieldTextContex
|
+ int width, height; |
+ SkScalar contrast = 0.5f; |
+ SkScalar paintGamma = deviceProperties.fGamma; |
+ SkScalar deviceGamma = deviceProperties.fGamma; |
+ void *data = cache->getScalerContext()->getGammaLUTData(width, height, contrast, |
+ paintGamma, deviceGamma); |
+ |
+ // 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; |
+ |
+ gGammaTexture = context->getGpu()->createTexture(desc, NULL, 0); |
+ if (NULL == gGammaTexture) { |
+ return; |
+ } |
+ |
+ context->writeTexturePixels(gGammaTexture, |
+ 0, 0, width, height, |
+ gGammaTexture->config(), data, 0, |
+ GrContext::kDontFlush_PixelOpsFlag); |
+ } |
+} |
+ |
void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, |
const char text[], size_t byteLength, |
SkScalar x, SkScalar y) { |
@@ -386,6 +434,8 @@ void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
+ setup_gamma_texture(fContext, cache, fDeviceProperties); |
+ |
// need to measure first |
// TODO - generate positions and pre-load cache as well? |
const char* stop = text + byteLength; |
@@ -459,6 +509,8 @@ void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
+ setup_gamma_texture(fContext, cache, fDeviceProperties); |
+ |
const char* stop = text + byteLength; |
if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |