Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Unified Diff: src/gpu/GrDistanceFieldTextContext.cpp

Issue 1042373002: Emulate gamma fix by making glyphs thicker or thinner (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase to ToT Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrDistanceFieldTextContext.cpp
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index f0915a7555d52d307698e2bd7675723e9fce4c11..fe89cfa606adf5b595f40766e3d09a6f15f25471 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -42,6 +42,11 @@ static const int kLargeDFFontSize = 162;
static const int kVerticesPerGlyph = 4;
static const int kIndicesPerGlyph = 6;
+#ifdef SK_DEBUG
+static const int kExpectedWidthAdjustTableSize = 8;
+#endif
+static const int kWidthAdjustLumShift = 5;
+
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
SkGpuDevice* gpuDevice,
const SkDeviceProperties& properties,
@@ -53,7 +58,7 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
fEnableDFRendering = enable;
#endif
fStrike = NULL;
- fGammaTexture = NULL;
+ fWidthAdjustTable = NULL;
fEffectTextureUniqueID = SK_InvalidUniqueID;
fEffectColor = GrColor_ILLEGAL;
@@ -74,13 +79,62 @@ GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex
bool enable) {
GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextContext,
(context, gpuDevice, props, enable));
+ textContext->buildWidthAdjustTable();
textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, gpuDevice, props);
return textContext;
}
+
+void GrDistanceFieldTextContext::buildWidthAdjustTable() {
+ int width, height;
+ size_t size;
+
+#ifdef SK_GAMMA_CONTRAST
+ SkScalar contrast = SK_GAMMA_CONTRAST;
+#else
+ SkScalar contrast = 0.5f;
+#endif
+ SkScalar paintGamma = fDeviceProperties.gamma();
+ SkScalar deviceGamma = fDeviceProperties.gamma();
+
+ size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
+ &width, &height);
+
+ SkASSERT(kExpectedWidthAdjustTableSize == height);
+ fWidthAdjustTable = SkNEW_ARRAY(SkScalar, height);
+
+ SkAutoTArray<uint8_t> data((int)size);
+ SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
+
+ // find the inverse points where we cross 0.5
+ // binsearch might be better, but we only need to do this once on creation
+ for (int row = 0; row < height; ++row) {
+ uint8_t* rowPtr = data.get() + row*width;
+ for (int col = 0; col < width - 1; ++col) {
+ if (rowPtr[col] <= 127 && rowPtr[col + 1] >= 128) {
+ // compute point where a mask value will give us a result of 0.5
+ float interp = (127.5f - rowPtr[col]) / (rowPtr[col + 1] - rowPtr[col]);
+ float borderAlpha = (col + interp) / 255.f;
+
+ // compute t value for that alpha
+ // this is an approximate inverse for smoothstep()
+ float t = borderAlpha*(borderAlpha*(4.0f*borderAlpha - 6.0f) + 5.0f) / 3.0f;
+
+ // compute distance which gives us that t value
+ float d = 2.0f*0.7071f*t - 0.7071f;
+
+ fWidthAdjustTable[row] = d;
+ break;
+ }
+ }
+ }
+}
+
+
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
- SkSafeSetNull(fGammaTexture);
+ SkDELETE_ARRAY(fWidthAdjustTable);
+ fWidthAdjustTable = NULL;
}
bool GrDistanceFieldTextContext::canDraw(const GrRenderTarget* rt,
@@ -178,45 +232,6 @@ inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& c
fSkPaint.setSubpixelText(true);
}
-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.gamma();
- SkScalar deviceGamma = deviceProperties.gamma();
-
- 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.
- GrSurfaceDesc desc;
- desc.fFlags = kNone_GrSurfaceFlags;
- desc.fWidth = width;
- desc.fHeight = height;
- desc.fConfig = kAlpha_8_GrPixelConfig;
-
- *gammaTexture = context->getGpu()->createTexture(desc, true, NULL, 0);
- if (NULL == *gammaTexture) {
- return;
- }
-
- (*gammaTexture)->writePixels(0, 0, width, height,
- (*gammaTexture)->config(), data.get(), 0,
- GrContext::kDontFlush_PixelOpsFlag);
- }
-}
-
void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
const GrPaint& paint,
const SkPaint& skPaint, const SkMatrix& viewMatrix,
@@ -309,8 +324,6 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip&
SkGlyphCache* cache = autoCache.getCache();
GrFontScaler* fontScaler = GetGrFontScaler(cache);
- setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
-
int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL);
fTotalVertexCount = kVerticesPerGlyph*numGlyphs;
@@ -438,13 +451,22 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
GrColor color = fPaint.getColor();
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
+
+ float redCorrection =
+ fWidthAdjustTable[GrColorUnpackR(colorNoPreMul) >> kWidthAdjustLumShift];
+ float greenCorrection =
+ fWidthAdjustTable[GrColorUnpackG(colorNoPreMul) >> kWidthAdjustLumShift];
+ float blueCorrection =
+ fWidthAdjustTable[GrColorUnpackB(colorNoPreMul) >> kWidthAdjustLumShift];
+ GrDistanceFieldLCDTextureEffect::WidthAdjust widthAdjust =
+ GrDistanceFieldLCDTextureEffect::WidthAdjust::Make(redCorrection,
+ greenCorrection,
+ blueCorrection);
fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color,
fViewMatrix,
fCurrTexture,
params,
- fGammaTexture,
- gammaParams,
- colorNoPreMul,
+ widthAdjust,
flags));
} else {
flags |= kColorAttr_DistanceFieldEffectFlag;
@@ -452,13 +474,12 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
filteredColor);
+ float correction = fWidthAdjustTable[lum >> kWidthAdjustLumShift];
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
fViewMatrix,
fCurrTexture,
params,
- fGammaTexture,
- gammaParams,
- lum/255.f,
+ correction,
flags,
opaque));
#else

Powered by Google App Engine
This is Rietveld 408576698