diff options
author | Derek Sollenberger <djsollen@google.com> | 2017-05-25 16:43:59 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-26 18:14:33 +0000 |
commit | 5480a18d8799511034d0da219c72932cd8f25274 (patch) | |
tree | 0be82d1f2275f2df75a5bf77eb330fadf677166b /src | |
parent | dc8c34455849574e4e0260ea35485f093723c10d (diff) |
Add method to GrContext to purge unlocked resources.
Beyond setting the total cache limits this method enables clients to
request to purge a specific number of bytes, as well as specify their
preference to purge scratch resources over resources of other types.
Change-Id: I9259d5544d34251575d77eebe599388f213ff3ce
Reviewed-on: https://skia-review.googlesource.com/17987
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Derek Sollenberger <djsollen@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkTDPQueue.h | 14 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.cpp | 41 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.h | 12 |
4 files changed, 72 insertions, 0 deletions
diff --git a/src/core/SkTDPQueue.h b/src/core/SkTDPQueue.h index b5c9923c81..5f6fd3bc73 100644 --- a/src/core/SkTDPQueue.h +++ b/src/core/SkTDPQueue.h @@ -9,6 +9,7 @@ #define SkTDPQueue_DEFINED #include "SkTDArray.h" +#include "SkTSort.h" /** * This class implements a priority queue. T is the type of the elements in the queue. LESS is a @@ -102,6 +103,19 @@ public: to peek(). Otherwise, there is no guarantee about ordering of elements in the queue. */ T at(int i) const { return fArray[i]; } + /** Sorts the queue into priority order. The queue is only guarenteed to remain in sorted order + * until any other operation, other than at(), is performed. + */ + void sort() { + if (fArray.count() > 1) { + SkTQSort<T>(fArray.begin(), fArray.end() - 1, LESS); + for (int i = 0; i < fArray.count(); i++) { + this->setIndex(i); + } + this->validate(); + } + } + private: static int LeftOf(int x) { SkASSERT(x >= 0); return 2 * x + 1; } static int ParentOf(int x) { SkASSERT(x > 0); return (x - 1) >> 1; } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index e7aff3586a..e78dc6ab12 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -204,6 +204,11 @@ void GrContext::purgeResourcesNotUsedInMs(std::chrono::milliseconds ms) { fResourceCache->purgeResourcesNotUsedSince(GrStdSteadyClock::now() - ms); } +void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) { + ASSERT_SINGLE_OWNER + fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources); +} + void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { ASSERT_SINGLE_OWNER diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 53a62c05c0..ef703e2474 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -536,6 +536,47 @@ void GrResourceCache::purgeResourcesNotUsedSince(GrStdSteadyClock::time_point pu } } +void GrResourceCache::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) { + + const size_t tmpByteBudget = SkTMax((size_t)0, fBytes - bytesToPurge); + bool stillOverbudget = tmpByteBudget < fBytes; + + if (preferScratchResources && bytesToPurge < fPurgeableBytes) { + // Sort the queue + fPurgeableQueue.sort(); + + // Make a list of the scratch resources to delete + SkTDArray<GrGpuResource*> scratchResources; + size_t scratchByteCount = 0; + for (int i = 0; i < fPurgeableQueue.count() && stillOverbudget; i++) { + GrGpuResource* resource = fPurgeableQueue.at(i); + SkASSERT(resource->isPurgeable()); + if (!resource->getUniqueKey().isValid()) { + *scratchResources.append() = resource; + scratchByteCount += resource->gpuMemorySize(); + stillOverbudget = tmpByteBudget < fBytes - scratchByteCount; + } + } + + // Delete the scratch resources. This must be done as a separate pass + // to avoid messing up the sorted order of the queue + for (int i = 0; i < scratchResources.count(); i++) { + scratchResources.getAt(i)->cacheAccess().release(); + } + stillOverbudget = tmpByteBudget < fBytes; + + this->validate(); + } + + // Purge any remaining resources in LRU order + if (stillOverbudget) { + const size_t cachedByteCount = fMaxBytes; + fMaxBytes = tmpByteBudget; + this->purgeAsNeeded(); + fMaxBytes = cachedByteCount; + } +} + void GrResourceCache::processInvalidUniqueKeys( const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) { for (int i = 0; i < msgs.count(); ++i) { diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h index 6362c37e09..f851ab1592 100644 --- a/src/gpu/GrResourceCache.h +++ b/src/gpu/GrResourceCache.h @@ -173,6 +173,18 @@ public: /** Purge all resources not used since the passed in time. */ void purgeResourcesNotUsedSince(GrStdSteadyClock::time_point); + /** + * Purge unlocked resources from the cache until the the provided byte count has been reached + * or we have purged all unlocked resources. The default policy is to purge in LRU order, but + * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other + * resource types. + * + * @param maxBytesToPurge the desired number of bytes to be purged. + * @param preferScratchResources If true scratch resources will be purged prior to other + * resource types. + */ + void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources); + /** Returns true if the cache would like a flush to occur in order to make more resources purgeable. */ bool requestsFlush() const { return fRequestFlush; } |