| Index: src/gpu/GrLayerCache.cpp
|
| diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
|
| index 9af89a34665664e42499623bab05e46cc60cd156..105ee04e53cd1a26f6ab78238211229bc3916225 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");
|
|
|