Add GrResourceCache::purgeToMakeHeadroom
This function will be used by the resource allocator to figure out
whether an allocation plan is feasible without committing to it.
Bug: skia:10877
Change-Id: I135b7b80d53d9c3541d2fa0313d91d14a1d54eb2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/394156
Commit-Queue: Adlai Holler <adlai@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Auto-Submit: Adlai Holler <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrGpuResource.h b/src/gpu/GrGpuResource.h
index 015f036..3a5c064 100644
--- a/src/gpu/GrGpuResource.h
+++ b/src/gpu/GrGpuResource.h
@@ -124,7 +124,7 @@
/**
* Retrieves the context that owns the object. Note that it is possible for
* this to return NULL. When objects have been release()ed or abandon()ed
- * they no longer have an owning context. Destroying a GrContext
+ * they no longer have an owning context. Destroying a GrDirectContext
* automatically releases all its resources.
*/
const GrDirectContext* getContext() const;
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 4c5cb85..94211f2 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -7,6 +7,7 @@
#include "src/gpu/GrResourceCache.h"
#include <atomic>
+#include <vector>
#include "include/gpu/GrDirectContext.h"
#include "include/private/GrSingleOwner.h"
#include "include/private/SkTo.h"
@@ -619,6 +620,40 @@
}
}
+bool GrResourceCache::purgeToMakeHeadroom(size_t desiredHeadroomBytes) {
+ AutoValidate av(this);
+ if (this->wouldFit(desiredHeadroomBytes)) {
+ return true;
+ }
+ fPurgeableQueue.sort();
+
+ size_t headroom = this->overBudget() ? 0 : fMaxBytes - fBudgetedBytes;
+ int purgeCnt = 0;
+ for (int i = 0; i < fPurgeableQueue.count(); i++) {
+ GrGpuResource* resource = fPurgeableQueue.at(i);
+ headroom += resource->gpuMemorySize();
+ if (headroom >= desiredHeadroomBytes) {
+ purgeCnt = i + 1;
+ break;
+ }
+ }
+ if (headroom < desiredHeadroomBytes) {
+ return false;
+ }
+
+ // Success! Release the resources.
+ // Copy to array first so we don't mess with the queue.
+ std::vector<GrGpuResource*> resources;
+ resources.reserve(purgeCnt);
+ for (int i = 0; i < purgeCnt; i++) {
+ resources.push_back(fPurgeableQueue.at(i));
+ }
+ for (GrGpuResource* resource : resources) {
+ resource->cacheAccess().release();
+ }
+ return true;
+}
+
void GrResourceCache::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
const size_t tmpByteBudget = std::max((size_t)0, fBytes - bytesToPurge);
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index 4a634ad..eb52ca2 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -165,6 +165,11 @@
/** Purge all resources not used since the passed in time. */
void purgeResourcesNotUsedSince(GrStdSteadyClock::time_point);
+ /** If it's possible to purge enough resources to get the provided amount of budget
+ headroom, do so and return true. If it's not possible, do nothing and return false.
+ */
+ bool purgeToMakeHeadroom(size_t desiredHeadroomBytes);
+
bool overBudget() const { return fBudgetedBytes > fMaxBytes; }
/**