diff options
author | 2015-04-09 08:22:37 -0700 | |
---|---|---|
committer | 2015-04-09 08:22:37 -0700 | |
commit | 62db8ba68b980245e0927b792747864ebd6fcb6a (patch) | |
tree | 19da7371dc2338de2805d875afb75f071a70637f | |
parent | 8ed3b9a386374d7996dfbe0c9de13b42f3dd245d (diff) |
fix for perf regression on ugamsolutions / msaa16
BUG=skia:
Review URL: https://codereview.chromium.org/1076853002
-rw-r--r-- | src/gpu/GrAtlasTextContext.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrBatchFontCache.cpp | 121 | ||||
-rw-r--r-- | src/gpu/GrBatchFontCache.h | 89 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 3 |
4 files changed, 102 insertions, 119 deletions
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index d6bb3e0797..8c89f2b53e 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -701,13 +701,19 @@ public: return; } + GrTexture* texture = fFontCache->getTexture(fMaskFormat); + if (!texture) { + SkDebugf("Could not allocate backing texture for atlas\n"); + return; + } + GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode); // This will be ignored in the non A8 case bool opaqueVertexColors = GrColorIsOpaque(this->color()); SkAutoTUnref<const GrGeometryProcessor> gp( GrBitmapTextGeoProc::Create(this->color(), - fFontCache->getTexture(fMaskFormat), + texture, params, fMaskFormat, opaqueVertexColors, diff --git a/src/gpu/GrBatchFontCache.cpp b/src/gpu/GrBatchFontCache.cpp index 3cd7a64a73..653649ac78 100644 --- a/src/gpu/GrBatchFontCache.cpp +++ b/src/gpu/GrBatchFontCache.cpp @@ -34,57 +34,41 @@ static GrBatchAtlas* make_atlas(GrContext* context, GrPixelConfig config, return SkNEW_ARGS(GrBatchAtlas, (texture, numPlotsX, numPlotsY)); } -int GrBatchFontCache::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]; -} - -GrMaskFormat GrBatchFontCache::AtlasIndexToMaskFormat(int atlasIndex) { - static GrMaskFormat sMaskFormats[] = { - kA8_GrMaskFormat, - kA565_GrMaskFormat, - kARGB_GrMaskFormat, - }; - SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sMaskFormats) == kMaskFormatCount, array_size_mismatch); - - SkASSERT(sMaskFormats[atlasIndex] < kMaskFormatCount); - return sMaskFormats[atlasIndex]; -} - -GrBatchFontCache::GrBatchFontCache() - : fPreserveStrike(NULL) { -} - -void GrBatchFontCache::init(GrContext* context) { - for (int i = 0; i < kMaskFormatCount; i++) { - GrMaskFormat format = AtlasIndexToMaskFormat(i); +bool GrBatchFontCache::initAtlas(GrMaskFormat format) { + int index = MaskFormatToAtlasIndex(format); + if (!fAtlases[index]) { GrPixelConfig config = this->getPixelConfig(format); - if (kA8_GrMaskFormat == format) { - fAtlases[i] = make_atlas(context, config, - GR_FONT_ATLAS_A8_TEXTURE_WIDTH, - GR_FONT_ATLAS_TEXTURE_HEIGHT, - GR_FONT_ATLAS_A8_NUM_PLOTS_X, - GR_FONT_ATLAS_NUM_PLOTS_Y); + fAtlases[index] = make_atlas(fContext, config, + GR_FONT_ATLAS_A8_TEXTURE_WIDTH, + GR_FONT_ATLAS_TEXTURE_HEIGHT, + GR_FONT_ATLAS_A8_NUM_PLOTS_X, + GR_FONT_ATLAS_NUM_PLOTS_Y); } else { - fAtlases[i] = make_atlas(context, config, - GR_FONT_ATLAS_TEXTURE_WIDTH, - GR_FONT_ATLAS_TEXTURE_HEIGHT, - GR_FONT_ATLAS_NUM_PLOTS_X, - GR_FONT_ATLAS_NUM_PLOTS_Y); + fAtlases[index] = make_atlas(fContext, config, + GR_FONT_ATLAS_TEXTURE_WIDTH, + GR_FONT_ATLAS_TEXTURE_HEIGHT, + GR_FONT_ATLAS_NUM_PLOTS_X, + GR_FONT_ATLAS_NUM_PLOTS_Y); } - if (fAtlases[i]) { - fAtlases[i]->registerEvictionCallback(&GrBatchFontCache::HandleEviction, (void*)this); + // Atlas creation can fail + if (fAtlases[index]) { + fAtlases[index]->registerEvictionCallback(&GrBatchFontCache::HandleEviction, + (void*)this); + } else { + return false; } } + return true; +} + +GrBatchFontCache::GrBatchFontCache(GrContext* context) + : fContext(context) + , fPreserveStrike(NULL) { + for (int i = 0; i < kMaskFormatCount; ++i) { + fAtlases[i] = NULL; + } } GrBatchFontCache::~GrBatchFontCache() { @@ -98,12 +82,6 @@ GrBatchFontCache::~GrBatchFontCache() { } } -GrBatchTextStrike* GrBatchFontCache::generateStrike(GrFontScaler* scaler) { - GrBatchTextStrike* strike = SkNEW_ARGS(GrBatchTextStrike, (this, scaler->getKey())); - fCache.add(strike); - return strike; -} - void GrBatchFontCache::freeAll() { SkTDynamicHash<GrBatchTextStrike, GrFontDescKey>::Iter iter(&fCache); while (!iter.done()) { @@ -117,49 +95,6 @@ void GrBatchFontCache::freeAll() { } } -inline GrBatchAtlas* GrBatchFontCache::getAtlas(GrMaskFormat format) const { - int atlasIndex = MaskFormatToAtlasIndex(format); - SkASSERT(fAtlases[atlasIndex]); - return fAtlases[atlasIndex]; -} - -bool GrBatchFontCache::hasGlyph(GrGlyph* glyph) { - SkASSERT(glyph); - return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID); -} - -void GrBatchFontCache::addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater* updater, - GrGlyph* glyph, - GrBatchAtlas::BatchToken token) { - SkASSERT(glyph); - updater->add(glyph->fID); - this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token); -} - -void GrBatchFontCache::setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater& updater, - GrBatchAtlas::BatchToken token, - GrMaskFormat format) { - this->getAtlas(format)->setLastUseTokenBulk(updater, token); -} - -bool GrBatchFontCache::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); -} - -uint64_t GrBatchFontCache::atlasGeneration(GrMaskFormat format) const { - return this->getAtlas(format)->atlasGeneration(); -} - -GrTexture* GrBatchFontCache::getTexture(GrMaskFormat format) { - int atlasIndex = MaskFormatToAtlasIndex(format); - SkASSERT(fAtlases[atlasIndex]); - return fAtlases[atlasIndex]->getTexture(); -} - GrPixelConfig GrBatchFontCache::getPixelConfig(GrMaskFormat format) const { static const GrPixelConfig kPixelConfigs[] = { kAlpha_8_GrPixelConfig, diff --git a/src/gpu/GrBatchFontCache.h b/src/gpu/GrBatchFontCache.h index d9352323a5..6aa14e69da 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; }; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 48e50b7717..2d61f35a4f 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -135,8 +135,7 @@ void GrContext::initCommon() { this->setupDrawBuffer(); // GrBatchFontCache will eventually replace GrFontCache - fBatchFontCache = SkNEW(GrBatchFontCache); - fBatchFontCache->init(this); + fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this)); fTextBlobCache.reset(SkNEW(GrTextBlobCache)); } |