aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-16 18:15:34 +0000
committerGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-16 18:15:34 +0000
commitc7a40fad0b4c243087ad1adb14ebc2184d42cac0 (patch)
tree0221bd972c7e7b7d7df8571762dee010f3c026b6 /src
parent3f1f2a3a59c43e5bce67ab98e55df45bc7c933a3 (diff)
Split out GrBitmapTextContext from GrTextContext.
This is a stepping stone to having a variety of different text context types (bitmaps, distance fields, NV path rendering). R=bsalomon@google.com Review URL: https://codereview.chromium.org/27199002 git-svn-id: http://skia.googlecode.com/svn/trunk@11820 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp248
-rw-r--r--src/gpu/GrTextContext.cpp241
-rw-r--r--src/gpu/SkGpuDevice.cpp6
3 files changed, 251 insertions, 244 deletions
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
new file mode 100755
index 0000000000..7a99f093e5
--- /dev/null
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrBitmapTextContext.h"
+#include "GrAtlas.h"
+#include "GrDrawTarget.h"
+#include "GrFontScaler.h"
+#include "GrIndexBuffer.h"
+#include "GrTextStrike.h"
+#include "GrTextStrike_impl.h"
+#include "SkPath.h"
+#include "SkRTConf.h"
+#include "SkStrokeRec.h"
+#include "effects/GrCustomCoordsTextureEffect.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.");
+
+GrBitmapTextContext::GrBitmapTextContext(GrContext* context, const GrPaint& paint) :
+ GrTextContext(context, paint) {
+ fAutoMatrix.setIdentity(fContext, &fPaint);
+
+ fStrike = NULL;
+
+ fCurrTexture = NULL;
+ fCurrVertex = 0;
+
+ fVertices = NULL;
+ fMaxVertices = 0;
+}
+
+GrBitmapTextContext::~GrBitmapTextContext() {
+ this->flushGlyphs();
+}
+
+void GrBitmapTextContext::flushGlyphs() {
+ if (NULL == fDrawTarget) {
+ return;
+ }
+
+ GrDrawState* drawState = fDrawTarget->drawState();
+ GrDrawState::AutoRestoreEffects are(drawState);
+ drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
+
+ if (fCurrVertex > 0) {
+ // setup our sampler state for our text texture/atlas
+ SkASSERT(GrIsALIGN4(fCurrVertex));
+ SkASSERT(fCurrTexture);
+ GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
+
+ // This effect could be stored with one of the cache objects (atlas?)
+ drawState->addCoverageEffect(
+ GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
+ kGlyphCoordsAttributeIndex)->unref();
+
+ if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
+ if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
+ kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
+ fPaint.numColorStages()) {
+ GrPrintf("LCD Text will not draw correctly.\n");
+ }
+ // setup blend so that we get mask * paintColor + (1-mask)*dstColor
+ drawState->setBlendConstant(fPaint.getColor());
+ drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
+ // don't modulate by the paint's color in the frag since we're
+ // already doing it via the blend const.
+ drawState->setColor(0xffffffff);
+ } else {
+ // set back to normal in case we took LCD path previously.
+ drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState->setColor(fPaint.getColor());
+ }
+
+ int nGlyphs = fCurrVertex / 4;
+ fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
+ fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
+ nGlyphs,
+ 4, 6);
+ fDrawTarget->resetVertexSource();
+ fVertices = NULL;
+ fMaxVertices = 0;
+ fCurrVertex = 0;
+ SkSafeSetNull(fCurrTexture);
+ }
+}
+
+namespace {
+
+// position + texture coord
+extern const GrVertexAttrib gTextVertexAttribs[] = {
+ {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
+ {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
+};
+
+};
+
+void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
+ GrFixed vx, GrFixed vy,
+ GrFontScaler* scaler) {
+ if (NULL == fDrawTarget) {
+ return;
+ }
+ if (NULL == fStrike) {
+ fStrike = fContext->getFontCache()->getStrike(scaler);
+ }
+
+ GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
+ if (NULL == glyph || glyph->fBounds.isEmpty()) {
+ return;
+ }
+
+ vx += SkIntToFixed(glyph->fBounds.fLeft);
+ vy += SkIntToFixed(glyph->fBounds.fTop);
+
+ // keep them as ints until we've done the clip-test
+ GrFixed width = glyph->fBounds.width();
+ GrFixed height = glyph->fBounds.height();
+
+ // check if we clipped out
+ if (true || NULL == glyph->fPlot) {
+ int x = vx >> 16;
+ int y = vy >> 16;
+ if (fClipRect.quickReject(x, y, x + width, y + height)) {
+// SkCLZ(3); // so we can set a break-point in the debugger
+ return;
+ }
+ }
+
+ if (NULL == glyph->fPlot) {
+ if (fStrike->getGlyphAtlas(glyph, scaler)) {
+ goto HAS_ATLAS;
+ }
+
+ // try to clear out an unused plot before we flush
+ fContext->getFontCache()->freePlotExceptFor(fStrike);
+ if (fStrike->getGlyphAtlas(glyph, scaler)) {
+ goto HAS_ATLAS;
+ }
+
+ if (c_DumpFontCache) {
+#ifdef SK_DEVELOPER
+ fContext->getFontCache()->dump();
+#endif
+ }
+
+ // before we purge the cache, we must flush any accumulated draws
+ this->flushGlyphs();
+ fContext->flush();
+
+ // try to purge
+ fContext->getFontCache()->purgeExceptFor(fStrike);
+ // need to use new flush count here
+ if (fStrike->getGlyphAtlas(glyph, scaler)) {
+ goto HAS_ATLAS;
+ }
+
+ if (NULL == glyph->fPath) {
+ SkPath* path = SkNEW(SkPath);
+ if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
+ // flag the glyph as being dead?
+ delete path;
+ return;
+ }
+ glyph->fPath = path;
+ }
+
+ GrContext::AutoMatrix am;
+ SkMatrix translate;
+ translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds.fLeft)),
+ SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop)));
+ GrPaint tmpPaint(fPaint);
+ am.setPreConcat(fContext, translate, &tmpPaint);
+ SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
+ fContext->drawPath(tmpPaint, *glyph->fPath, stroke);
+ return;
+ }
+
+HAS_ATLAS:
+ SkASSERT(glyph->fPlot);
+ GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
+ glyph->fPlot->setDrawToken(drawToken);
+
+ // now promote them to fixed (TODO: Rethink using fixed pt).
+ width = SkIntToFixed(width);
+ height = SkIntToFixed(height);
+
+ GrTexture* texture = glyph->fPlot->texture();
+ SkASSERT(texture);
+
+ if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
+ this->flushGlyphs();
+ fCurrTexture = texture;
+ fCurrTexture->ref();
+ }
+
+ 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));
+ bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
+ if (flush) {
+ this->flushGlyphs();
+ fContext->flush();
+ fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
+ SK_ARRAY_COUNT(gTextVertexAttribs));
+ }
+ fMaxVertices = kDefaultRequestedVerts;
+ // ignore return, no point in flushing again.
+ fDrawTarget->geometryHints(&fMaxVertices, NULL);
+
+ int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
+ if (fMaxVertices < kMinRequestedVerts) {
+ fMaxVertices = kDefaultRequestedVerts;
+ } else if (fMaxVertices > maxQuadVertices) {
+ // don't exceed the limit of the index buffer
+ fMaxVertices = maxQuadVertices;
+ }
+ bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
+ 0,
+ GrTCast<void**>(&fVertices),
+ NULL);
+ GrAlwaysAssert(success);
+ SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize());
+ }
+
+ GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
+ GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
+
+ fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx),
+ SkFixedToFloat(vy),
+ SkFixedToFloat(vx + width),
+ SkFixedToFloat(vy + height),
+ 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));
+ fCurrVertex += 4;
+}
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 8178032ae7..363a817778 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -6,82 +6,10 @@
*/
-
#include "GrTextContext.h"
-#include "GrAtlas.h"
-#include "GrContext.h"
-#include "GrDrawTarget.h"
-#include "GrFontScaler.h"
-#include "GrIndexBuffer.h"
-#include "GrTextStrike.h"
-#include "GrTextStrike_impl.h"
-#include "SkPath.h"
-#include "SkRTConf.h"
-#include "SkStrokeRec.h"
-#include "effects/GrCustomCoordsTextureEffect.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.");
-
-void GrTextContext::flushGlyphs() {
- if (NULL == fDrawTarget) {
- return;
- }
-
- GrDrawState* drawState = fDrawTarget->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
-
- if (fCurrVertex > 0) {
- // setup our sampler state for our text texture/atlas
- SkASSERT(GrIsALIGN4(fCurrVertex));
- SkASSERT(fCurrTexture);
- GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
-
- // This effect could be stored with one of the cache objects (atlas?)
- drawState->addCoverageEffect(
- GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
- kGlyphCoordsAttributeIndex)->unref();
-
- if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
- if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
- kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
- fPaint.numColorStages()) {
- GrPrintf("LCD Text will not draw correctly.\n");
- }
- // setup blend so that we get mask * paintColor + (1-mask)*dstColor
- drawState->setBlendConstant(fPaint.getColor());
- drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
- // don't modulate by the paint's color in the frag since we're
- // already doing it via the blend const.
- drawState->setColor(0xffffffff);
- } else {
- // set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- drawState->setColor(fPaint.getColor());
- }
-
- int nGlyphs = fCurrVertex / 4;
- fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
- nGlyphs,
- 4, 6);
- fDrawTarget->resetVertexSource();
- fVertices = NULL;
- fMaxVertices = 0;
- fCurrVertex = 0;
- SkSafeSetNull(fCurrTexture);
- }
-}
GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(paint) {
fContext = context;
- fStrike = NULL;
-
- fCurrTexture = NULL;
- fCurrVertex = 0;
const GrClipData* clipData = context->getClip();
@@ -95,175 +23,6 @@ GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(
devConservativeBound.roundOut(&fClipRect);
- fAutoMatrix.setIdentity(fContext, &fPaint);
-
fDrawTarget = fContext->getTextTarget();
-
- fVertices = NULL;
- fMaxVertices = 0;
-}
-
-GrTextContext::~GrTextContext() {
- this->flushGlyphs();
}
-void GrTextContext::flush() {
- this->flushGlyphs();
-}
-
-namespace {
-
-// position + texture coord
-extern const GrVertexAttrib gTextVertexAttribs[] = {
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
- {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
-};
-
-};
-
-void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
- GrFixed vx, GrFixed vy,
- GrFontScaler* scaler) {
- if (NULL == fDrawTarget) {
- return;
- }
- if (NULL == fStrike) {
- fStrike = fContext->getFontCache()->getStrike(scaler);
- }
-
- GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
- if (NULL == glyph || glyph->fBounds.isEmpty()) {
- return;
- }
-
- vx += SkIntToFixed(glyph->fBounds.fLeft);
- vy += SkIntToFixed(glyph->fBounds.fTop);
-
- // keep them as ints until we've done the clip-test
- GrFixed width = glyph->fBounds.width();
- GrFixed height = glyph->fBounds.height();
-
- // check if we clipped out
- if (true || NULL == glyph->fPlot) {
- int x = vx >> 16;
- int y = vy >> 16;
- if (fClipRect.quickReject(x, y, x + width, y + height)) {
-// SkCLZ(3); // so we can set a break-point in the debugger
- return;
- }
- }
-
- if (NULL == glyph->fPlot) {
- if (fStrike->getGlyphAtlas(glyph, scaler)) {
- goto HAS_ATLAS;
- }
-
- // try to clear out an unused plot before we flush
- fContext->getFontCache()->freePlotExceptFor(fStrike);
- if (fStrike->getGlyphAtlas(glyph, scaler)) {
- goto HAS_ATLAS;
- }
-
- if (c_DumpFontCache) {
-#ifdef SK_DEVELOPER
- fContext->getFontCache()->dump();
-#endif
- }
-
- // before we purge the cache, we must flush any accumulated draws
- this->flushGlyphs();
- fContext->flush();
-
- // try to purge
- fContext->getFontCache()->purgeExceptFor(fStrike);
- // need to use new flush count here
- if (fStrike->getGlyphAtlas(glyph, scaler)) {
- goto HAS_ATLAS;
- }
-
- if (NULL == glyph->fPath) {
- SkPath* path = SkNEW(SkPath);
- if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
- // flag the glyph as being dead?
- delete path;
- return;
- }
- glyph->fPath = path;
- }
-
- GrContext::AutoMatrix am;
- SkMatrix translate;
- translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds.fLeft)),
- SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop)));
- GrPaint tmpPaint(fPaint);
- am.setPreConcat(fContext, translate, &tmpPaint);
- SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
- fContext->drawPath(tmpPaint, *glyph->fPath, stroke);
- return;
- }
-
-HAS_ATLAS:
- SkASSERT(glyph->fPlot);
- GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
- glyph->fPlot->setDrawToken(drawToken);
-
- // now promote them to fixed (TODO: Rethink using fixed pt).
- width = SkIntToFixed(width);
- height = SkIntToFixed(height);
-
- GrTexture* texture = glyph->fPlot->texture();
- SkASSERT(texture);
-
- if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
- this->flushGlyphs();
- fCurrTexture = texture;
- fCurrTexture->ref();
- }
-
- 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));
- bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
- if (flush) {
- this->flushGlyphs();
- fContext->flush();
- fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
- SK_ARRAY_COUNT(gTextVertexAttribs));
- }
- fMaxVertices = kDefaultRequestedVerts;
- // ignore return, no point in flushing again.
- fDrawTarget->geometryHints(&fMaxVertices, NULL);
-
- int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
- if (fMaxVertices < kMinRequestedVerts) {
- fMaxVertices = kDefaultRequestedVerts;
- } else if (fMaxVertices > maxQuadVertices) {
- // don't exceed the limit of the index buffer
- fMaxVertices = maxQuadVertices;
- }
- bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
- 0,
- GrTCast<void**>(&fVertices),
- NULL);
- GrAlwaysAssert(success);
- SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize());
- }
-
- GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
- GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
-
- fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx),
- SkFixedToFloat(vy),
- SkFixedToFloat(vx + width),
- SkFixedToFloat(vy + height),
- 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));
- fCurrVertex += 4;
-}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 7bba41f60a..3c91101b34 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -11,7 +11,7 @@
#include "effects/GrSimpleTextureEffect.h"
#include "GrContext.h"
-#include "GrTextContext.h"
+#include "GrBitmapTextContext.h"
#include "SkGrTexturePixelRef.h"
@@ -1743,7 +1743,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
return;
}
- GrTextContext context(fContext, grPaint);
+ GrBitmapTextContext context(fContext, grPaint);
myDraw.fProcs = this->initDrawForText(&context);
this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
}
@@ -1766,7 +1766,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
return;
}
- GrTextContext context(fContext, grPaint);
+ GrBitmapTextContext context(fContext, grPaint);
myDraw.fProcs = this->initDrawForText(&context);
this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
scalarsPerPos, paint);