| 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;
|
| };
|
|
|