Index: src/gpu/GrBitmapTextContext.cpp |
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp |
index fe3fa31c196a8d8ba3e4f480e6a3d5009dbb5062..3ca98e46eb29723151c471b1591ddccf03b9fe44 100755 |
--- a/src/gpu/GrBitmapTextContext.cpp |
+++ b/src/gpu/GrBitmapTextContext.cpp |
@@ -59,6 +59,7 @@ |
fEffectTextureUniqueID = SK_InvalidUniqueID; |
fVertices = NULL; |
+ fMaxVertices = 0; |
fVertexBounds.setLargestInverted(); |
} |
@@ -153,6 +154,7 @@ |
fDrawTarget->resetVertexSource(); |
fVertices = NULL; |
+ fMaxVertices = 0; |
fCurrVertex = 0; |
fVertexBounds.setLargestInverted(); |
SkSafeSetNull(fCurrTexture); |
@@ -168,6 +170,7 @@ |
fCurrVertex = 0; |
fVertices = NULL; |
+ fMaxVertices = 0; |
} |
inline void GrBitmapTextContext::finish() { |
@@ -188,18 +191,11 @@ |
this->init(paint, skPaint); |
- if (NULL == fDrawTarget) { |
- return; |
- } |
- |
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix()); |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
- if (NULL == fStrike) { |
- fStrike = fContext->getFontCache()->getStrike(fontScaler, false); |
- } |
// transform our starting point |
{ |
@@ -227,23 +223,6 @@ |
} |
const char* stop = text + byteLength; |
- |
- // allocate vertices |
- SkASSERT(NULL == fVertices); |
- bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat(); |
- if (useColorVerts) { |
- 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, |
- &fVertices, |
- NULL); |
- GrAlwaysAssert(success); |
SkAutoKern autokern; |
@@ -305,41 +284,16 @@ |
this->init(paint, skPaint); |
- if (NULL == fDrawTarget) { |
- return; |
- } |
- |
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix()); |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
- |
- if (NULL == fStrike) { |
- fStrike = fContext->getFontCache()->getStrike(fontScaler, false); |
- } |
// store original matrix before we reset, so we can use it to transform positions |
SkMatrix ctm = fContext->getMatrix(); |
GrContext::AutoMatrix autoMatrix; |
autoMatrix.setIdentity(fContext, &fPaint); |
- |
- // allocate vertices |
- SkASSERT(NULL == fVertices); |
- bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat(); |
- if (useColorVerts) { |
- 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, |
- &fVertices, |
- NULL); |
- GrAlwaysAssert(success); |
const char* stop = text + byteLength; |
SkTextAlignProc alignProc(fSkPaint.getTextAlign()); |
@@ -472,6 +426,14 @@ |
void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
SkFixed vx, SkFixed vy, |
GrFontScaler* scaler) { |
+ if (NULL == fDrawTarget) { |
+ return; |
+ } |
+ |
+ if (NULL == fStrike) { |
+ fStrike = fContext->getFontCache()->getStrike(scaler, false); |
+ } |
+ |
GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
if (NULL == glyph || glyph->fBounds.isEmpty()) { |
return; |
@@ -554,10 +516,53 @@ |
GrTexture* texture = glyph->fPlot->texture(); |
SkASSERT(texture); |
- if (fCurrTexture != texture) { |
+ if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
this->flushGlyphs(); |
fCurrTexture = texture; |
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; |
+ 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(); |
+ 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. |
+ 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, |
+ &fVertices, |
+ NULL); |
+ GrAlwaysAssert(success); |
} |
SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); |
@@ -571,7 +576,6 @@ |
fVertexBounds.growToInclude(r); |
- bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat(); |
size_t vertSize = useColorVerts ? (2 * sizeof(SkPoint) + sizeof(GrColor)) : |
(2 * sizeof(SkPoint)); |