• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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