aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrLayerCache.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-11-09 13:51:06 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-11-09 13:51:06 -0800
commit60029a5397f75aae4bdb994f26bd297edc3e433c (patch)
treeecfe56285b4e3810fb864bd3cb2c07d1855d9638 /src/gpu/GrLayerCache.cpp
parente5911c9c5b859d60208f4b9ac4bf2a638f4bc35f (diff)
Update Layer Hoisting to store its atlas texture in the resource cache
Diffstat (limited to 'src/gpu/GrLayerCache.cpp')
-rw-r--r--src/gpu/GrLayerCache.cpp92
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");