| Index: src/gpu/GrBitmapTextContext.cpp
|
| diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
|
| index 744d97f4268a9e6c75769b3a8e4abb791b2f26fb..a3e9cb3d794905ce6e673dbd21ac3453585740a5 100755
|
| --- a/src/gpu/GrBitmapTextContext.cpp
|
| +++ b/src/gpu/GrBitmapTextContext.cpp
|
| @@ -24,11 +24,28 @@
|
| #include "SkGpuDevice.h"
|
| #include "SkGr.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;
|
| +
|
| +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}
|
| +};
|
| +
|
| +};
|
| +
|
| GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
|
| const SkDeviceProperties& properties)
|
| : GrTextContext(context, properties) {
|
| @@ -76,35 +93,52 @@ void GrBitmapTextContext::flushGlyphs() {
|
| GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
|
|
|
| // This effect could be stored with one of the cache objects (atlas?)
|
| + int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex :
|
| + kGlyphCoordsNoColorAttributeIndex;
|
| drawState->addCoverageEffect(
|
| GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
|
| - kGlyphCoordsAttributeIndex)->unref();
|
| -
|
| - if (NULL != fStrike && kARGB_GrMaskFormat == fStrike->getMaskFormat()) {
|
| - drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
|
| - drawState->setColor(0xffffffff);
|
| - } else if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
|
| - if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
|
| - kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
|
| - fPaint.numColorStages()) {
|
| - GrPrintf("LCD Text will not draw correctly.\n");
|
| + coordsIdx)->unref();
|
| + SkASSERT(NULL != fStrike);
|
| + switch (fStrike->getMaskFormat()) {
|
| + // Color bitmap text
|
| + case kARGB_GrMaskFormat:
|
| + SkASSERT(!drawState->hasColorVertexAttribute());
|
| + drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
|
| + drawState->setColor(0xffffffff);
|
| + break;
|
| + // LCD text
|
| + case kA888_GrMaskFormat:
|
| + case kA565_GrMaskFormat: {
|
| + 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
|
| + // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
|
| + int a = SkColorGetA(fSkPaint.getColor());
|
| + // paintAlpha
|
| + drawState->setColor(SkColorSetARGB(a, a, a, a));
|
| + // paintColor
|
| + drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
|
| + drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
|
| + break;
|
| }
|
| - // 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
|
| - // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
|
| - int a = SkColorGetA(fSkPaint.getColor());
|
| - // paintAlpha
|
| - drawState->setColor(SkColorSetARGB(a, a, a, a));
|
| - // paintColor
|
| - drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
|
| - drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
|
| - } else {
|
| - // set back to normal in case we took LCD path previously.
|
| - drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
|
| - drawState->setColor(fPaint.getColor());
|
| + // Grayscale/BW text
|
| + case kA8_GrMaskFormat:
|
| + // set back to normal in case we took LCD path previously.
|
| + drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
|
| + //drawState->setColor(fPaint.getColor());
|
| + // We're using per-vertex color.
|
| + SkASSERT(drawState->hasColorVertexAttribute());
|
| + drawState->setColor(0xFFFFFFFF);
|
| + break;
|
| + default:
|
| + SkFAIL("Unexepected mask format.");
|
| }
|
| -
|
| int nGlyphs = fCurrVertex / 4;
|
| fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
|
| fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
|
| @@ -133,7 +167,7 @@ inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPai
|
| }
|
|
|
| inline void GrBitmapTextContext::finish() {
|
| - flushGlyphs();
|
| + this->flushGlyphs();
|
|
|
| GrTextContext::finish();
|
| }
|
| @@ -472,16 +506,6 @@ void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
|
| this->finish();
|
| }
|
|
|
| -namespace {
|
| -
|
| -// position + texture coord
|
| -extern const GrVertexAttrib gTextVertexAttribs[] = {
|
| - {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
| - {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
|
| -};
|
| -
|
| -};
|
| -
|
| void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
| SkFixed vx, SkFixed vy,
|
| GrFontScaler* scaler) {
|
| @@ -581,18 +605,30 @@ HAS_ATLAS:
|
| fCurrTexture->ref();
|
| }
|
|
|
| + bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat();
|
| +
|
| if (NULL == fVertices) {
|
| // If we need to reserve vertices allow the draw target to suggest
|
| // a number of verts to reserve and whether to perform a flush.
|
| fMaxVertices = kMinRequestedVerts;
|
| - fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
|
| - SK_ARRAY_COUNT(gTextVertexAttribs));
|
| + if (useColorVerts) {
|
| + fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
|
| + SK_ARRAY_COUNT(gTextVertexWithColorAttribs));
|
| + } else {
|
| + fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
|
| + SK_ARRAY_COUNT(gTextVertexAttribs));
|
| + }
|
| bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
|
| if (flush) {
|
| this->flushGlyphs();
|
| fContext->flush();
|
| - fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
|
| - SK_ARRAY_COUNT(gTextVertexAttribs));
|
| + if (useColorVerts) {
|
| + fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
|
| + SK_ARRAY_COUNT(gTextVertexWithColorAttribs));
|
| + } else {
|
| + fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
|
| + SK_ARRAY_COUNT(gTextVertexAttribs));
|
| + }
|
| }
|
| fMaxVertices = kDefaultRequestedVerts;
|
| // ignore return, no point in flushing again.
|
| @@ -607,10 +643,9 @@ HAS_ATLAS:
|
| }
|
| bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
|
| 0,
|
| - GrTCast<void**>(&fVertices),
|
| + &fVertices,
|
| NULL);
|
| GrAlwaysAssert(success);
|
| - SkASSERT(2*sizeof(SkPoint) == fDrawTarget->getDrawState().getVertexSize());
|
| }
|
|
|
| SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
|
| @@ -624,12 +659,30 @@ HAS_ATLAS:
|
|
|
| fVertexBounds.growToInclude(r);
|
|
|
| - fVertices[2*fCurrVertex].setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom,
|
| - 2 * sizeof(SkPoint));
|
| - fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
|
| - SkFixedToFloat(texture->normalizeFixedY(ty)),
|
| - SkFixedToFloat(texture->normalizeFixedX(tx + width)),
|
| - SkFixedToFloat(texture->normalizeFixedY(ty + height)),
|
| - 2 * sizeof(SkPoint));
|
| + size_t vertSize = useColorVerts ? (2 * sizeof(SkPoint) + sizeof(GrColor)) :
|
| + (2 * sizeof(SkPoint));
|
| +
|
| + SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexSize());
|
| +
|
| + SkPoint* positions = reinterpret_cast<SkPoint*>(
|
| + reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
|
| + positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, 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) + vertSize - sizeof(SkPoint));
|
| + textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
|
| + SkFixedToFloat(texture->normalizeFixedY(ty)),
|
| + SkFixedToFloat(texture->normalizeFixedX(tx + width)),
|
| + SkFixedToFloat(texture->normalizeFixedY(ty + height)),
|
| + vertSize);
|
| + if (useColorVerts) {
|
| + // 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;
|
| }
|
|
|