aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDistanceFieldTextContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrDistanceFieldTextContext.cpp')
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp91
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;