Add plumbing for the GrThreadSafeUniquelyKeyedProxyViewCache

This CL is also imperfect and incomplete but, although currently unused, it sketches in how the threadSafeProxyCache will be plumbed through the GrContexts and GrResourceCache.

Bug: 1108408
Change-Id: Idb012b6efd49291de69bd88e4b4c531458a3e553
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317360
Reviewed-by: Adlai Holler <adlai@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 6b3c8d0..fcdd8d9 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -21,6 +21,7 @@
 #include "src/gpu/GrProxyProvider.h"
 #include "src/gpu/GrTexture.h"
 #include "src/gpu/GrTextureProxyCacheAccess.h"
+#include "src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.h"
 #include "src/gpu/GrTracing.h"
 #include "src/gpu/SkGr.h"
 
@@ -200,6 +201,8 @@
 void GrResourceCache::abandonAll() {
     AutoValidate av(this);
 
+    fThreadSafeViewCache->dropAllRefs();
+
     // We need to make sure to free any resources that were waiting on a free message but never
     // received one.
     fTexturesAwaitingUnref.reset();
@@ -230,6 +233,8 @@
 void GrResourceCache::releaseAll() {
     AutoValidate av(this);
 
+    fThreadSafeViewCache->dropAllRefs();
+
     this->processFreedGpuResources();
 
     // We need to make sure to free any resources that were waiting on a free message but never
@@ -237,6 +242,8 @@
     fTexturesAwaitingUnref.reset();
 
     SkASSERT(fProxyProvider); // better have called setProxyProvider
+    SkASSERT(fThreadSafeViewCache); // better have called setThreadSafeViewCache too
+
     // We must remove the uniqueKeys from the proxies here. While they possess a uniqueKey
     // they also have a raw pointer back to this class (which is presumably going away)!
     fProxyProvider->removeAllUniqueKeys();
@@ -522,10 +529,25 @@
         stillOverbudget = this->overBudget();
     }
 
+    if (stillOverbudget) {
+        fThreadSafeViewCache->dropAllUniqueRefs(); // Is there a less nuclear option?
+
+        while (stillOverbudget && fPurgeableQueue.count()) {
+            GrGpuResource* resource = fPurgeableQueue.peek();
+            SkASSERT(resource->resourcePriv().isPurgeable());
+            resource->cacheAccess().release();
+            stillOverbudget = this->overBudget();
+        }
+    }
+
     this->validate();
 }
 
 void GrResourceCache::purgeUnlockedResources(bool scratchResourcesOnly) {
+    // In the scratch-only mode we could just drop the ones that are uniquely held and would
+    // be converted to scratch textures
+    fThreadSafeViewCache->dropAllUniqueRefs();
+
     if (!scratchResourcesOnly) {
         // We could disable maintaining the heap property here, but it would add a lot of
         // complexity. Moreover, this is rarely called.
@@ -616,12 +638,12 @@
         fMaxBytes = cachedByteCount;
     }
 }
+
 bool GrResourceCache::requestsFlush() const {
     return this->overBudget() && !fPurgeableQueue.count() &&
            fNumBudgetedResourcesFlushWillMakePurgeable > 0;
 }
 
-
 void GrResourceCache::insertDelayedTextureUnref(GrTexture* texture) {
     texture->ref();
     uint32_t id = texture->uniqueID().asUInt();
@@ -634,7 +656,7 @@
 
 void GrResourceCache::processFreedGpuResources() {
     if (!fTexturesAwaitingUnref.count()) {
-      return;
+        return;
     }
 
     SkTArray<GrTextureFreedMessage> msgs;