blob: b776e798178ffa4984d8c8f718fe948c924ec1f3 [file] [log] [blame]
Robert Phillips26f3aeb2020-09-16 10:57:32 -04001/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/GrThreadSafeUniquelyKeyedProxyViewCache.h"
9
Robert Phillips187b04b2020-09-22 12:18:16 -040010#include "src/gpu/GrResourceCache.h"
11
Robert Phillips45593682020-09-18 16:16:33 -040012GrThreadSafeUniquelyKeyedProxyViewCache::GrThreadSafeUniquelyKeyedProxyViewCache()
13 : fFreeEntryList(nullptr) {
14}
Robert Phillips26f3aeb2020-09-16 10:57:32 -040015
16GrThreadSafeUniquelyKeyedProxyViewCache::~GrThreadSafeUniquelyKeyedProxyViewCache() {
Robert Phillips45593682020-09-18 16:16:33 -040017 this->dropAllRefs();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040018}
19
20#if GR_TEST_UTILS
21int GrThreadSafeUniquelyKeyedProxyViewCache::numEntries() const {
22 SkAutoSpinlock lock{fSpinLock};
23
Robert Phillips45593682020-09-18 16:16:33 -040024 return fUniquelyKeyedProxyViewMap.count();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040025}
26
Robert Phillipsc61c8952020-09-22 14:24:43 -040027size_t GrThreadSafeUniquelyKeyedProxyViewCache::approxBytesUsedForHash() const {
Robert Phillips26f3aeb2020-09-16 10:57:32 -040028 SkAutoSpinlock lock{fSpinLock};
29
Robert Phillipsc61c8952020-09-22 14:24:43 -040030 return fUniquelyKeyedProxyViewMap.approxBytesUsed();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040031}
32#endif
33
34void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllRefs() {
35 SkAutoSpinlock lock{fSpinLock};
36
Robert Phillips45593682020-09-18 16:16:33 -040037 fUniquelyKeyedProxyViewMap.reset();
38 while (auto tmp = fUniquelyKeyedProxyViewList.head()) {
39 fUniquelyKeyedProxyViewList.remove(tmp);
40 this->recycleEntry(tmp);
41 }
42 // TODO: should we empty out the fFreeEntryList and reset fEntryAllocator?
Robert Phillips26f3aeb2020-09-16 10:57:32 -040043}
44
Robert Phillips331699c2020-09-22 15:20:01 -040045// TODO: add an atomic flag so we know when it is worthwhile to iterate
46void GrThreadSafeUniquelyKeyedProxyViewCache::dropUniqueRefs(GrResourceCache* resourceCache) {
Robert Phillips12d06a32020-09-16 12:31:34 -040047 SkAutoSpinlock lock{fSpinLock};
48
Robert Phillips187b04b2020-09-22 12:18:16 -040049 // Iterate from LRU to MRU
50 Entry* cur = fUniquelyKeyedProxyViewList.tail();
51 Entry* prev = cur ? cur->fPrev : nullptr;
Robert Phillips45593682020-09-18 16:16:33 -040052
53 while (cur) {
Robert Phillips187b04b2020-09-22 12:18:16 -040054 if (resourceCache && !resourceCache->overBudget()) {
55 return;
56 }
57
Robert Phillips45593682020-09-18 16:16:33 -040058 if (cur->fView.proxy()->unique()) {
59 fUniquelyKeyedProxyViewMap.remove(cur->fKey);
60 fUniquelyKeyedProxyViewList.remove(cur);
61 this->recycleEntry(cur);
62 }
63
Robert Phillips187b04b2020-09-22 12:18:16 -040064 cur = prev;
65 prev = cur ? cur->fPrev : nullptr;
Robert Phillips45593682020-09-18 16:16:33 -040066 }
Robert Phillips12d06a32020-09-16 12:31:34 -040067}
68
Robert Phillipsc2fe1642020-09-22 17:34:51 -040069void GrThreadSafeUniquelyKeyedProxyViewCache::dropUniqueRefsOlderThan(
70 GrStdSteadyClock::time_point purgeTime) {
71 SkAutoSpinlock lock{fSpinLock};
72
73 // Iterate from LRU to MRU
74 Entry* cur = fUniquelyKeyedProxyViewList.tail();
75 Entry* prev = cur ? cur->fPrev : nullptr;
76
77 while (cur) {
78 if (cur->fLastAccess >= purgeTime) {
79 // This entry and all the remaining ones in the list will be newer than 'purgeTime'
80 return;
81 }
82
83 if (cur->fView.proxy()->unique()) {
84 fUniquelyKeyedProxyViewMap.remove(cur->fKey);
85 fUniquelyKeyedProxyViewList.remove(cur);
86 this->recycleEntry(cur);
87 }
88
89 cur = prev;
90 prev = cur ? cur->fPrev : nullptr;
91 }
92}
93
Robert Phillips26f3aeb2020-09-16 10:57:32 -040094GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::find(const GrUniqueKey& key) {
95 SkAutoSpinlock lock{fSpinLock};
96
Robert Phillips45593682020-09-18 16:16:33 -040097 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -040098 if (tmp) {
Robert Phillips45593682020-09-18 16:16:33 -040099 SkASSERT(fUniquelyKeyedProxyViewList.isInList(tmp));
100 // make the sought out entry the MRU
Robert Phillipsc2fe1642020-09-22 17:34:51 -0400101 tmp->fLastAccess = GrStdSteadyClock::now();
Robert Phillips45593682020-09-18 16:16:33 -0400102 fUniquelyKeyedProxyViewList.remove(tmp);
103 fUniquelyKeyedProxyViewList.addToHead(tmp);
Robert Phillips752f7e12020-09-18 12:28:59 -0400104 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400105 }
106
107 return {};
108}
109
Robert Phillips45593682020-09-18 16:16:33 -0400110GrThreadSafeUniquelyKeyedProxyViewCache::Entry*
111GrThreadSafeUniquelyKeyedProxyViewCache::getEntry(const GrUniqueKey& key,
112 const GrSurfaceProxyView& view) {
113 Entry* entry;
114
115 if (fFreeEntryList) {
116 entry = fFreeEntryList;
117 fFreeEntryList = entry->fNext;
118 entry->fNext = nullptr;
119
120 entry->fKey = key;
121 entry->fView = view;
122 } else {
123 entry = fEntryAllocator.make<Entry>(key, view);
124 }
125
Robert Phillipsc2fe1642020-09-22 17:34:51 -0400126 // make 'entry' the MRU
127 entry->fLastAccess = GrStdSteadyClock::now();
128 fUniquelyKeyedProxyViewList.addToHead(entry);
Robert Phillips45593682020-09-18 16:16:33 -0400129 fUniquelyKeyedProxyViewMap.add(entry);
130 return entry;
131}
132
133void GrThreadSafeUniquelyKeyedProxyViewCache::recycleEntry(Entry* dead) {
134 SkASSERT(!dead->fPrev && !dead->fNext && !dead->fList);
135
136 dead->fKey.reset();
137 dead->fView.reset();
138
139 dead->fNext = fFreeEntryList;
140 fFreeEntryList = dead;
141}
142
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400143GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::internalAdd(
144 const GrUniqueKey& key,
145 const GrSurfaceProxyView& view) {
Robert Phillips45593682020-09-18 16:16:33 -0400146 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400147 if (!tmp) {
Robert Phillipsf3e2b3c2020-09-18 14:07:43 -0400148 tmp = this->getEntry(key, view);
Robert Phillips45593682020-09-18 16:16:33 -0400149
150 SkASSERT(fUniquelyKeyedProxyViewMap.find(key));
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400151 }
152
Robert Phillips752f7e12020-09-18 12:28:59 -0400153 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400154}
155
156GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::add(const GrUniqueKey& key,
157 const GrSurfaceProxyView& view) {
158 SkAutoSpinlock lock{fSpinLock};
159
160 return this->internalAdd(key, view);
161}