1 /*
2 * Copyright 2024 Google LLC
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/graphite/ScratchResourceManager.h"
9
10 #include "src/gpu/graphite/Resource.h"
11 #include "src/gpu/graphite/ResourceProvider.h"
12 #include "src/gpu/graphite/Texture.h"
13 #include "src/gpu/graphite/TextureProxy.h"
14
15 namespace skgpu::graphite {
16
17 #if defined(SK_DEBUG)
hasPendingReads() const18 bool ProxyReadCountMap::hasPendingReads() const {
19 bool hasPendingReads = false;
20 fCounts.foreach([&hasPendingReads](const TextureProxy*, int proxyReadCount) {
21 hasPendingReads |= (proxyReadCount > 0);
22 });
23 return hasPendingReads;
24 }
25 #endif
26
ScratchResourceManager(ResourceProvider * resourceProvider,std::unique_ptr<ProxyReadCountMap> proxyCounts)27 ScratchResourceManager::ScratchResourceManager(ResourceProvider* resourceProvider,
28 std::unique_ptr<ProxyReadCountMap> proxyCounts)
29 : fResourceProvider(resourceProvider)
30 , fProxyReadCounts(std::move(proxyCounts)) {
31 SkASSERT(resourceProvider);
32 SkASSERT(fProxyReadCounts);
33 }
34
~ScratchResourceManager()35 ScratchResourceManager::~ScratchResourceManager() {
36 SkASSERT(fUnavailable.empty());
37 SkASSERT(!fProxyReadCounts->hasPendingReads());
38 }
39
getScratchTexture(SkISize dimensions,const TextureInfo & info,std::string_view label)40 sk_sp<Texture> ScratchResourceManager::getScratchTexture(SkISize dimensions,
41 const TextureInfo& info,
42 std::string_view label) {
43 sk_sp<Texture> scratchTexture = fResourceProvider->findOrCreateScratchTexture(
44 dimensions, info, label, fUnavailable);
45 // Store the returned scratch texture into fUnavailable so that it is filtered from the
46 // ResourceCache when going through *this* ScratchResourceManager. But the scratch texture will
47 // remain visible to other Recorders.
48 SkASSERT(!fUnavailable.contains(scratchTexture.get()));
49 fUnavailable.add(scratchTexture.get());
50 return scratchTexture;
51 }
52
returnTexture(sk_sp<Texture> texture)53 void ScratchResourceManager::returnTexture(sk_sp<Texture> texture) {
54 // Fails if trying to return a resource that didn't come from getScratchTexture()
55 SkASSERT(fUnavailable.contains(texture.get()));
56 fUnavailable.remove(texture.get());
57 }
58
pushScope()59 void ScratchResourceManager::pushScope() {
60 // Push a null pointer to mark the beginning of the list of listeners in the next depth
61 fListenerStack.push_back(nullptr);
62 }
63
popScope()64 void ScratchResourceManager::popScope() {
65 // Must have at least the null element to start the scope being popped
66 SkASSERT(!fListenerStack.empty());
67
68 // TODO: Assert that the current sublist is empty (i.e. the back element is a null pointer) but
69 // for now skip over them and leave them un-invoked to keep the unconsumed scratch resources
70 // out of the pool so they remain valid in later recordings.
71 int n = 0;
72 while (fListenerStack.fromBack(n)) {
73 n++;
74 }
75 SkASSERT(n < fListenerStack.size() && fListenerStack.fromBack(n) == nullptr);
76 // Remove all non-null listeners after the most recent null entry AND the null entry
77 fListenerStack.pop_back_n(n + 1);
78 }
79
notifyResourcesConsumed()80 void ScratchResourceManager::notifyResourcesConsumed() {
81 // Should only be called inside a scope
82 SkASSERT(!fListenerStack.empty());
83
84 int n = 0;
85 while (PendingUseListener* listener = fListenerStack.fromBack(n)) {
86 listener->onUseCompleted(this);
87 n++;
88 }
89 SkASSERT(n < fListenerStack.size() && fListenerStack.fromBack(n) == nullptr);
90 // Remove all non-null listeners that were just invoked, but do not remove the null entry that
91 // marks the start of this scope boundary.
92 if (n > 0) {
93 fListenerStack.pop_back_n(n);
94 }
95 }
96
markResourceInUse(PendingUseListener * listener)97 void ScratchResourceManager::markResourceInUse(PendingUseListener* listener) {
98 // Should only be called inside a scope
99 SkASSERT(!fListenerStack.empty());
100 fListenerStack.push_back(listener);
101 }
102
103 } // namespace skgpu::graphite
104