aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-04-09 08:22:37 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-09 08:22:37 -0700
commit62db8ba68b980245e0927b792747864ebd6fcb6a (patch)
tree19da7371dc2338de2805d875afb75f071a70637f
parent8ed3b9a386374d7996dfbe0c9de13b42f3dd245d (diff)
fix for perf regression on ugamsolutions / msaa16
-rw-r--r--src/gpu/GrAtlasTextContext.cpp8
-rw-r--r--src/gpu/GrBatchFontCache.cpp121
-rw-r--r--src/gpu/GrBatchFontCache.h89
-rwxr-xr-xsrc/gpu/GrContext.cpp3
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));
}