blob: 4a401983c5a49129b2664b2ebb7b8e25cc3691ff [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 Phillips45593682020-09-18 16:16:33 -040010GrThreadSafeUniquelyKeyedProxyViewCache::GrThreadSafeUniquelyKeyedProxyViewCache()
11 : fFreeEntryList(nullptr) {
12}
Robert Phillips26f3aeb2020-09-16 10:57:32 -040013
14GrThreadSafeUniquelyKeyedProxyViewCache::~GrThreadSafeUniquelyKeyedProxyViewCache() {
Robert Phillips45593682020-09-18 16:16:33 -040015 this->dropAllRefs();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040016}
17
18#if GR_TEST_UTILS
19int GrThreadSafeUniquelyKeyedProxyViewCache::numEntries() const {
20 SkAutoSpinlock lock{fSpinLock};
21
Robert Phillips45593682020-09-18 16:16:33 -040022 return fUniquelyKeyedProxyViewMap.count();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040023}
24
Robert Phillips752f7e12020-09-18 12:28:59 -040025int GrThreadSafeUniquelyKeyedProxyViewCache::count() const {
Robert Phillips26f3aeb2020-09-16 10:57:32 -040026 SkAutoSpinlock lock{fSpinLock};
27
Robert Phillips45593682020-09-18 16:16:33 -040028 return fUniquelyKeyedProxyViewMap.count();
Robert Phillips26f3aeb2020-09-16 10:57:32 -040029}
30#endif
31
32void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllRefs() {
33 SkAutoSpinlock lock{fSpinLock};
34
Robert Phillips45593682020-09-18 16:16:33 -040035 fUniquelyKeyedProxyViewMap.reset();
36 while (auto tmp = fUniquelyKeyedProxyViewList.head()) {
37 fUniquelyKeyedProxyViewList.remove(tmp);
38 this->recycleEntry(tmp);
39 }
40 // TODO: should we empty out the fFreeEntryList and reset fEntryAllocator?
Robert Phillips26f3aeb2020-09-16 10:57:32 -040041}
42
Robert Phillips12d06a32020-09-16 12:31:34 -040043void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllUniqueRefs() {
44 SkAutoSpinlock lock{fSpinLock};
45
Robert Phillips45593682020-09-18 16:16:33 -040046 Entry* cur = fUniquelyKeyedProxyViewList.head();
47 Entry* next = cur ? cur->fNext : nullptr;
48
49 while (cur) {
50 if (cur->fView.proxy()->unique()) {
51 fUniquelyKeyedProxyViewMap.remove(cur->fKey);
52 fUniquelyKeyedProxyViewList.remove(cur);
53 this->recycleEntry(cur);
54 }
55
56 cur = next;
57 next = cur ? cur->fNext : nullptr;
58 }
Robert Phillips12d06a32020-09-16 12:31:34 -040059}
60
Robert Phillips26f3aeb2020-09-16 10:57:32 -040061GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::find(const GrUniqueKey& key) {
62 SkAutoSpinlock lock{fSpinLock};
63
Robert Phillips45593682020-09-18 16:16:33 -040064 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -040065 if (tmp) {
Robert Phillips45593682020-09-18 16:16:33 -040066 SkASSERT(fUniquelyKeyedProxyViewList.isInList(tmp));
67 // make the sought out entry the MRU
68 fUniquelyKeyedProxyViewList.remove(tmp);
69 fUniquelyKeyedProxyViewList.addToHead(tmp);
Robert Phillips752f7e12020-09-18 12:28:59 -040070 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -040071 }
72
73 return {};
74}
75
Robert Phillips45593682020-09-18 16:16:33 -040076GrThreadSafeUniquelyKeyedProxyViewCache::Entry*
77GrThreadSafeUniquelyKeyedProxyViewCache::getEntry(const GrUniqueKey& key,
78 const GrSurfaceProxyView& view) {
79 Entry* entry;
80
81 if (fFreeEntryList) {
82 entry = fFreeEntryList;
83 fFreeEntryList = entry->fNext;
84 entry->fNext = nullptr;
85
86 entry->fKey = key;
87 entry->fView = view;
88 } else {
89 entry = fEntryAllocator.make<Entry>(key, view);
90 }
91
92 fUniquelyKeyedProxyViewList.addToHead(entry); // make 'entry' the MRU
93 fUniquelyKeyedProxyViewMap.add(entry);
94 return entry;
95}
96
97void GrThreadSafeUniquelyKeyedProxyViewCache::recycleEntry(Entry* dead) {
98 SkASSERT(!dead->fPrev && !dead->fNext && !dead->fList);
99
100 dead->fKey.reset();
101 dead->fView.reset();
102
103 dead->fNext = fFreeEntryList;
104 fFreeEntryList = dead;
105}
106
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400107GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::internalAdd(
108 const GrUniqueKey& key,
109 const GrSurfaceProxyView& view) {
Robert Phillips45593682020-09-18 16:16:33 -0400110 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400111 if (!tmp) {
Robert Phillipsf3e2b3c2020-09-18 14:07:43 -0400112 tmp = this->getEntry(key, view);
Robert Phillips45593682020-09-18 16:16:33 -0400113
114 SkASSERT(fUniquelyKeyedProxyViewMap.find(key));
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400115 }
116
Robert Phillips752f7e12020-09-18 12:28:59 -0400117 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400118}
119
120GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::add(const GrUniqueKey& key,
121 const GrSurfaceProxyView& view) {
122 SkAutoSpinlock lock{fSpinLock};
123
124 return this->internalAdd(key, view);
125}