diff options
author | Robert Phillips <robertphillips@google.com> | 2017-11-13 15:48:12 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-14 12:20:02 +0000 |
commit | 5b65a84b990e4ed3b5534cd85167cdc3ed6c820a (patch) | |
tree | 525a1ecceb01c02ed5ee4ba57beb716a26ac8d18 /src/gpu/GrResourceAllocator.cpp | |
parent | 74c8436f2c34161fc0d506c15aa96c283bd5bc9e (diff) |
Resolve GrSurface/GrSurfaceProxy ref counting issue in GrResourceAllocator
The underlying issue is/was that (given that GrResourceProvider::createApproxTexture can pull a scratch texture out of the resource cache) resources the GrResourceAllocator thought is was controlling could magically be re-assigned behind its back. This CL resolves the issue by having the GrResourceAllocator maintain a strong ref on all the resources it believes it is controlling.
Change-Id: Ibcf49009dc953bd97d882177284eb57490cd5711
Reviewed-on: https://skia-review.googlesource.com/70722
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrResourceAllocator.cpp')
-rw-r--r-- | src/gpu/GrResourceAllocator.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp index f263802448..3e34a713d9 100644 --- a/src/gpu/GrResourceAllocator.cpp +++ b/src/gpu/GrResourceAllocator.cpp @@ -8,12 +8,27 @@ #include "GrResourceAllocator.h" #include "GrGpuResourcePriv.h" +#include "GrOpList.h" #include "GrResourceProvider.h" #include "GrSurfacePriv.h" #include "GrSurfaceProxy.h" #include "GrSurfaceProxyPriv.h" #include "GrTextureProxy.h" +void GrResourceAllocator::Interval::assign(sk_sp<GrSurface> s) { + SkASSERT(!fAssignedSurface); + fAssignedSurface = s; + fProxy->priv().assign(std::move(s)); +} + +GrResourceAllocator::~GrResourceAllocator() { +#ifndef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION + SkASSERT(fIntvlList.empty()); + SkASSERT(fActiveIntvls.empty()); + SkASSERT(!fIntvlHash.count()); +#endif +} + void GrResourceAllocator::addInterval(GrSurfaceProxy* proxy, unsigned int start, unsigned int end) { SkASSERT(start <= end); @@ -22,7 +37,7 @@ void GrResourceAllocator::addInterval(GrSurfaceProxy* proxy, if (Interval* intvl = fIntvlHash.find(proxy->uniqueID().asUInt())) { // Revise the interval for an existing use // TODO: this assert is failing on the copy_on_write_retain GM! - //SkASSERT(intvl->end() <= start); + SkASSERT(intvl->end() <= start); if (intvl->end() < end) { intvl->extendEnd(end); } @@ -87,7 +102,7 @@ void GrResourceAllocator::IntervalList::insertByIncreasingEnd(Interval* intvl) { } // 'surface' can be reused. Add it back to the free pool. -void GrResourceAllocator::freeUpSurface(GrSurface* surface) { +void GrResourceAllocator::freeUpSurface(sk_sp<GrSurface> surface) { const GrScratchKey &key = surface->resourcePriv().getScratchKey(); if (!key.isValid()) { @@ -102,7 +117,7 @@ void GrResourceAllocator::freeUpSurface(GrSurface* surface) { } // TODO: fix this insertion so we get a more LRU-ish behavior - fFreePool.insert(key, SkRef(surface)); + fFreePool.insert(key, surface.release()); } // First try to reuse one of the recently allocated/used GrSurfaces in the free pool. @@ -138,7 +153,10 @@ sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy void GrResourceAllocator::expire(unsigned int curIndex) { while (!fActiveIntvls.empty() && fActiveIntvls.peekHead()->end() < curIndex) { Interval* temp = fActiveIntvls.popHead(); - this->freeUpSurface(temp->proxy()->priv().peekSurface()); + + if (temp->wasAssignedSurface()) { + this->freeUpSurface(temp->detachSurface()); + } // Add temp to the free interval list so it can be reused temp->setNext(fFreeIntervalList); @@ -168,9 +186,13 @@ void GrResourceAllocator::assign() { SkASSERT(surface->getUniqueKey() == tex->getUniqueKey()); } - cur->proxy()->priv().assign(std::move(surface)); + cur->assign(std::move(surface)); } // TODO: handle resouce allocation failure upstack fActiveIntvls.insertByIncreasingEnd(cur); } + + // expire all the remaining intervals to drain the active interval list + this->expire(std::numeric_limits<unsigned int>::max()); } + |