Index: src/gpu/GrDistanceFieldTextContext.cpp |
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp |
index dc0ea954ec189f50cd47f058acd6a35497a3c2a0..429897d6c3d1d470d79ec6f5b1740cd83ebf145b 100755 |
--- a/src/gpu/GrDistanceFieldTextContext.cpp |
+++ b/src/gpu/GrDistanceFieldTextContext.cpp |
@@ -60,24 +60,20 @@ static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); |
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, |
const SkDeviceProperties& properties, |
bool enable) |
- : GrTextContext(context, properties) { |
+ : GrTextContext(context, properties) |
+ , fStrike(NULL) |
#if SK_FORCE_DISTANCEFIELD_FONTS |
- fEnableDFRendering = true; |
+ , fEnableDFRendering(true) |
#else |
- fEnableDFRendering = enable; |
+ , fEnableDFRendering(enable) |
#endif |
- fStrike = NULL; |
- fGammaTexture = NULL; |
- |
- fCurrTexture = NULL; |
- fCurrVertex = 0; |
- fEffectTextureUniqueID = SK_InvalidUniqueID; |
- fEffectColor = GrColor_ILLEGAL; |
- fEffectFlags = 0; |
- |
- fVertices = NULL; |
- fMaxVertices = 0; |
- |
+ , fEffectTextureUniqueID(SK_InvalidUniqueID) |
+ , fEffectColor(GrColor_ILLEGAL) |
+ , fEffectFlags(0) |
+ , fGammaTexture(NULL) |
+ , fVertices(NULL) |
+ , fVertexCount(0) |
+ , fCurrVertex(0) { |
fVertexBounds.setLargestInverted(); |
} |
@@ -126,7 +122,9 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo |
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode); |
GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode); |
- uint32_t textureUniqueID = fCurrTexture->getUniqueID(); |
+ GrTexture* currTexture = fStrike->getTexture(); |
+ SkASSERT(currTexture); |
+ uint32_t textureUniqueID = currTexture->getUniqueID(); |
// set up any flags |
uint32_t flags = 0; |
@@ -144,7 +142,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo |
flags != fEffectFlags) { |
if (fUseLCDText) { |
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); |
- fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTexture, |
+ fCachedEffect.reset(GrDistanceFieldLCDTextureEffect::Create(currTexture, |
params, |
fGammaTexture, |
gammaParams, |
@@ -154,14 +152,14 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo |
#ifdef SK_GAMMA_APPLY_TO_A8 |
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma, |
filteredColor); |
- fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture, |
+ fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture, |
params, |
fGammaTexture, |
gammaParams, |
lum/255.f, |
flags)); |
#else |
- fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture, |
+ fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(currTexture, |
params, flags)); |
#endif |
} |
@@ -230,26 +228,17 @@ void GrDistanceFieldTextContext::flushGlyphs() { |
fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
nGlyphs, |
4, 6, &fVertexBounds); |
- fDrawTarget->resetVertexSource(); |
- fVertices = NULL; |
- fMaxVertices = 0; |
fCurrVertex = 0; |
- SkSafeSetNull(fCurrTexture); |
fVertexBounds.setLargestInverted(); |
} |
+ |
+ fDrawTarget->resetVertexSource(); |
+ fVertices = NULL; |
} |
void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
SkFixed vx, SkFixed vy, |
GrFontScaler* scaler) { |
- if (NULL == fDrawTarget) { |
- return; |
- } |
- |
- if (NULL == fStrike) { |
- fStrike = fContext->getFontCache()->getStrike(scaler, true); |
- } |
- |
GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
if (NULL == glyph || glyph->fBounds.isEmpty()) { |
return; |
@@ -293,10 +282,19 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
#endif |
} |
- // before we purge the cache, we must flush any accumulated draws |
+ // flush any accumulated draws to allow us to free up a plot |
+ int remainingVertexCount = fVertexCount - fCurrVertex; |
this->flushGlyphs(); |
fContext->flush(); |
+ // need to reallocate the vertex buffer for the remaining glyphs |
+ fVertexCount = remainingVertexCount; |
+ bool success = fDrawTarget->reserveVertexAndIndexSpace(fVertexCount, |
+ 0, |
+ &fVertices, |
+ NULL); |
+ GrAlwaysAssert(success); |
+ |
// we should have an unused plot now |
if (fContext->getFontCache()->freeUnusedPlot(fStrike) && |
fStrike->addGlyphToAtlas(glyph, scaler)) { |
@@ -332,59 +330,6 @@ HAS_ATLAS: |
GrTexture* texture = glyph->fPlot->texture(); |
SkASSERT(texture); |
- if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
- this->flushGlyphs(); |
- fCurrTexture = texture; |
- fCurrTexture->ref(); |
- } |
- |
- bool useColorVerts = !fUseLCDText; |
- |
- 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), |
- kTextVAColorSize); |
- } else { |
- fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
- SK_ARRAY_COUNT(gTextVertexAttribs), |
- kTextVASize); |
- } |
- bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); |
- if (flush) { |
- this->flushGlyphs(); |
- fContext->flush(); |
- if (useColorVerts) { |
- fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( |
- SK_ARRAY_COUNT(gTextVertexWithColorAttribs), |
- kTextVAColorSize); |
- } else { |
- fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
- SK_ARRAY_COUNT(gTextVertexAttribs), |
- kTextVASize); |
- } |
- } |
- 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); |
- } |
- |
SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); |
SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); |
SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
@@ -397,7 +342,7 @@ HAS_ATLAS: |
sy += dy; |
width *= scale; |
height *= scale; |
- |
+ |
SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset); |
SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset); |
SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset); |
@@ -428,7 +373,7 @@ HAS_ATLAS: |
SkFixedToFloat(texture->normalizeFixedX(tx + tw)), |
SkFixedToFloat(texture->normalizeFixedY(ty + th)), |
vertSize); |
- if (useColorVerts) { |
+ if (!fUseLCDText) { |
if (0xFF == GrColorUnpackA(fPaint.getColor())) { |
fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); |
} |
@@ -518,6 +463,25 @@ static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, |
} |
} |
+void GrDistanceFieldTextContext::allocateVertices(const char text[], size_t byteLength) { |
+ SkASSERT(NULL == fVertices); |
+ if (!fUseLCDText) { |
+ fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>( |
+ SK_ARRAY_COUNT(gTextVertexWithColorAttribs), |
+ kTextVAColorSize); |
+ } else { |
+ fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( |
+ SK_ARRAY_COUNT(gTextVertexAttribs), |
+ kTextVASize); |
+ } |
+ fVertexCount = 4*fSkPaint.textToGlyphs(text, byteLength, NULL); |
+ bool success = fDrawTarget->reserveVertexAndIndexSpace(fVertexCount, |
+ 0, |
+ &fVertices, |
+ NULL); |
+ GrAlwaysAssert(success); |
+} |
+ |
void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, |
const char text[], size_t byteLength, |
SkScalar x, SkScalar y) { |
@@ -531,6 +495,10 @@ void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s |
this->init(paint, skPaint); |
+ if (NULL == fDrawTarget) { |
+ return; |
+ } |
+ |
SkScalar sizeRatio = fTextRatio; |
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
@@ -538,9 +506,14 @@ void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& s |
SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
+ if (NULL == fStrike) { |
+ fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
+ } |
setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
+ this->allocateVertices(text, byteLength); |
+ |
// need to measure first |
// TODO - generate positions and pre-load cache as well? |
const char* stop = text + byteLength; |
@@ -608,14 +581,23 @@ void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint |
this->init(paint, skPaint); |
+ if (NULL == fDrawTarget) { |
+ return; |
+ } |
+ |
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); |
SkGlyphCache* cache = autoCache.getCache(); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
+ if (NULL == fStrike) { |
+ fStrike = fContext->getFontCache()->getStrike(fontScaler, true); |
+ } |
setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); |
+ this->allocateVertices(text, byteLength); |
+ |
const char* stop = text + byteLength; |
if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { |