diff options
Diffstat (limited to 'src/gpu')
-rwxr-xr-x | src/gpu/GrBitmapTextContext.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrBitmapTextContext.h | 7 | ||||
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrFontScaler.cpp | 24 | ||||
-rw-r--r-- | src/gpu/GrTextStrike.cpp | 65 | ||||
-rw-r--r-- | src/gpu/GrTextStrike.h | 17 |
6 files changed, 82 insertions, 54 deletions
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index 9478d0436c..7cfe91771f 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -370,7 +370,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, } // try to clear out an unused plot before we flush - if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -386,7 +386,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, fContext->flush(); // we should have an unused plot now - if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -422,6 +422,7 @@ HAS_ATLAS: width = SkIntToFixed(width); height = SkIntToFixed(height); + // the current texture/maskformat must match what the glyph needs GrTexture* texture = glyph->fPlot->texture(); SkASSERT(texture); @@ -429,9 +430,10 @@ HAS_ATLAS: this->flush(); fCurrTexture = texture; fCurrTexture->ref(); + fCurrMaskFormat = glyph->fMaskFormat; } - bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat(); + bool useColorVerts = kA8_GrMaskFormat == fCurrMaskFormat; if (NULL == fVertices) { // If we need to reserve vertices allow the draw target to suggest @@ -549,12 +551,12 @@ void GrBitmapTextContext::flush() { // This effect could be stored with one of the cache objects (atlas?) drawState->setGeometryProcessor(fCachedGeometryProcessor.get()); SkASSERT(fStrike); - switch (fStrike->getMaskFormat()) { + switch (fCurrMaskFormat) { // Color bitmap text case kARGB_GrMaskFormat: SkASSERT(!drawState->hasColorVertexAttribute()); drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); - drawState->setColor(0xffffffff); + drawState->setAlpha(fSkPaint.getAlpha()); break; // LCD text case kA888_GrMaskFormat: @@ -585,7 +587,7 @@ void GrBitmapTextContext::flush() { SkASSERT(drawState->hasColorVertexAttribute()); break; default: - SkFAIL("Unexepected mask format."); + SkFAIL("Unexpected mask format."); } int nGlyphs = fCurrVertex / 4; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index 4bff399ade..a9805cb0fb 100644 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h @@ -40,13 +40,14 @@ private: GrTextStrike* fStrike; void* fVertices; - int32_t fMaxVertices; + int fCurrVertex; + int fMaxVertices; + SkRect fVertexBounds; GrTexture* fCurrTexture; + GrMaskFormat fCurrMaskFormat; SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor; // Used to check whether fCachedEffect is still valid. uint32_t fEffectTextureUniqueID; - int fCurrVertex; - SkRect fVertexBounds; void init(const GrPaint&, const SkPaint&); void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*); diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index baba10d570..a1f5ce6660 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -412,6 +412,11 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, return; } + // TODO: support color glyphs + if (kA8_GrMaskFormat != glyph->fMaskFormat) { + return; + } + SkScalar sx = SkFixedToScalar(vx); SkScalar sy = SkFixedToScalar(vy); /* @@ -440,7 +445,7 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, } // try to clear out an unused plot before we flush - if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -456,7 +461,7 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, fContext->flush(); // we should have an unused plot now - if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) && fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } diff --git a/src/gpu/GrFontScaler.cpp b/src/gpu/GrFontScaler.cpp index 164768f3b0..b16b498ac1 100644 --- a/src/gpu/GrFontScaler.cpp +++ b/src/gpu/GrFontScaler.cpp @@ -59,7 +59,7 @@ GrFontScaler::~GrFontScaler() { SkSafeUnref(fKey); } -GrMaskFormat GrFontScaler::getMaskFormat() { +GrMaskFormat GrFontScaler::getMaskFormat() const { SkMask::Format format = fStrike->getMaskFormat(); switch (format) { case SkMask::kBW_Format: @@ -85,6 +85,28 @@ const GrFontDescKey* GrFontScaler::getKey() { return fKey; } +GrMaskFormat GrFontScaler::getPackedGlyphMaskFormat(GrGlyph::PackedID packed) const { + const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), + GrGlyph::UnpackFixedX(packed), + GrGlyph::UnpackFixedY(packed)); + SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat); + switch (format) { + case SkMask::kBW_Format: + // fall through to kA8 -- we store BW glyphs in our 8-bit cache + case SkMask::kA8_Format: + return kA8_GrMaskFormat; + case SkMask::kLCD16_Format: + return kA565_GrMaskFormat; + case SkMask::kLCD32_Format: + return kA888_GrMaskFormat; + case SkMask::kARGB32_Format: + return kARGB_GrMaskFormat; + default: + SkDEBUGFAIL("unsupported SkMask::Format"); + return kA8_GrMaskFormat; + } +} + bool GrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) { const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), GrGlyph::UnpackFixedX(packed), diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp index 8ae10cc8dd..81be3418f7 100644 --- a/src/gpu/GrTextStrike.cpp +++ b/src/gpu/GrTextStrike.cpp @@ -80,20 +80,7 @@ static int mask_format_to_atlas_index(GrMaskFormat format) { } GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler) { - GrMaskFormat format = scaler->getMaskFormat(); - GrPixelConfig config = mask_format_to_pixel_config(format); - int atlasIndex = mask_format_to_atlas_index(format); - if (NULL == fAtlases[atlasIndex]) { - SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, - GR_ATLAS_TEXTURE_HEIGHT); - fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextureFlags, - textureSize, - GR_NUM_PLOTS_X, - GR_NUM_PLOTS_Y, - true)); - } - GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, - (this, scaler->getKey(), format, fAtlases[atlasIndex])); + GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, (this, scaler->getKey())); fCache.add(strike); if (fHead) { @@ -130,10 +117,30 @@ void GrFontCache::purgeStrike(GrTextStrike* strike) { delete strike; } -bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) { + +GrPlot* GrFontCache::addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage, + int width, int height, const void* image, + SkIPoint16* loc) { + GrPixelConfig config = mask_format_to_pixel_config(format); + int atlasIndex = mask_format_to_atlas_index(format); + if (NULL == fAtlases[atlasIndex]) { + SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, + GR_ATLAS_TEXTURE_HEIGHT); + fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextureFlags, + textureSize, + GR_NUM_PLOTS_X, + GR_NUM_PLOTS_Y, + true)); + } + return fAtlases[atlasIndex]->addToAtlas(usage, width, height, image, loc); +} + + +bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* glyph) { SkASSERT(preserveStrike); - GrAtlas* atlas = preserveStrike->fAtlas; + int index = mask_format_to_atlas_index(glyph->fMaskFormat); + GrAtlas* atlas = fAtlases[index]; GrPlot* plot = atlas->getUnusedPlot(); if (NULL == plot) { return false; @@ -141,13 +148,7 @@ bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) { plot->resetRects(); GrTextStrike* strike = fHead; - GrMaskFormat maskFormat = preserveStrike->fMaskFormat; while (strike) { - if (maskFormat != strike->fMaskFormat) { - strike = strike->fNext; - continue; - } - GrTextStrike* strikeToPurge = strike; strike = strikeToPurge->fNext; strikeToPurge->removePlot(plot); @@ -228,16 +229,11 @@ void GrFontCache::dump() const { atlas and a position within that texture. */ -GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key, - GrMaskFormat format, - GrAtlas* atlas) : fPool(64) { +GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key) : fPool(64) { fFontScalerKey = key; fFontScalerKey->ref(); fFontCache = cache; // no need to ref, it won't go away before we do - fAtlas = atlas; // no need to ref, it won't go away before we do - - fMaskFormat = format; #ifdef SK_DEBUG // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); @@ -271,9 +267,10 @@ GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, return NULL; } } - + GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed); + GrGlyph* glyph = fPool.alloc(); - glyph->init(packed, bounds); + glyph->init(packed, bounds, format); fCache.add(glyph); return glyph; } @@ -317,7 +314,7 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) { SkAutoUnref ar(SkSafeRef(scaler)); - int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); + int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat); size_t size = glyph->fBounds.area() * bytesPerPixel; GrAutoMalloc<1024> storage(size); @@ -337,9 +334,9 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) { } } - GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, glyph->width(), - glyph->height(), storage.get(), - &glyph->fAtlasLocation); + GrPlot* plot = fFontCache->addToAtlas(glyph->fMaskFormat, &fPlotUsage, + glyph->width(), glyph->height(), + storage.get(), &glyph->fAtlasLocation); if (NULL == plot) { return false; diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrTextStrike.h index 401bd73259..779d676e43 100644 --- a/src/gpu/GrTextStrike.h +++ b/src/gpu/GrTextStrike.h @@ -23,18 +23,16 @@ class GrGpu; class GrFontPurgeListener; /** - * The textcache maps a hostfontscaler instance to a dictionary of + * The textstrike maps a hostfontscaler instance to a dictionary of * glyphid->strike */ class GrTextStrike { public: - GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey, GrMaskFormat, GrAtlas*); + GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey); ~GrTextStrike(); const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; } GrFontCache* getFontCache() const { return fFontCache; } - GrMaskFormat getMaskFormat() const { return fMaskFormat; } - GrTexture* getTexture() const { return fAtlas->getTexture(); } inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*); // returns true if glyph (or glyph+padding for distance field) @@ -67,8 +65,6 @@ private: GrTAllocPool<GrGlyph> fPool; GrFontCache* fFontCache; - GrAtlas* fAtlas; - GrMaskFormat fMaskFormat; bool fUseDistanceField; GrAtlas::ClientPlotUsage fPlotUsage; @@ -85,10 +81,15 @@ public: inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField); + // add to texture atlas that matches this format + GrPlot* addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage, + int width, int height, const void* image, + SkIPoint16* loc); + void freeAll(); - // make an unused plot available - bool freeUnusedPlot(GrTextStrike* preserveStrike); + // make an unused plot available for this glyph + bool freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* glyph); // testing int countStrikes() const { return fCache.count(); } |