diff options
author | jvanverth <jvanverth@google.com> | 2014-07-25 19:03:34 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-07-25 19:03:34 -0700 |
commit | feceba5e2d4504adbf4bca963c175fcc60be1d58 (patch) | |
tree | e626c2258478abf60e120cab2ab4d6f791b5007b /src | |
parent | f17bc6cf7ae4b6483ff3a5f52b0672e4243011e3 (diff) |
Add vertex color support to distance field text.
BUG=skia:
R=bsalomon@google.com
Author: jvanverth@google.com
Review URL: https://codereview.chromium.org/421563002
Diffstat (limited to 'src')
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 103 |
1 files changed, 68 insertions, 35 deletions
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 8827382b75..0ef596a27b 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -25,7 +25,11 @@ #include "SkStrokeRec.h" #include "effects/GrDistanceFieldTextureEffect.h" -static const int kGlyphCoordsAttributeIndex = 1; +SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, + "Dump the contents of the font cache before every purge."); + +static const int kGlyphCoordsNoColorAttributeIndex = 1; +static const int kGlyphCoordsWithColorAttributeIndex = 2; static const int kSmallDFFontSize = 32; static const int kSmallDFFontLimit = 32; @@ -33,8 +37,21 @@ static const int kMediumDFFontSize = 64; static const int kMediumDFFontLimit = 64; static const int kLargeDFFontSize = 128; -SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, - "Dump the contents of the font cache before every purge."); +namespace { +// position + texture coord +extern const GrVertexAttrib gTextVertexAttribs[] = { + {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, + {kVec2f_GrVertexAttribType, sizeof(SkPoint) , kEffect_GrVertexAttribBinding} +}; + +// position + color + texture coord +extern const GrVertexAttrib gTextVertexWithColorAttribs[] = { + {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, + {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding}, + {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kEffect_GrVertexAttribBinding} +}; + +}; GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, const SkDeviceProperties& properties, @@ -112,6 +129,8 @@ void GrDistanceFieldTextContext::flushGlyphs() { GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode); // Effects could be stored with one of the cache objects (atlas?) + int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex : + kGlyphCoordsNoColorAttributeIndex; SkColor filteredColor; SkColorFilter* colorFilter = fSkPaint.getColorFilter(); if (NULL != colorFilter) { @@ -132,13 +151,14 @@ void GrDistanceFieldTextContext::flushGlyphs() { fContext->getMatrix().rectStaysRect() && fContext->getMatrix().isSimilarity(), useBGR), - kGlyphCoordsAttributeIndex)->unref(); + coordsIdx)->unref(); if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { GrPrintf("LCD Text will not draw correctly.\n"); } + SkASSERT(!drawState->hasColorVertexAttribute()); // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get @@ -158,18 +178,20 @@ void GrDistanceFieldTextContext::flushGlyphs() { fGammaTexture, gammaParams, lum/255.f, fContext->getMatrix().isSimilarity()), - kGlyphCoordsAttributeIndex)->unref(); + coordsIdx)->unref(); #else drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create( currTexture, params, fContext->getMatrix().isSimilarity()), - kGlyphCoordsAttributeIndex)->unref(); + coordsIdx)->unref(); #endif // set back to normal in case we took LCD path previously. drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); - drawState->setColor(fPaint.getColor()); + //drawState->setColor(fPaint.getColor()); + // We're using per-vertex color. + SkASSERT(drawState->hasColorVertexAttribute()); + drawState->setColor(0xFFFFFFFF); } - int nGlyphs = fCurrVertex / 4; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, @@ -181,16 +203,6 @@ void GrDistanceFieldTextContext::flushGlyphs() { fVertices = NULL; } -namespace { - -// position + texture coord -extern const GrVertexAttrib gTextVertexAttribs[] = { - {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, - {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} -}; - -}; - void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, SkFixed vx, SkFixed vy, GrFontScaler* scaler) { @@ -294,21 +306,32 @@ HAS_ATLAS: SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset); - static const size_t kVertexSize = 2 * sizeof(SkPoint); + size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint)) + : (2 * sizeof(SkPoint) + sizeof(GrColor)); + + SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexSize()); + SkPoint* positions = reinterpret_cast<SkPoint*>( - reinterpret_cast<intptr_t>(fVertices) + kVertexSize * fCurrVertex); - positions->setRectFan(sx, - sy, - sx + width, - sy + height, - kVertexSize); + reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex); + positions->setRectFan(sx, sy, sx + width, sy + height, vertSize); + + // The texture coords are last in both the with and without color vertex layouts. SkPoint* textureCoords = reinterpret_cast<SkPoint*>( - reinterpret_cast<intptr_t>(positions) + kVertexSize - sizeof(SkPoint)); + reinterpret_cast<intptr_t>(positions) + vertSize - sizeof(SkPoint)); textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), - SkFixedToFloat(texture->normalizeFixedY(ty)), - SkFixedToFloat(texture->normalizeFixedX(tx + tw)), - SkFixedToFloat(texture->normalizeFixedY(ty + th)), - kVertexSize); + SkFixedToFloat(texture->normalizeFixedY(ty)), + SkFixedToFloat(texture->normalizeFixedX(tx + tw)), + SkFixedToFloat(texture->normalizeFixedY(ty + th)), + vertSize); + if (!fUseLCDText) { + // color comes after position. + GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); + for (int i = 0; i < 4; ++i) { + *colors = fPaint.getColor(); + colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors) + vertSize); + } + } + fCurrVertex += 4; } @@ -342,7 +365,7 @@ inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint } inline void GrDistanceFieldTextContext::finish() { - flushGlyphs(); + this->flushGlyphs(); GrTextContext::finish(); } @@ -419,8 +442,13 @@ void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s // allocate vertices SkASSERT(NULL == fVertices); - fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( - SK_ARRAY_COUNT(gTextVertexAttribs)); + if (!fUseLCDText) { + fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( + SK_ARRAY_COUNT(gTextVertexWithColorAttribs)); + } else { + fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( + SK_ARRAY_COUNT(gTextVertexAttribs)); + } int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, 0, @@ -510,8 +538,13 @@ void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint // allocate vertices SkASSERT(NULL == fVertices); - fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( - SK_ARRAY_COUNT(gTextVertexAttribs)); + if (!fUseLCDText) { + fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( + SK_ARRAY_COUNT(gTextVertexWithColorAttribs)); + } else { + fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( + SK_ARRAY_COUNT(gTextVertexAttribs)); + } int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); bool success = fDrawTarget->reserveVertexAndIndexSpace(4*numGlyphs, 0, |