diff options
author | 2015-11-09 13:51:06 -0800 | |
---|---|---|
committer | 2015-11-09 13:51:06 -0800 | |
commit | 60029a5397f75aae4bdb994f26bd297edc3e433c (patch) | |
tree | ecfe56285b4e3810fb864bd3cb2c07d1855d9638 /src/gpu | |
parent | e5911c9c5b859d60208f4b9ac4bf2a638f4bc35f (diff) |
Update Layer Hoisting to store its atlas texture in the resource cache
BUG=skia:4346
Committed: https://skia.googlesource.com/skia/+/42597bc99f00553825843b5ed41e81b121773368
Review URL: https://codereview.chromium.org/1406013006
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrLayerAtlas.cpp | 45 | ||||
-rw-r--r-- | src/gpu/GrLayerAtlas.h | 21 | ||||
-rw-r--r-- | src/gpu/GrLayerCache.cpp | 92 | ||||
-rw-r--r-- | src/gpu/GrLayerCache.h | 38 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.h | 7 | ||||
-rw-r--r-- | src/gpu/GrRectanizer_skyline.h | 4 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.h | 47 | ||||
-rw-r--r-- | src/gpu/GrTest.cpp | 55 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 3 |
10 files changed, 232 insertions, 95 deletions
diff --git a/src/gpu/GrLayerAtlas.cpp b/src/gpu/GrLayerAtlas.cpp index 3b30607c8c..9beb509f86 100644 --- a/src/gpu/GrLayerAtlas.cpp +++ b/src/gpu/GrLayerAtlas.cpp @@ -6,6 +6,7 @@ * found in the LICENSE file. */ +#include "GrGpuResourcePriv.h" #include "GrLayerAtlas.h" #include "GrRectanizer.h" #include "GrTextureProvider.h" @@ -43,6 +44,32 @@ void GrLayerAtlas::Plot::reset() { } /////////////////////////////////////////////////////////////////////////////// +GR_DECLARE_STATIC_UNIQUE_KEY(gLayerAtlasKey); +static const GrUniqueKey& get_layer_atlas_key() { + GR_DEFINE_STATIC_UNIQUE_KEY(gLayerAtlasKey); + return gLayerAtlasKey; +} + +bool GrLayerAtlas::reattachBackingTexture() { + SkASSERT(!fTexture); + + fTexture.reset(fTexProvider->findAndRefTextureByUniqueKey(get_layer_atlas_key())); + return SkToBool(fTexture); +} + +void GrLayerAtlas::createBackingTexture() { + SkASSERT(!fTexture); + + GrSurfaceDesc desc; + desc.fFlags = fFlags; + desc.fWidth = fBackingTextureSize.width(); + desc.fHeight = fBackingTextureSize.height(); + desc.fConfig = fPixelConfig; + + fTexture.reset(fTexProvider->createTexture(desc, true, nullptr, 0)); + + fTexture->resourcePriv().setUniqueKey(get_layer_atlas_key()); +} GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config, GrSurfaceFlags flags, @@ -52,7 +79,6 @@ GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config, fPixelConfig = config; fFlags = flags; fBackingTextureSize = backingTextureSize; - fTexture = nullptr; int textureWidth = fBackingTextureSize.width(); int textureHeight = fBackingTextureSize.height(); @@ -81,8 +107,14 @@ GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config, } } +void GrLayerAtlas::resetPlots() { + PlotIter iter; + for (Plot* plot = iter.init(fPlotList, PlotIter::kHead_IterStart); plot; plot = iter.next()) { + plot->reset(); + } +} + GrLayerAtlas::~GrLayerAtlas() { - SkSafeUnref(fTexture); delete[] fPlotArray; } @@ -111,14 +143,7 @@ GrLayerAtlas::Plot* GrLayerAtlas::addToAtlas(ClientPlotUsage* usage, // before we get a new plot, make sure we have a backing texture if (nullptr == fTexture) { - // TODO: Update this to use the cache rather than directly creating a texture. - GrSurfaceDesc desc; - desc.fFlags = fFlags; - desc.fWidth = fBackingTextureSize.width(); - desc.fHeight = fBackingTextureSize.height(); - desc.fConfig = fPixelConfig; - - fTexture = fTexProvider->createTexture(desc, true, nullptr, 0); + this->createBackingTexture(); if (nullptr == fTexture) { return nullptr; } diff --git a/src/gpu/GrLayerAtlas.h b/src/gpu/GrLayerAtlas.h index ae08e4527b..e84667b5ea 100644 --- a/src/gpu/GrLayerAtlas.h +++ b/src/gpu/GrLayerAtlas.h @@ -9,15 +9,13 @@ #ifndef GrLayerAtlas_DEFINED #define GrLayerAtlas_DEFINED -#include "GrTypes.h" +#include "GrTexture.h" #include "SkPoint.h" -#include "SkSize.h" #include "SkTDArray.h" #include "SkTInternalLList.h" class GrLayerAtlas; -class GrTexture; class GrTextureProvider; class GrRectanizer; @@ -109,10 +107,23 @@ public: // nullptr is returned if there is no more space in the atlas. Plot* addToAtlas(ClientPlotUsage*, int width, int height, SkIPoint16* loc); + GrTexture* getTextureOrNull() const { + return fTexture; + } + GrTexture* getTexture() const { + SkASSERT(fTexture); return fTexture; } + bool reattachBackingTexture(); + + void detachBackingTexture() { + fTexture.reset(nullptr); + } + + void resetPlots(); + enum IterOrder { kLRUFirst_IterOrder, kMRUFirst_IterOrder @@ -127,12 +138,14 @@ public: } private: + void createBackingTexture(); + void makeMRU(Plot* plot); GrTextureProvider* fTexProvider; GrPixelConfig fPixelConfig; GrSurfaceFlags fFlags; - GrTexture* fTexture; + SkAutoTUnref<GrTexture> fTexture; SkISize fBackingTextureSize; diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp index 9af89a3466..105ee04e53 100644 --- a/src/gpu/GrLayerCache.cpp +++ b/src/gpu/GrLayerCache.cpp @@ -27,9 +27,11 @@ void GrCachedLayer::validate(const GrTexture* backingTexture) const { SkASSERT(fRect.isEmpty()); SkASSERT(nullptr == fPlot); SkASSERT(!fLocked); // layers without a texture cannot be locked + SkASSERT(!fAtlased); // can't be atlased if it doesn't have a texture } if (fPlot) { + SkASSERT(fAtlased); // If a layer has a plot (i.e., is atlased) then it must point to // the backing texture. Additionally, its rect should be non-empty. SkASSERT(fTexture && backingTexture == fTexture); @@ -119,8 +121,10 @@ void GrLayerCache::freeAll() { } fLayerHash.rewind(); - // The atlas only lets go of its texture when the atlas is deleted. - fAtlas.free(); + if (fAtlas) { + fAtlas->resetPlots(); + fAtlas->detachBackingTexture(); + } } GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, @@ -167,7 +171,7 @@ GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID, bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* needsRendering) { - SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr, layer);) + SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTextureOrNull() : nullptr, layer);) SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight)); SkASSERT(0 == desc.fSampleCnt); @@ -217,7 +221,7 @@ bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, // The layer was successfully added to the atlas const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY, desc.fWidth, desc.fHeight); - layer->setTexture(fAtlas->getTexture(), bounds); + layer->setTexture(fAtlas->getTexture(), bounds, true); layer->setPlot(plot); layer->setLocked(true); this->incPlotLock(layer->plot()->id()); @@ -227,7 +231,7 @@ bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, // The layer was rejected by the atlas (even though we know it is // plausibly atlas-able). See if a plot can be purged and try again. - if (!this->purgePlot()) { + if (!this->purgePlots(true)) { break; // We weren't able to purge any plots } } @@ -260,14 +264,14 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* n return false; } - layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight)); + layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight), false); layer->setLocked(true); *needsRendering = true; return true; } void GrLayerCache::unlock(GrCachedLayer* layer) { - SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr, layer);) + SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTextureOrNull() : nullptr, layer);) if (nullptr == layer || !layer->locked()) { // invalid or not locked @@ -299,11 +303,11 @@ void GrLayerCache::unlock(GrCachedLayer* layer) { } layer->setPlot(nullptr); - layer->setTexture(nullptr, SkIRect::MakeEmpty()); + layer->setTexture(nullptr, SkIRect::MakeEmpty(), false); #endif } else { - layer->setTexture(nullptr, SkIRect::MakeEmpty()); + layer->setTexture(nullptr, SkIRect::MakeEmpty(), false); } layer->setLocked(false); @@ -318,7 +322,7 @@ void GrLayerCache::validate() const { for (; !iter.done(); ++iter) { const GrCachedLayer* layer = &(*iter); - layer->validate(fAtlas.get() ? fAtlas->getTexture() : nullptr); + layer->validate(fAtlas.get() ? fAtlas->getTextureOrNull() : nullptr); const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); if (!pictInfo) { @@ -389,10 +393,11 @@ void GrLayerCache::purge(uint32_t pictureID) { } } -bool GrLayerCache::purgePlot() { +bool GrLayerCache::purgePlots(bool justOne) { SkDEBUGCODE(GrAutoValidateCache avc(this);) SkASSERT(fAtlas); + bool anyPurged = false; GrLayerAtlas::PlotIter iter; GrLayerAtlas::Plot* plot; for (plot = fAtlas->iterInit(&iter, GrLayerAtlas::kLRUFirst_IterOrder); @@ -402,11 +407,14 @@ bool GrLayerCache::purgePlot() { continue; } + anyPurged = true; this->purgePlot(plot); - return true; + if (justOne) { + break; + } } - return false; + return anyPurged; } void GrLayerCache::purgePlot(GrLayerAtlas::Plot* plot) { @@ -455,27 +463,57 @@ void GrLayerCache::purgeAll() { return; } - GrLayerAtlas::PlotIter iter; - GrLayerAtlas::Plot* plot; - for (plot = fAtlas->iterInit(&iter, GrLayerAtlas::kLRUFirst_IterOrder); - plot; - plot = iter.prev()) { - SkASSERT(0 == fPlotLocks[plot->id()]); - - this->purgePlot(plot); - } + this->purgePlots(false); // clear them all out SkASSERT(0 == fPictureHash.count()); - SkAutoTUnref<GrDrawContext> drawContext( - fContext->drawContext(fAtlas->getTexture()->asRenderTarget())); + if (fAtlas->getTextureOrNull()) { + SkAutoTUnref<GrDrawContext> drawContext( + fContext->drawContext(fAtlas->getTexture()->asRenderTarget())); - if (drawContext) { - drawContext->discard(); + if (drawContext) { + drawContext->discard(); + } } } #endif +void GrLayerCache::begin() { + if (!fAtlas) { + return; + } + + if (!fAtlas->reattachBackingTexture()) { + // We weren't able to re-attach. Clear out all the atlased layers. + this->purgePlots(false); + SkASSERT(0 == fPictureHash.count()); + } +#ifdef SK_DEBUG + else { + // we've reattached - everything had better make sense + SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); + for (; !iter.done(); ++iter) { + GrCachedLayer* layer = &(*iter); + + if (layer->isAtlased()) { + SkASSERT(fAtlas->getTexture() == layer->texture()); + } + } + } +#endif +} + +void GrLayerCache::end() { + if (!fAtlas) { + return; + } + + // Adding this call will clear out all the layers in the atlas + //this->purgePlots(false); + + fAtlas->detachBackingTexture(); +} + void GrLayerCache::processDeletedPictures() { SkTArray<SkPicture::DeletionMessage> deletedPictures; fPictDeletionInbox.poll(&deletedPictures); @@ -489,7 +527,7 @@ void GrLayerCache::processDeletedPictures() { void GrLayerCache::writeLayersToDisk(const SkString& dirName) { if (fAtlas) { - GrTexture* atlasTexture = fAtlas->getTexture(); + GrTexture* atlasTexture = fAtlas->getTextureOrNull(); if (nullptr != atlasTexture) { SkString fileName(dirName); fileName.append("\\atlas.png"); diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h index 914d0d5a58..a606681896 100644 --- a/src/gpu/GrLayerCache.h +++ b/src/gpu/GrLayerCache.h @@ -165,6 +165,7 @@ public: , fPaint(paint ? new SkPaint(*paint) : nullptr) , fFilter(nullptr) , fTexture(nullptr) + , fAtlased(false) , fRect(SkIRect::MakeEmpty()) , fPlot(nullptr) , fUses(0) @@ -180,7 +181,9 @@ public: } ~GrCachedLayer() { - SkSafeUnref(fTexture); + if (!fAtlased) { + SkSafeUnref(fTexture); + } SkSafeUnref(fFilter); delete fPaint; } @@ -195,8 +198,15 @@ public: const SkIRect& srcIR() const { return fSrcIR; } const SkIRect& dstIR() const { return fDstIR; } int stop() const { return fStop; } - void setTexture(GrTexture* texture, const SkIRect& rect) { - SkRefCnt_SafeAssign(fTexture, texture); + void setTexture(GrTexture* texture, const SkIRect& rect, bool atlased) { + if (texture && !atlased) { + texture->ref(); // non-atlased textures carry a ref + } + if (fTexture && !fAtlased) { + fTexture->unref(); // non-atlased textures carry a ref + } + fTexture = texture; + fAtlased = atlased; fRect = rect; if (!fTexture) { fLocked = false; @@ -216,7 +226,7 @@ public: } GrLayerAtlas::Plot* plot() { return fPlot; } - bool isAtlased() const { return SkToBool(fPlot); } + bool isAtlased() const { SkASSERT(fAtlased == SkToBool(fPlot)); return fAtlased; } void setLocked(bool locked) { fLocked = locked; } bool locked() const { return fLocked; } @@ -252,6 +262,10 @@ private: // ref on a GrTexture for non-atlased textures. GrTexture* fTexture; + // true if this layer is in the atlas (and 'fTexture' doesn't carry a ref) + // and false if the layer is a free floater (and carries a ref). + bool fAtlased; + // For both atlased and non-atlased layers 'fRect' contains the bound of // the layer in whichever texture it resides. It is empty when 'fTexture' // is nullptr. @@ -285,10 +299,9 @@ private: // The GrLayerCache caches pre-computed saveLayers for later rendering. // Non-atlased layers are stored in their own GrTexture while the atlased // layers share a single GrTexture. -// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888) -// and one GrPlot (for the entire atlas). As such, the GrLayerCache -// roughly combines the functionality of the GrFontCache and GrTextStrike -// classes. +// Unlike the GrFontCache, the GrLayerCache only has one atlas (for 8888). +// As such, the GrLayerCache roughly combines the functionality of the +// GrFontCache and GrTextStrike classes. class GrLayerCache { public: GrLayerCache(GrContext*); @@ -346,6 +359,9 @@ public: return width <= kPlotWidth && height <= kPlotHeight; } + void begin(); + void end(); + #if !GR_CACHE_HOISTED_LAYERS void purgeAll(); #endif @@ -361,7 +377,7 @@ private: static const int kPlotHeight = kAtlasTextureHeight / kNumPlotsY; GrContext* fContext; // pointer back to owning context - SkAutoTDelete<GrLayerAtlas> fAtlas; // TODO: could lazily allocate + SkAutoTDelete<GrLayerAtlas> fAtlas; // lazily allocated // We cache this information here (rather then, say, on the owning picture) // because we want to be able to clean it up as needed (e.g., if a picture @@ -397,9 +413,9 @@ private: void purgePlot(GrLayerAtlas::Plot* plot); - // Try to find a purgeable plot and clear it out. Return true if a plot + // Either purge all un-locked plots or just one. Return true if >= 1 plot // was purged; false otherwise. - bool purgePlot(); + bool purgePlots(bool justOne); void incPlotLock(int plotIdx) { ++fPlotLocks[plotIdx]; } void decPlotLock(int plotIdx) { diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp index 2bf1abb5fd..004e4d0e6e 100644 --- a/src/gpu/GrLayerHoister.cpp +++ b/src/gpu/GrLayerHoister.cpp @@ -322,7 +322,7 @@ void GrLayerHoister::FilterLayer(GrContext* context, } SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height()); - layer->setTexture(filteredBitmap.getTexture(), newRect); + layer->setTexture(filteredBitmap.getTexture(), newRect, false); layer->setOffset(offset); } @@ -380,13 +380,22 @@ void GrLayerHoister::UnlockLayers(GrContext* context, SkDEBUGCODE(layerCache->validate();) } -void GrLayerHoister::PurgeCache(GrContext* context) { -#if !GR_CACHE_HOISTED_LAYERS +void GrLayerHoister::Begin(GrContext* context) { + GrLayerCache* layerCache = context->getLayerCache(); + + layerCache->begin(); +} + +void GrLayerHoister::End(GrContext* context) { GrLayerCache* layerCache = context->getLayerCache(); +#if !GR_CACHE_HOISTED_LAYERS + // This code completely clears out the atlas. It is required when // caching is disabled so the atlas doesn't fill up and force more // free floating layers layerCache->purgeAll(); #endif + + layerCache->end(); } diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h index f30c53c038..13cac5173a 100644 --- a/src/gpu/GrLayerHoister.h +++ b/src/gpu/GrLayerHoister.h @@ -33,6 +33,13 @@ public: // UnlockLayers should be called once to allow the texture resources to be recycled class GrLayerHoister { public: + /** Attempt to reattach layers that may have been atlased in the past + */ + static void Begin(GrContext* context); + + /** Release cache resources + */ + static void End(GrContext* context); /** Find the layers in 'topLevelPicture' that can be atlased. Note that the discovered layers can be inside nested sub-pictures. diff --git a/src/gpu/GrRectanizer_skyline.h b/src/gpu/GrRectanizer_skyline.h index a06bba00fb..576b1fc62a 100644 --- a/src/gpu/GrRectanizer_skyline.h +++ b/src/gpu/GrRectanizer_skyline.h @@ -19,9 +19,9 @@ public: this->reset(); } - virtual ~GrRectanizerSkyline() { } + ~GrRectanizerSkyline() override { } - void reset() override{ + void reset() override { fAreaSoFar = 0; fSkyline.reset(); SkylineSegment* seg = fSkyline.append(1); diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h index 2412174121..ed2affeae3 100644 --- a/src/gpu/GrResourceCache.h +++ b/src/gpu/GrResourceCache.h @@ -182,7 +182,52 @@ public: void notifyFlushOccurred(); -#if GR_GPU_STATS +#if GR_CACHE_STATS + struct Stats { + int fTotal; + int fNumPurgeable; + int fNumNonPurgeable; + + int fScratch; + int fExternal; + int fBorrowed; + int fAdopted; + size_t fUnbudgetedSize; + + Stats() { this->reset(); } + + void reset() { + fTotal = 0; + fNumPurgeable = 0; + fNumNonPurgeable = 0; + fScratch = 0; + fExternal = 0; + fBorrowed = 0; + fAdopted = 0; + fUnbudgetedSize = 0; + } + + void update(GrGpuResource* resource) { + if (resource->cacheAccess().isScratch()) { + ++fScratch; + } + if (resource->cacheAccess().isExternal()) { + ++fExternal; + } + if (resource->cacheAccess().isBorrowed()) { + ++fBorrowed; + } + if (resource->cacheAccess().isAdopted()) { + ++fAdopted; + } + if (!resource->resourcePriv().isBudgeted()) { + fUnbudgetedSize += resource->gpuMemorySize(); + } + } + }; + + void getStats(Stats*) const; + void dumpStats(SkString*) const; #endif diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp index 7a44942a16..2889e9709e 100644 --- a/src/gpu/GrTest.cpp +++ b/src/gpu/GrTest.cpp @@ -140,47 +140,27 @@ void GrGpu::Stats::dump(SkString* out) { #endif #if GR_CACHE_STATS -void GrResourceCache::dumpStats(SkString* out) const { - this->validate(); - - int locked = fNonpurgeableResources.count(); - - struct Stats { - int fScratch; - int fExternal; - int fBorrowed; - int fAdopted; - size_t fUnbudgetedSize; - - Stats() : fScratch(0), fExternal(0), fBorrowed(0), fAdopted(0), fUnbudgetedSize(0) {} - - void update(GrGpuResource* resource) { - if (resource->cacheAccess().isScratch()) { - ++fScratch; - } - if (resource->cacheAccess().isExternal()) { - ++fExternal; - } - if (resource->cacheAccess().isBorrowed()) { - ++fBorrowed; - } - if (resource->cacheAccess().isAdopted()) { - ++fAdopted; - } - if (!resource->resourcePriv().isBudgeted()) { - fUnbudgetedSize += resource->gpuMemorySize(); - } - } - }; +void GrResourceCache::getStats(Stats* stats) const { + stats->reset(); - Stats stats; + stats->fTotal = this->getResourceCount(); + stats->fNumNonPurgeable = fNonpurgeableResources.count(); + stats->fNumPurgeable = fPurgeableQueue.count(); for (int i = 0; i < fNonpurgeableResources.count(); ++i) { - stats.update(fNonpurgeableResources[i]); + stats->update(fNonpurgeableResources[i]); } for (int i = 0; i < fPurgeableQueue.count(); ++i) { - stats.update(fPurgeableQueue.at(i)); + stats->update(fPurgeableQueue.at(i)); } +} + +void GrResourceCache::dumpStats(SkString* out) const { + this->validate(); + + Stats stats; + + this->getStats(&stats); float countUtilization = (100.f * fBudgetedCount) / fMaxCount; float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes; @@ -188,8 +168,9 @@ void GrResourceCache::dumpStats(SkString* out) const { out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes); out->appendf("\t\tEntry Count: current %d" " (%d budgeted, %d external(%d borrowed, %d adopted), %d locked, %d scratch %.2g%% full), high %d\n", - this->getResourceCount(), fBudgetedCount, stats.fExternal, stats.fBorrowed, - stats.fAdopted, locked, stats.fScratch, countUtilization, fHighWaterCount); + stats.fTotal, fBudgetedCount, stats.fExternal, stats.fBorrowed, + stats.fAdopted, stats.fNumNonPurgeable, stats.fScratch, countUtilization, + fHighWaterCount); out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n", SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization, SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes)); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index c97d24809a..36e0342f78 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -2028,6 +2028,8 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture SkMatrix initialMatrix = mainCanvas->getTotalMatrix(); + GrLayerHoister::Begin(fContext); + GrLayerHoister::FindLayersToAtlas(fContext, mainPicture, initialMatrix, clipBounds, @@ -2056,6 +2058,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture GrLayerHoister::UnlockLayers(fContext, recycled); GrLayerHoister::UnlockLayers(fContext, atlasedNeedRendering); GrLayerHoister::UnlockLayers(fContext, atlasedRecycled); + GrLayerHoister::End(fContext); return true; #else |