Add time-based purging to the GrThreadSafeUniquelyKeyedProxyViewCache

Bug: 1108408
Change-Id: I7dd4a3b1b20f3267903dd7f303a2d639b562d84a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/318761
Reviewed-by: Adlai Holler <adlai@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp b/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp
index 3c253d1..b776e79 100644
--- a/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp
+++ b/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp
@@ -66,6 +66,31 @@
     }
 }
 
+void GrThreadSafeUniquelyKeyedProxyViewCache::dropUniqueRefsOlderThan(
+        GrStdSteadyClock::time_point purgeTime) {
+    SkAutoSpinlock lock{fSpinLock};
+
+    // Iterate from LRU to MRU
+    Entry* cur = fUniquelyKeyedProxyViewList.tail();
+    Entry* prev = cur ? cur->fPrev : nullptr;
+
+    while (cur) {
+        if (cur->fLastAccess >= purgeTime) {
+            // This entry and all the remaining ones in the list will be newer than 'purgeTime'
+            return;
+        }
+
+        if (cur->fView.proxy()->unique()) {
+            fUniquelyKeyedProxyViewMap.remove(cur->fKey);
+            fUniquelyKeyedProxyViewList.remove(cur);
+            this->recycleEntry(cur);
+        }
+
+        cur = prev;
+        prev = cur ? cur->fPrev : nullptr;
+    }
+}
+
 GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::find(const GrUniqueKey& key) {
     SkAutoSpinlock lock{fSpinLock};
 
@@ -73,6 +98,7 @@
     if (tmp) {
         SkASSERT(fUniquelyKeyedProxyViewList.isInList(tmp));
         // make the sought out entry the MRU
+        tmp->fLastAccess = GrStdSteadyClock::now();
         fUniquelyKeyedProxyViewList.remove(tmp);
         fUniquelyKeyedProxyViewList.addToHead(tmp);
         return tmp->fView;
@@ -97,7 +123,9 @@
         entry = fEntryAllocator.make<Entry>(key, view);
     }
 
-    fUniquelyKeyedProxyViewList.addToHead(entry);  // make 'entry' the MRU
+    // make 'entry' the MRU
+    entry->fLastAccess = GrStdSteadyClock::now();
+    fUniquelyKeyedProxyViewList.addToHead(entry);
     fUniquelyKeyedProxyViewMap.add(entry);
     return entry;
 }