Add MRU to GrThreadSafeUniquelyKeyedProxyViewCache
Bug: 1108408
Change-Id: I54ae1512340408e61c2fb2f408b006d6f7697cf7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317860
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 0c305d2..4a40198 100644
--- a/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp
+++ b/src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.cpp
@@ -7,59 +7,111 @@
#include "src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.h"
-GrThreadSafeUniquelyKeyedProxyViewCache::GrThreadSafeUniquelyKeyedProxyViewCache() {}
+GrThreadSafeUniquelyKeyedProxyViewCache::GrThreadSafeUniquelyKeyedProxyViewCache()
+ : fFreeEntryList(nullptr) {
+}
GrThreadSafeUniquelyKeyedProxyViewCache::~GrThreadSafeUniquelyKeyedProxyViewCache() {
- fUniquelyKeyedProxyViews.foreach([this](Entry* v) { this->recycleEntry(v); });
+ this->dropAllRefs();
}
#if GR_TEST_UTILS
int GrThreadSafeUniquelyKeyedProxyViewCache::numEntries() const {
SkAutoSpinlock lock{fSpinLock};
- return fUniquelyKeyedProxyViews.count();
+ return fUniquelyKeyedProxyViewMap.count();
}
int GrThreadSafeUniquelyKeyedProxyViewCache::count() const {
SkAutoSpinlock lock{fSpinLock};
- return fUniquelyKeyedProxyViews.count();
+ return fUniquelyKeyedProxyViewMap.count();
}
#endif
void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllRefs() {
SkAutoSpinlock lock{fSpinLock};
- fUniquelyKeyedProxyViews.foreach([this](Entry* v) { this->recycleEntry(v); });
- fUniquelyKeyedProxyViews.reset();
+ fUniquelyKeyedProxyViewMap.reset();
+ while (auto tmp = fUniquelyKeyedProxyViewList.head()) {
+ fUniquelyKeyedProxyViewList.remove(tmp);
+ this->recycleEntry(tmp);
+ }
+ // TODO: should we empty out the fFreeEntryList and reset fEntryAllocator?
}
void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllUniqueRefs() {
SkAutoSpinlock lock{fSpinLock};
- fUniquelyKeyedProxyViews.foreach([](Entry* v) {
- // problematic
- });
+ Entry* cur = fUniquelyKeyedProxyViewList.head();
+ Entry* next = cur ? cur->fNext : nullptr;
+
+ while (cur) {
+ if (cur->fView.proxy()->unique()) {
+ fUniquelyKeyedProxyViewMap.remove(cur->fKey);
+ fUniquelyKeyedProxyViewList.remove(cur);
+ this->recycleEntry(cur);
+ }
+
+ cur = next;
+ next = cur ? cur->fNext : nullptr;
+ }
}
GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::find(const GrUniqueKey& key) {
SkAutoSpinlock lock{fSpinLock};
- Entry* tmp = fUniquelyKeyedProxyViews.find(key);
+ Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
if (tmp) {
+ SkASSERT(fUniquelyKeyedProxyViewList.isInList(tmp));
+ // make the sought out entry the MRU
+ fUniquelyKeyedProxyViewList.remove(tmp);
+ fUniquelyKeyedProxyViewList.addToHead(tmp);
return tmp->fView;
}
return {};
}
+GrThreadSafeUniquelyKeyedProxyViewCache::Entry*
+GrThreadSafeUniquelyKeyedProxyViewCache::getEntry(const GrUniqueKey& key,
+ const GrSurfaceProxyView& view) {
+ Entry* entry;
+
+ if (fFreeEntryList) {
+ entry = fFreeEntryList;
+ fFreeEntryList = entry->fNext;
+ entry->fNext = nullptr;
+
+ entry->fKey = key;
+ entry->fView = view;
+ } else {
+ entry = fEntryAllocator.make<Entry>(key, view);
+ }
+
+ fUniquelyKeyedProxyViewList.addToHead(entry); // make 'entry' the MRU
+ fUniquelyKeyedProxyViewMap.add(entry);
+ return entry;
+}
+
+void GrThreadSafeUniquelyKeyedProxyViewCache::recycleEntry(Entry* dead) {
+ SkASSERT(!dead->fPrev && !dead->fNext && !dead->fList);
+
+ dead->fKey.reset();
+ dead->fView.reset();
+
+ dead->fNext = fFreeEntryList;
+ fFreeEntryList = dead;
+}
+
GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::internalAdd(
const GrUniqueKey& key,
const GrSurfaceProxyView& view) {
- Entry* tmp = fUniquelyKeyedProxyViews.find(key);
+ Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
if (!tmp) {
tmp = this->getEntry(key, view);
- fUniquelyKeyedProxyViews.add(tmp);
+
+ SkASSERT(fUniquelyKeyedProxyViewMap.find(key));
}
return tmp->fView;