Index: src/gpu/GrBatchFontCache.h |
diff --git a/src/gpu/GrBatchFontCache.h b/src/gpu/GrBatchFontCache.h |
index d9352323a5217f0a1c279fd5f6b5a7fe18d82122..6aa14e69daf271fd05f049c9acbb76fb820c78c4 100644 |
--- a/src/gpu/GrBatchFontCache.h |
+++ b/src/gpu/GrBatchFontCache.h |
@@ -75,18 +75,17 @@ private: |
/* |
* GrBatchFontCache manages strikes which are indexed by a GrFontScaler. These strikes can then be |
* used to individual Glyph Masks. The GrBatchFontCache also manages GrBatchAtlases, though this is |
- * more or less transparent to the client(aside from atlasGeneration, described below) |
+ * more or less transparent to the client(aside from atlasGeneration, described below). |
+ * Note - we used to initialize the backing atlas for the GrBatchFontCache at initialization time. |
+ * However, this caused a regression, even when the GrBatchFontCache was unused. We now initialize |
+ * the backing atlases lazily. Its not immediately clear why this improves the situation. |
*/ |
class GrBatchFontCache { |
public: |
- GrBatchFontCache(); |
+ GrBatchFontCache(GrContext*); |
~GrBatchFontCache(); |
- // Initializes the GrBatchFontCache on the owning GrContext |
- void init(GrContext*); |
- |
inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) { |
- |
GrBatchTextStrike* strike = fCache.find(*(scaler->getKey())); |
if (NULL == strike) { |
strike = this->generateStrike(scaler); |
@@ -94,49 +93,93 @@ public: |
return strike; |
} |
- bool hasGlyph(GrGlyph* glyph); |
+ void freeAll(); |
+ |
+ // if getTexture returns NULL, the client must not try to use other functions on the |
+ // GrBatchFontCache which use the atlas. This function *must* be called first, before other |
+ // functions which use the atlas. |
+ GrTexture* getTexture(GrMaskFormat format) { |
+ if (this->initAtlas(format)) { |
+ return this->getAtlas(format)->getTexture(); |
+ } |
+ return NULL; |
+ } |
+ |
+ bool hasGlyph(GrGlyph* glyph) { |
+ SkASSERT(glyph); |
+ return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID); |
+ } |
// To ensure the GrBatchAtlas does not evict the Glyph Mask from its texture backing store, |
// the client must pass in the currentToken from the GrBatchTarget along with the GrGlyph. |
// A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas. |
// For convenience, this function will also set the use token for the current glyph if required |
// NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration |
- void addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater*, GrGlyph*, |
- GrBatchAtlas::BatchToken); |
+ void addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater* updater, |
+ GrGlyph* glyph, GrBatchAtlas::BatchToken token) { |
+ SkASSERT(glyph); |
+ updater->add(glyph->fID); |
+ this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token); |
+ } |
- void setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater&, GrBatchAtlas::BatchToken, |
- GrMaskFormat); |
+ void setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater& updater, |
+ GrBatchAtlas::BatchToken token, |
+ GrMaskFormat format) { |
+ this->getAtlas(format)->setLastUseTokenBulk(updater, token); |
+ } |
// add to texture atlas that matches this format |
- bool addToAtlas(GrBatchTextStrike*, GrBatchAtlas::AtlasID*, GrBatchTarget*, |
- GrMaskFormat, int width, int height, const void* image, |
- SkIPoint16* loc); |
+ bool addToAtlas(GrBatchTextStrike* strike, GrBatchAtlas::AtlasID* id, |
+ GrBatchTarget* batchTarget, |
+ GrMaskFormat format, int width, int height, const void* image, |
+ SkIPoint16* loc) { |
+ fPreserveStrike = strike; |
+ return this->getAtlas(format)->addToAtlas(id, batchTarget, width, height, image, loc); |
+ } |
// Some clients may wish to verify the integrity of the texture backing store of the |
// GrBatchAtlas. The atlasGeneration returned below is a monitonically increasing number which |
// changes everytime something is removed from the texture backing store. |
- uint64_t atlasGeneration(GrMaskFormat) const; |
- |
- void freeAll(); |
+ uint64_t atlasGeneration(GrMaskFormat format) const { |
+ return this->getAtlas(format)->atlasGeneration(); |
+ } |
- GrTexture* getTexture(GrMaskFormat); |
GrPixelConfig getPixelConfig(GrMaskFormat) const; |
void dump() const; |
private: |
// There is a 1:1 mapping between GrMaskFormats and atlas indices |
- static int MaskFormatToAtlasIndex(GrMaskFormat); |
- static GrMaskFormat AtlasIndexToMaskFormat(int atlasIndex); |
+ static int MaskFormatToAtlasIndex(GrMaskFormat format) { |
+ static const int sAtlasIndices[] = { |
+ kA8_GrMaskFormat, |
+ kA565_GrMaskFormat, |
+ kARGB_GrMaskFormat, |
+ }; |
+ SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_size_mismatch); |
+ |
+ SkASSERT(sAtlasIndices[format] < kMaskFormatCount); |
+ return sAtlasIndices[format]; |
+ } |
- GrBatchTextStrike* generateStrike(GrFontScaler*); |
+ bool initAtlas(GrMaskFormat); |
- inline GrBatchAtlas* getAtlas(GrMaskFormat) const; |
+ GrBatchTextStrike* generateStrike(GrFontScaler* scaler) { |
+ GrBatchTextStrike* strike = SkNEW_ARGS(GrBatchTextStrike, (this, scaler->getKey())); |
+ fCache.add(strike); |
+ return strike; |
+ } |
+ |
+ GrBatchAtlas* getAtlas(GrMaskFormat format) const { |
+ int atlasIndex = MaskFormatToAtlasIndex(format); |
+ SkASSERT(fAtlases[atlasIndex]); |
+ return fAtlases[atlasIndex]; |
+ } |
static void HandleEviction(GrBatchAtlas::AtlasID, void*); |
+ GrContext* fContext; |
SkTDynamicHash<GrBatchTextStrike, GrFontDescKey> fCache; |
- |
GrBatchAtlas* fAtlases[kMaskFormatCount]; |
GrBatchTextStrike* fPreserveStrike; |
}; |