diff options
author | robertphillips <robertphillips@google.com> | 2015-11-09 13:51:06 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-09 13:51:06 -0800 |
commit | 60029a5397f75aae4bdb994f26bd297edc3e433c (patch) | |
tree | ecfe56285b4e3810fb864bd3cb2c07d1855d9638 /src/gpu/GrLayerCache.cpp | |
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/GrLayerCache.cpp')
-rw-r--r-- | src/gpu/GrLayerCache.cpp | 92 |
1 files changed, 65 insertions, 27 deletions
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"); |