• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 "include/gpu/graphite/Recording.h"
9 
10 #include "src/gpu/graphite/CommandBuffer.h"
11 #include "src/gpu/graphite/ContextPriv.h"
12 #include "src/gpu/graphite/Log.h"
13 #include "src/gpu/graphite/RecordingPriv.h"
14 #include "src/gpu/graphite/Resource.h"
15 #include "src/gpu/graphite/ResourceProvider.h"
16 #include "src/gpu/graphite/Surface_Graphite.h"
17 #include "src/gpu/graphite/TaskGraph.h"
18 #include "src/gpu/graphite/Texture.h"
19 #include "src/gpu/graphite/TextureProxy.h"
20 
21 #include <unordered_set>
22 
23 namespace skgpu::graphite {
24 
Recording(std::unique_ptr<TaskGraph> graph,std::unordered_set<sk_sp<TextureProxy>,ProxyHash> && nonVolatileLazyProxies,std::unordered_set<sk_sp<TextureProxy>,ProxyHash> && volatileLazyProxies,std::unique_ptr<LazyProxyData> targetProxyData)25 Recording::Recording(std::unique_ptr<TaskGraph> graph,
26                      std::unordered_set<sk_sp<TextureProxy>, ProxyHash>&& nonVolatileLazyProxies,
27                      std::unordered_set<sk_sp<TextureProxy>, ProxyHash>&& volatileLazyProxies,
28                      std::unique_ptr<LazyProxyData> targetProxyData)
29         : fGraph(std::move(graph))
30         , fNonVolatileLazyProxies(std::move(nonVolatileLazyProxies))
31         , fVolatileLazyProxies(std::move(volatileLazyProxies))
32         , fTargetProxyData(std::move(targetProxyData)) {}
33 
~Recording()34 Recording::~Recording() {}
35 
36 #if GRAPHITE_TEST_UTILS
isTargetProxyInstantiated() const37 bool Recording::isTargetProxyInstantiated() const {
38     return fTargetProxyData->lazyProxy()->isInstantiated();
39 }
40 #endif
41 
42 ////////////////////////////////////////////////////////////////////////////////
hasNonVolatileLazyProxies() const43 bool RecordingPriv::hasNonVolatileLazyProxies() const {
44     return !fRecording->fNonVolatileLazyProxies.empty();
45 }
46 
instantiateNonVolatileLazyProxies(ResourceProvider * resourceProvider)47 bool RecordingPriv::instantiateNonVolatileLazyProxies(ResourceProvider* resourceProvider) {
48     SkASSERT(this->hasNonVolatileLazyProxies());
49 
50     for (auto proxy : fRecording->fNonVolatileLazyProxies) {
51         if (!proxy->lazyInstantiate(resourceProvider)) {
52             return false;
53         }
54     }
55 
56     // Note: once all the lazy proxies have been instantiated, that's it - there are no more
57     // chances to instantiate.
58     fRecording->fNonVolatileLazyProxies.clear();
59     return true;
60 }
61 
hasVolatileLazyProxies() const62 bool RecordingPriv::hasVolatileLazyProxies() const {
63     return !fRecording->fVolatileLazyProxies.empty();
64 }
65 
instantiateVolatileLazyProxies(ResourceProvider * resourceProvider)66 bool RecordingPriv::instantiateVolatileLazyProxies(ResourceProvider* resourceProvider) {
67     SkASSERT(this->hasVolatileLazyProxies());
68 
69     for (auto proxy : fRecording->fVolatileLazyProxies) {
70         if (!proxy->lazyInstantiate(resourceProvider)) {
71             return false;
72         }
73     }
74 
75     return true;
76 }
77 
deinstantiateVolatileLazyProxies()78 void RecordingPriv::deinstantiateVolatileLazyProxies() {
79     if (!this->hasVolatileLazyProxies()) {
80         return;
81     }
82 
83     for (auto proxy : fRecording->fVolatileLazyProxies) {
84         SkASSERT(proxy->isVolatile());
85         proxy->deinstantiate();
86     }
87 }
88 
89 #if GRAPHITE_TEST_UTILS
numVolatilePromiseImages() const90 int RecordingPriv::numVolatilePromiseImages() const {
91     return fRecording->fVolatileLazyProxies.size();
92 }
93 
numNonVolatilePromiseImages() const94 int RecordingPriv::numNonVolatilePromiseImages() const {
95     return fRecording->fNonVolatileLazyProxies.size();
96 }
97 
hasTasks() const98 bool RecordingPriv::hasTasks() const { return fRecording->fGraph->hasTasks(); }
99 #endif
100 
addCommands(Context * context,CommandBuffer * commandBuffer,Surface * replaySurface,SkIVector replayTranslation)101 bool RecordingPriv::addCommands(Context* context,
102                                 CommandBuffer* commandBuffer,
103                                 Surface* replaySurface,
104                                 SkIVector replayTranslation) {
105     AutoDeinstantiateTextureProxy autoDeinstantiateTargetProxy(
106             fRecording->fTargetProxyData ? fRecording->fTargetProxyData->lazyProxy() : nullptr);
107 
108     const Texture* replayTarget = nullptr;
109     SkASSERT(SkToBool(fRecording->fTargetProxyData) == SkToBool(replaySurface));
110     ResourceProvider* resourceProvider = context->priv().resourceProvider();
111     if (fRecording->fTargetProxyData) {
112         if (!replaySurface) {
113             SKGPU_LOG_E("No surface provided to instantiate target texture proxy.");
114             return false;
115         }
116         TextureProxy* surfaceTexture = replaySurface->backingTextureProxy();
117         if (!surfaceTexture->instantiate(resourceProvider)) {
118             SKGPU_LOG_E("Could not instantiate target texture proxy.");
119             return false;
120         }
121         if (!fRecording->fTargetProxyData->lazyInstantiate(resourceProvider,
122                                                            surfaceTexture->refTexture())) {
123             SKGPU_LOG_E("Could not instantiate deferred texture proxy.");
124             return false;
125         }
126         replayTarget = surfaceTexture->texture();
127     }
128 
129     if (!fRecording->fGraph->addCommands(
130                 context, commandBuffer, {replayTarget, replayTranslation})) {
131         return false;
132     }
133     for (size_t i = 0; i < fRecording->fExtraResourceRefs.size(); ++i) {
134         commandBuffer->trackResource(fRecording->fExtraResourceRefs[i]);
135     }
136     return true;
137 }
138 
addResourceRef(sk_sp<Resource> resource)139 void RecordingPriv::addResourceRef(sk_sp<Resource> resource) {
140     fRecording->fExtraResourceRefs.push_back(std::move(resource));
141 }
142 
addTask(sk_sp<Task> task)143 void RecordingPriv::addTask(sk_sp<Task> task) {
144     fRecording->fGraph->prepend(std::move(task));
145 }
146 
LazyProxyData(const TextureInfo & textureInfo)147 Recording::LazyProxyData::LazyProxyData(const TextureInfo& textureInfo) {
148     fTargetProxy = TextureProxy::MakeFullyLazy(
149             textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, [this](ResourceProvider*) {
150                 SkASSERT(SkToBool(fTarget));
151                 return std::move(fTarget);
152             });
153 }
154 
lazyProxy()155 TextureProxy* Recording::LazyProxyData::lazyProxy() { return fTargetProxy.get(); }
156 
refLazyProxy()157 sk_sp<TextureProxy> Recording::LazyProxyData::refLazyProxy() { return fTargetProxy; }
158 
lazyInstantiate(ResourceProvider * resourceProvider,sk_sp<Texture> texture)159 bool Recording::LazyProxyData::lazyInstantiate(ResourceProvider* resourceProvider,
160                                                sk_sp<Texture> texture) {
161     fTarget = std::move(texture);
162     return fTargetProxy->lazyInstantiate(resourceProvider);
163 }
164 
165 } // namespace skgpu::graphite
166