1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTask.h"
8*c8dee2aaSAndroid Build Coastguard Worker
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDrawingManager.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTargetProxy.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurface.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxyPriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureResolveManager.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureResolveRenderTask.h"
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
22*c8dee2aaSAndroid Build Coastguard Worker #include <atomic>
23*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
24*c8dee2aaSAndroid Build Coastguard Worker
CreateUniqueID()25*c8dee2aaSAndroid Build Coastguard Worker uint32_t GrRenderTask::CreateUniqueID() {
26*c8dee2aaSAndroid Build Coastguard Worker static std::atomic<uint32_t> nextID{1};
27*c8dee2aaSAndroid Build Coastguard Worker uint32_t id;
28*c8dee2aaSAndroid Build Coastguard Worker do {
29*c8dee2aaSAndroid Build Coastguard Worker id = nextID.fetch_add(1, std::memory_order_relaxed);
30*c8dee2aaSAndroid Build Coastguard Worker } while (id == SK_InvalidUniqueID);
31*c8dee2aaSAndroid Build Coastguard Worker return id;
32*c8dee2aaSAndroid Build Coastguard Worker }
33*c8dee2aaSAndroid Build Coastguard Worker
GrRenderTask()34*c8dee2aaSAndroid Build Coastguard Worker GrRenderTask::GrRenderTask()
35*c8dee2aaSAndroid Build Coastguard Worker : fUniqueID(CreateUniqueID())
36*c8dee2aaSAndroid Build Coastguard Worker , fFlags(0) {
37*c8dee2aaSAndroid Build Coastguard Worker }
38*c8dee2aaSAndroid Build Coastguard Worker
disown(GrDrawingManager * drawingMgr)39*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::disown(GrDrawingManager* drawingMgr) {
40*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fDrawingMgr || drawingMgr == fDrawingMgr);
41*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->isClosed());
42*c8dee2aaSAndroid Build Coastguard Worker if (this->isSetFlag(kDisowned_Flag)) {
43*c8dee2aaSAndroid Build Coastguard Worker return;
44*c8dee2aaSAndroid Build Coastguard Worker }
45*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(fDrawingMgr = nullptr);
46*c8dee2aaSAndroid Build Coastguard Worker this->setFlag(kDisowned_Flag);
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
49*c8dee2aaSAndroid Build Coastguard Worker if (this == drawingMgr->getLastRenderTask(target.get())) {
50*c8dee2aaSAndroid Build Coastguard Worker drawingMgr->setLastRenderTask(target.get(), nullptr);
51*c8dee2aaSAndroid Build Coastguard Worker }
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker
makeSkippable()55*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::makeSkippable() {
56*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->isClosed());
57*c8dee2aaSAndroid Build Coastguard Worker if (!this->isSkippable()) {
58*c8dee2aaSAndroid Build Coastguard Worker this->setFlag(kSkippable_Flag);
59*c8dee2aaSAndroid Build Coastguard Worker this->onMakeSkippable();
60*c8dee2aaSAndroid Build Coastguard Worker }
61*c8dee2aaSAndroid Build Coastguard Worker }
62*c8dee2aaSAndroid Build Coastguard Worker
63*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
~GrRenderTask()64*c8dee2aaSAndroid Build Coastguard Worker GrRenderTask::~GrRenderTask() {
65*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->isSetFlag(kDisowned_Flag));
66*c8dee2aaSAndroid Build Coastguard Worker }
67*c8dee2aaSAndroid Build Coastguard Worker
deferredProxiesAreInstantiated() const68*c8dee2aaSAndroid Build Coastguard Worker bool GrRenderTask::deferredProxiesAreInstantiated() const {
69*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDeferredProxies.size(); ++i) {
70*c8dee2aaSAndroid Build Coastguard Worker if (!fDeferredProxies[i]->isInstantiated()) {
71*c8dee2aaSAndroid Build Coastguard Worker return false;
72*c8dee2aaSAndroid Build Coastguard Worker }
73*c8dee2aaSAndroid Build Coastguard Worker }
74*c8dee2aaSAndroid Build Coastguard Worker
75*c8dee2aaSAndroid Build Coastguard Worker return true;
76*c8dee2aaSAndroid Build Coastguard Worker }
77*c8dee2aaSAndroid Build Coastguard Worker #endif
78*c8dee2aaSAndroid Build Coastguard Worker
makeClosed(GrRecordingContext * rContext)79*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::makeClosed(GrRecordingContext* rContext) {
80*c8dee2aaSAndroid Build Coastguard Worker if (this->isClosed()) {
81*c8dee2aaSAndroid Build Coastguard Worker return;
82*c8dee2aaSAndroid Build Coastguard Worker }
83*c8dee2aaSAndroid Build Coastguard Worker
84*c8dee2aaSAndroid Build Coastguard Worker SkIRect targetUpdateBounds;
85*c8dee2aaSAndroid Build Coastguard Worker if (ExpectedOutcome::kTargetDirty == this->onMakeClosed(rContext, &targetUpdateBounds)) {
86*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxy* proxy = this->target(0);
87*c8dee2aaSAndroid Build Coastguard Worker if (proxy->requiresManualMSAAResolve()) {
88*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->target(0)->asRenderTargetProxy());
89*c8dee2aaSAndroid Build Coastguard Worker this->target(0)->asRenderTargetProxy()->markMSAADirty(targetUpdateBounds);
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker GrTextureProxy* textureProxy = this->target(0)->asTextureProxy();
92*c8dee2aaSAndroid Build Coastguard Worker if (textureProxy && skgpu::Mipmapped::kYes == textureProxy->mipmapped()) {
93*c8dee2aaSAndroid Build Coastguard Worker textureProxy->markMipmapsDirty();
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker }
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Worker if (fTextureResolveTask) {
98*c8dee2aaSAndroid Build Coastguard Worker this->addDependency(fTextureResolveTask);
99*c8dee2aaSAndroid Build Coastguard Worker fTextureResolveTask->makeClosed(rContext);
100*c8dee2aaSAndroid Build Coastguard Worker fTextureResolveTask = nullptr;
101*c8dee2aaSAndroid Build Coastguard Worker }
102*c8dee2aaSAndroid Build Coastguard Worker
103*c8dee2aaSAndroid Build Coastguard Worker this->setFlag(kClosed_Flag);
104*c8dee2aaSAndroid Build Coastguard Worker }
105*c8dee2aaSAndroid Build Coastguard Worker
prepare(GrOpFlushState * flushState)106*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::prepare(GrOpFlushState* flushState) {
107*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDeferredProxies.size(); ++i) {
108*c8dee2aaSAndroid Build Coastguard Worker fDeferredProxies[i]->texPriv().scheduleUpload(flushState);
109*c8dee2aaSAndroid Build Coastguard Worker }
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker this->onPrepare(flushState);
112*c8dee2aaSAndroid Build Coastguard Worker }
113*c8dee2aaSAndroid Build Coastguard Worker
114*c8dee2aaSAndroid Build Coastguard Worker // Add a GrRenderTask-based dependency
addDependency(GrRenderTask * dependedOn)115*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::addDependency(GrRenderTask* dependedOn) {
116*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
117*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->dependsOn(dependedOn)); // caller should weed out duplicates
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker fDependencies.push_back(dependedOn);
120*c8dee2aaSAndroid Build Coastguard Worker dependedOn->addDependent(this);
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(this->validate());
123*c8dee2aaSAndroid Build Coastguard Worker }
124*c8dee2aaSAndroid Build Coastguard Worker
addDependenciesFromOtherTask(GrRenderTask * otherTask)125*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::addDependenciesFromOtherTask(GrRenderTask* otherTask) {
126*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(otherTask);
127*c8dee2aaSAndroid Build Coastguard Worker for (GrRenderTask* task : otherTask->fDependencies) {
128*c8dee2aaSAndroid Build Coastguard Worker // The task should not be adding a dependency to itself.
129*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(task != this);
130*c8dee2aaSAndroid Build Coastguard Worker if (!this->dependsOn(task)) {
131*c8dee2aaSAndroid Build Coastguard Worker this->addDependency(task);
132*c8dee2aaSAndroid Build Coastguard Worker }
133*c8dee2aaSAndroid Build Coastguard Worker }
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker
136*c8dee2aaSAndroid Build Coastguard Worker // Convert from a GrSurface-based dependency to a GrRenderTask one
addDependency(GrDrawingManager * drawingMgr,GrSurfaceProxy * dependedOn,skgpu::Mipmapped mipmapped,GrTextureResolveManager textureResolveManager,const GrCaps & caps)137*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::addDependency(GrDrawingManager* drawingMgr,
138*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxy* dependedOn,
139*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped mipmapped,
140*c8dee2aaSAndroid Build Coastguard Worker GrTextureResolveManager textureResolveManager,
141*c8dee2aaSAndroid Build Coastguard Worker const GrCaps& caps) {
142*c8dee2aaSAndroid Build Coastguard Worker // If it is still receiving dependencies, this GrRenderTask shouldn't be closed
143*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->isClosed());
144*c8dee2aaSAndroid Build Coastguard Worker
145*c8dee2aaSAndroid Build Coastguard Worker GrRenderTask* dependedOnTask = drawingMgr->getLastRenderTask(dependedOn);
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker if (dependedOnTask == this) {
148*c8dee2aaSAndroid Build Coastguard Worker // self-read - presumably for dst reads. We don't need to do anything in this case. The
149*c8dee2aaSAndroid Build Coastguard Worker // XferProcessor will detect what is happening and insert a texture barrier.
150*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(skgpu::Mipmapped::kNo == mipmapped);
151*c8dee2aaSAndroid Build Coastguard Worker // We should never attempt a self-read on a surface that has a separate MSAA renderbuffer.
152*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!dependedOn->requiresManualMSAAResolve());
153*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!dependedOn->asTextureProxy() ||
154*c8dee2aaSAndroid Build Coastguard Worker !dependedOn->asTextureProxy()->texPriv().isDeferred());
155*c8dee2aaSAndroid Build Coastguard Worker return;
156*c8dee2aaSAndroid Build Coastguard Worker }
157*c8dee2aaSAndroid Build Coastguard Worker
158*c8dee2aaSAndroid Build Coastguard Worker bool alreadyDependent = false;
159*c8dee2aaSAndroid Build Coastguard Worker if (dependedOnTask) {
160*c8dee2aaSAndroid Build Coastguard Worker if (this->dependsOn(dependedOnTask) || fTextureResolveTask == dependedOnTask) {
161*c8dee2aaSAndroid Build Coastguard Worker alreadyDependent = true;
162*c8dee2aaSAndroid Build Coastguard Worker dependedOnTask = nullptr; // don't add duplicate dependencies
163*c8dee2aaSAndroid Build Coastguard Worker } else if (!dependedOnTask->isSetFlag(kAtlas_Flag)) {
164*c8dee2aaSAndroid Build Coastguard Worker // We are closing 'dependedOnTask' here bc the current contents of it are what 'this'
165*c8dee2aaSAndroid Build Coastguard Worker // renderTask depends on. We need a break in 'dependedOnTask' so that the usage of
166*c8dee2aaSAndroid Build Coastguard Worker // that state has a chance to execute.
167*c8dee2aaSAndroid Build Coastguard Worker dependedOnTask->makeClosed(drawingMgr->getContext());
168*c8dee2aaSAndroid Build Coastguard Worker }
169*c8dee2aaSAndroid Build Coastguard Worker }
170*c8dee2aaSAndroid Build Coastguard Worker
171*c8dee2aaSAndroid Build Coastguard Worker auto resolveFlags = GrSurfaceProxy::ResolveFlags::kNone;
172*c8dee2aaSAndroid Build Coastguard Worker
173*c8dee2aaSAndroid Build Coastguard Worker if (dependedOn->requiresManualMSAAResolve()) {
174*c8dee2aaSAndroid Build Coastguard Worker auto* renderTargetProxy = dependedOn->asRenderTargetProxy();
175*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(renderTargetProxy);
176*c8dee2aaSAndroid Build Coastguard Worker if (renderTargetProxy->isMSAADirty()) {
177*c8dee2aaSAndroid Build Coastguard Worker resolveFlags |= GrSurfaceProxy::ResolveFlags::kMSAA;
178*c8dee2aaSAndroid Build Coastguard Worker }
179*c8dee2aaSAndroid Build Coastguard Worker }
180*c8dee2aaSAndroid Build Coastguard Worker
181*c8dee2aaSAndroid Build Coastguard Worker GrTextureProxy* textureProxy = dependedOn->asTextureProxy();
182*c8dee2aaSAndroid Build Coastguard Worker if (skgpu::Mipmapped::kYes == mipmapped) {
183*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(textureProxy);
184*c8dee2aaSAndroid Build Coastguard Worker if (skgpu::Mipmapped::kYes != textureProxy->mipmapped()) {
185*c8dee2aaSAndroid Build Coastguard Worker // There are some cases where we might be given a non-mipmapped texture with a mipmap
186*c8dee2aaSAndroid Build Coastguard Worker // filter. See skbug.com/7094.
187*c8dee2aaSAndroid Build Coastguard Worker mipmapped = skgpu::Mipmapped::kNo;
188*c8dee2aaSAndroid Build Coastguard Worker } else if (textureProxy->mipmapsAreDirty()) {
189*c8dee2aaSAndroid Build Coastguard Worker resolveFlags |= GrSurfaceProxy::ResolveFlags::kMipMaps;
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker }
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker // Does this proxy have msaa to resolve and/or mipmaps to regenerate?
194*c8dee2aaSAndroid Build Coastguard Worker if (GrSurfaceProxy::ResolveFlags::kNone != resolveFlags) {
195*c8dee2aaSAndroid Build Coastguard Worker if (!fTextureResolveTask) {
196*c8dee2aaSAndroid Build Coastguard Worker fTextureResolveTask = textureResolveManager.newTextureResolveRenderTask(caps);
197*c8dee2aaSAndroid Build Coastguard Worker }
198*c8dee2aaSAndroid Build Coastguard Worker fTextureResolveTask->addProxy(drawingMgr, sk_ref_sp(dependedOn), resolveFlags, caps);
199*c8dee2aaSAndroid Build Coastguard Worker
200*c8dee2aaSAndroid Build Coastguard Worker // addProxy() should have closed the texture proxy's previous task.
201*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!dependedOnTask || dependedOnTask->isClosed());
202*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
205*c8dee2aaSAndroid Build Coastguard Worker // addProxy() should have called addDependency (in this instance, recursively) on
206*c8dee2aaSAndroid Build Coastguard Worker // fTextureResolveTask.
207*c8dee2aaSAndroid Build Coastguard Worker if (dependedOnTask) {
208*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fTextureResolveTask->dependsOn(dependedOnTask));
209*c8dee2aaSAndroid Build Coastguard Worker }
210*c8dee2aaSAndroid Build Coastguard Worker if (textureProxy && textureProxy->texPriv().isDeferred()) {
211*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fTextureResolveTask->fDeferredProxies.back() == textureProxy);
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker
214*c8dee2aaSAndroid Build Coastguard Worker // The GrTextureResolveRenderTask factory should have also marked the proxy clean, set the
215*c8dee2aaSAndroid Build Coastguard Worker // last renderTask on the textureProxy to textureResolveTask, and closed textureResolveTask.
216*c8dee2aaSAndroid Build Coastguard Worker if (resolveFlags & GrSurfaceProxy::ResolveFlags::kMSAA) {
217*c8dee2aaSAndroid Build Coastguard Worker if (GrRenderTargetProxy* renderTargetProxy = dependedOn->asRenderTargetProxy()) {
218*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!renderTargetProxy->isMSAADirty());
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker if (textureProxy && (resolveFlags & GrSurfaceProxy::ResolveFlags::kMipMaps)) {
222*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!textureProxy->mipmapsAreDirty());
223*c8dee2aaSAndroid Build Coastguard Worker }
224*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
225*c8dee2aaSAndroid Build Coastguard Worker #endif
226*c8dee2aaSAndroid Build Coastguard Worker return;
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker
229*c8dee2aaSAndroid Build Coastguard Worker if (textureProxy && textureProxy->texPriv().isDeferred()) {
230*c8dee2aaSAndroid Build Coastguard Worker if (alreadyDependent) {
231*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(std::find(fDeferredProxies.begin(), fDeferredProxies.end(), textureProxy) !=
232*c8dee2aaSAndroid Build Coastguard Worker fDeferredProxies.end());
233*c8dee2aaSAndroid Build Coastguard Worker } else {
234*c8dee2aaSAndroid Build Coastguard Worker fDeferredProxies.push_back(textureProxy);
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker
238*c8dee2aaSAndroid Build Coastguard Worker if (dependedOnTask) {
239*c8dee2aaSAndroid Build Coastguard Worker this->addDependency(dependedOnTask);
240*c8dee2aaSAndroid Build Coastguard Worker }
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker
replaceDependency(const GrRenderTask * toReplace,GrRenderTask * replaceWith)243*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::replaceDependency(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
244*c8dee2aaSAndroid Build Coastguard Worker for (auto& target : fDependencies) {
245*c8dee2aaSAndroid Build Coastguard Worker if (target == toReplace) {
246*c8dee2aaSAndroid Build Coastguard Worker target = replaceWith;
247*c8dee2aaSAndroid Build Coastguard Worker replaceWith->fDependents.push_back(this);
248*c8dee2aaSAndroid Build Coastguard Worker break;
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker }
251*c8dee2aaSAndroid Build Coastguard Worker }
252*c8dee2aaSAndroid Build Coastguard Worker
replaceDependent(const GrRenderTask * toReplace,GrRenderTask * replaceWith)253*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::replaceDependent(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
254*c8dee2aaSAndroid Build Coastguard Worker for (auto& target : fDependents) {
255*c8dee2aaSAndroid Build Coastguard Worker if (target == toReplace) {
256*c8dee2aaSAndroid Build Coastguard Worker target = replaceWith;
257*c8dee2aaSAndroid Build Coastguard Worker replaceWith->fDependencies.push_back(this);
258*c8dee2aaSAndroid Build Coastguard Worker break;
259*c8dee2aaSAndroid Build Coastguard Worker }
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker
dependsOn(const GrRenderTask * dependedOn) const263*c8dee2aaSAndroid Build Coastguard Worker bool GrRenderTask::dependsOn(const GrRenderTask* dependedOn) const {
264*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDependencies.size(); ++i) {
265*c8dee2aaSAndroid Build Coastguard Worker if (fDependencies[i] == dependedOn) {
266*c8dee2aaSAndroid Build Coastguard Worker return true;
267*c8dee2aaSAndroid Build Coastguard Worker }
268*c8dee2aaSAndroid Build Coastguard Worker }
269*c8dee2aaSAndroid Build Coastguard Worker
270*c8dee2aaSAndroid Build Coastguard Worker return false;
271*c8dee2aaSAndroid Build Coastguard Worker }
272*c8dee2aaSAndroid Build Coastguard Worker
273*c8dee2aaSAndroid Build Coastguard Worker
addDependent(GrRenderTask * dependent)274*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::addDependent(GrRenderTask* dependent) {
275*c8dee2aaSAndroid Build Coastguard Worker fDependents.push_back(dependent);
276*c8dee2aaSAndroid Build Coastguard Worker }
277*c8dee2aaSAndroid Build Coastguard Worker
278*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
isDependent(const GrRenderTask * dependent) const279*c8dee2aaSAndroid Build Coastguard Worker bool GrRenderTask::isDependent(const GrRenderTask* dependent) const {
280*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDependents.size(); ++i) {
281*c8dee2aaSAndroid Build Coastguard Worker if (fDependents[i] == dependent) {
282*c8dee2aaSAndroid Build Coastguard Worker return true;
283*c8dee2aaSAndroid Build Coastguard Worker }
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker
286*c8dee2aaSAndroid Build Coastguard Worker return false;
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker
validate() const289*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::validate() const {
290*c8dee2aaSAndroid Build Coastguard Worker // TODO: check for loops and duplicates
291*c8dee2aaSAndroid Build Coastguard Worker
292*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDependencies.size(); ++i) {
293*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fDependencies[i]->isDependent(this));
294*c8dee2aaSAndroid Build Coastguard Worker }
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker #endif
297*c8dee2aaSAndroid Build Coastguard Worker
isInstantiated() const298*c8dee2aaSAndroid Build Coastguard Worker bool GrRenderTask::isInstantiated() const {
299*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
300*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxy* proxy = target.get();
301*c8dee2aaSAndroid Build Coastguard Worker if (!proxy->isInstantiated()) {
302*c8dee2aaSAndroid Build Coastguard Worker return false;
303*c8dee2aaSAndroid Build Coastguard Worker }
304*c8dee2aaSAndroid Build Coastguard Worker
305*c8dee2aaSAndroid Build Coastguard Worker GrSurface* surface = proxy->peekSurface();
306*c8dee2aaSAndroid Build Coastguard Worker if (surface->wasDestroyed()) {
307*c8dee2aaSAndroid Build Coastguard Worker return false;
308*c8dee2aaSAndroid Build Coastguard Worker }
309*c8dee2aaSAndroid Build Coastguard Worker }
310*c8dee2aaSAndroid Build Coastguard Worker
311*c8dee2aaSAndroid Build Coastguard Worker return true;
312*c8dee2aaSAndroid Build Coastguard Worker }
313*c8dee2aaSAndroid Build Coastguard Worker
addTarget(GrDrawingManager * drawingMgr,sk_sp<GrSurfaceProxy> proxy)314*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::addTarget(GrDrawingManager* drawingMgr, sk_sp<GrSurfaceProxy> proxy) {
315*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(proxy);
316*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->isClosed());
317*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fDrawingMgr || drawingMgr == fDrawingMgr);
318*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(fDrawingMgr = drawingMgr);
319*c8dee2aaSAndroid Build Coastguard Worker drawingMgr->setLastRenderTask(proxy.get(), this);
320*c8dee2aaSAndroid Build Coastguard Worker proxy->isUsedAsTaskTarget();
321*c8dee2aaSAndroid Build Coastguard Worker fTargets.emplace_back(std::move(proxy));
322*c8dee2aaSAndroid Build Coastguard Worker }
323*c8dee2aaSAndroid Build Coastguard Worker
324*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
dump(const SkString & label,SkString indent,bool printDependencies,bool close) const325*c8dee2aaSAndroid Build Coastguard Worker void GrRenderTask::dump(const SkString& label,
326*c8dee2aaSAndroid Build Coastguard Worker SkString indent,
327*c8dee2aaSAndroid Build Coastguard Worker bool printDependencies,
328*c8dee2aaSAndroid Build Coastguard Worker bool close) const {
329*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s%s --------------------------------------------------------------\n",
330*c8dee2aaSAndroid Build Coastguard Worker indent.c_str(),
331*c8dee2aaSAndroid Build Coastguard Worker label.c_str());
332*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s%s task - renderTaskID: %u\n", indent.c_str(), this->name(), fUniqueID);
333*c8dee2aaSAndroid Build Coastguard Worker
334*c8dee2aaSAndroid Build Coastguard Worker if (!fTargets.empty()) {
335*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%sTargets: \n", indent.c_str());
336*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
337*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(target);
338*c8dee2aaSAndroid Build Coastguard Worker SkString proxyStr = target->dump();
339*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s%s\n", indent.c_str(), proxyStr.c_str());
340*c8dee2aaSAndroid Build Coastguard Worker }
341*c8dee2aaSAndroid Build Coastguard Worker }
342*c8dee2aaSAndroid Build Coastguard Worker
343*c8dee2aaSAndroid Build Coastguard Worker if (printDependencies) {
344*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%sI rely On (%d): ", indent.c_str(), fDependencies.size());
345*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDependencies.size(); ++i) {
346*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%u, ", fDependencies[i]->fUniqueID);
347*c8dee2aaSAndroid Build Coastguard Worker }
348*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
349*c8dee2aaSAndroid Build Coastguard Worker
350*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s(%d) Rely On Me: ", indent.c_str(), fDependents.size());
351*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fDependents.size(); ++i) {
352*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%u, ", fDependents[i]->fUniqueID);
353*c8dee2aaSAndroid Build Coastguard Worker }
354*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
355*c8dee2aaSAndroid Build Coastguard Worker }
356*c8dee2aaSAndroid Build Coastguard Worker
357*c8dee2aaSAndroid Build Coastguard Worker if (close) {
358*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s--------------------------------------------------------------\n\n",
359*c8dee2aaSAndroid Build Coastguard Worker indent.c_str());
360*c8dee2aaSAndroid Build Coastguard Worker }
361*c8dee2aaSAndroid Build Coastguard Worker }
362*c8dee2aaSAndroid Build Coastguard Worker #endif
363