blob: 56748f40385572dd708855a4c7bdee418cc0d5c2 [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 Phillips187b04b2020-09-22 12:18:16 -040045void GrThreadSafeUniquelyKeyedProxyViewCache::dropAllUniqueRefs(GrResourceCache* resourceCache) {
Robert Phillips12d06a32020-09-16 12:31:34 -040046 SkAutoSpinlock lock{fSpinLock};
47
Robert Phillips187b04b2020-09-22 12:18:16 -040048 // Iterate from LRU to MRU
49 Entry* cur = fUniquelyKeyedProxyViewList.tail();
50 Entry* prev = cur ? cur->fPrev : nullptr;
Robert Phillips45593682020-09-18 16:16:33 -040051
52 while (cur) {
Robert Phillips187b04b2020-09-22 12:18:16 -040053 if (resourceCache && !resourceCache->overBudget()) {
54 return;
55 }
56
Robert Phillips45593682020-09-18 16:16:33 -040057 if (cur->fView.proxy()->unique()) {
58 fUniquelyKeyedProxyViewMap.remove(cur->fKey);
59 fUniquelyKeyedProxyViewList.remove(cur);
60 this->recycleEntry(cur);
61 }
62
Robert Phillips187b04b2020-09-22 12:18:16 -040063 cur = prev;
64 prev = cur ? cur->fPrev : nullptr;
Robert Phillips45593682020-09-18 16:16:33 -040065 }
Robert Phillips12d06a32020-09-16 12:31:34 -040066}
67
Robert Phillips26f3aeb2020-09-16 10:57:32 -040068GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::find(const GrUniqueKey& key) {
69 SkAutoSpinlock lock{fSpinLock};
70
Robert Phillips45593682020-09-18 16:16:33 -040071 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -040072 if (tmp) {
Robert Phillips45593682020-09-18 16:16:33 -040073 SkASSERT(fUniquelyKeyedProxyViewList.isInList(tmp));
74 // make the sought out entry the MRU
75 fUniquelyKeyedProxyViewList.remove(tmp);
76 fUniquelyKeyedProxyViewList.addToHead(tmp);
Robert Phillips752f7e12020-09-18 12:28:59 -040077 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -040078 }
79
80 return {};
81}
82
Robert Phillips45593682020-09-18 16:16:33 -040083GrThreadSafeUniquelyKeyedProxyViewCache::Entry*
84GrThreadSafeUniquelyKeyedProxyViewCache::getEntry(const GrUniqueKey& key,
85 const GrSurfaceProxyView& view) {
86 Entry* entry;
87
88 if (fFreeEntryList) {
89 entry = fFreeEntryList;
90 fFreeEntryList = entry->fNext;
91 entry->fNext = nullptr;
92
93 entry->fKey = key;
94 entry->fView = view;
95 } else {
96 entry = fEntryAllocator.make<Entry>(key, view);
97 }
98
99 fUniquelyKeyedProxyViewList.addToHead(entry); // make 'entry' the MRU
100 fUniquelyKeyedProxyViewMap.add(entry);
101 return entry;
102}
103
104void GrThreadSafeUniquelyKeyedProxyViewCache::recycleEntry(Entry* dead) {
105 SkASSERT(!dead->fPrev && !dead->fNext && !dead->fList);
106
107 dead->fKey.reset();
108 dead->fView.reset();
109
110 dead->fNext = fFreeEntryList;
111 fFreeEntryList = dead;
112}
113
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400114GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::internalAdd(
115 const GrUniqueKey& key,
116 const GrSurfaceProxyView& view) {
Robert Phillips45593682020-09-18 16:16:33 -0400117 Entry* tmp = fUniquelyKeyedProxyViewMap.find(key);
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400118 if (!tmp) {
Robert Phillipsf3e2b3c2020-09-18 14:07:43 -0400119 tmp = this->getEntry(key, view);
Robert Phillips45593682020-09-18 16:16:33 -0400120
121 SkASSERT(fUniquelyKeyedProxyViewMap.find(key));
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400122 }
123
Robert Phillips752f7e12020-09-18 12:28:59 -0400124 return tmp->fView;
Robert Phillips26f3aeb2020-09-16 10:57:32 -0400125}
126
127GrSurfaceProxyView GrThreadSafeUniquelyKeyedProxyViewCache::add(const GrUniqueKey& key,
128 const GrSurfaceProxyView& view) {
129 SkAutoSpinlock lock{fSpinLock};
130
131 return this->internalAdd(key, view);
132}