blob: 1c15d66b8d9ce6110668ab30711bce531595cfda [file] [log] [blame]
Chris Dalton6b498102019-08-01 14:14:52 -06001/*
2 * Copyright 2019 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/GrRenderTask.h"
9
Greg Danielc0d69152020-10-08 14:59:00 -040010#include "src/gpu/GrAttachment.h"
Brian Salomonf7f54332020-07-28 09:23:35 -040011#include "src/gpu/GrRenderTarget.h"
Adlai Holler9e2c50e2021-02-09 14:41:52 -050012#include "src/gpu/GrTextureProxyPriv.h"
Chris Daltone2a903e2019-09-18 13:41:50 -060013#include "src/gpu/GrTextureResolveRenderTask.h"
Chris Dalton6b498102019-08-01 14:14:52 -060014
15uint32_t GrRenderTask::CreateUniqueID() {
16 static std::atomic<uint32_t> nextID{1};
17 uint32_t id;
18 do {
Adlai Holler4888cda2020-11-06 16:37:37 -050019 id = nextID.fetch_add(1, std::memory_order_relaxed);
Chris Dalton6b498102019-08-01 14:14:52 -060020 } while (id == SK_InvalidUniqueID);
21 return id;
22}
23
Greg Daniel16f5c652019-10-29 11:26:01 -040024GrRenderTask::GrRenderTask()
25 : fUniqueID(CreateUniqueID())
26 , fFlags(0) {
27}
28
Adlai Hollerd71b7b02020-06-08 15:55:00 -040029void GrRenderTask::disown(GrDrawingManager* drawingMgr) {
Adlai Holler96ead542020-06-26 08:50:14 -040030 SkASSERT(!fDrawingMgr || drawingMgr == fDrawingMgr);
31 SkASSERT(this->isClosed());
Adlai Hollerd71b7b02020-06-08 15:55:00 -040032 if (this->isSetFlag(kDisowned_Flag)) {
33 return;
Chris Dalton6b498102019-08-01 14:14:52 -060034 }
Adlai Holler96ead542020-06-26 08:50:14 -040035 SkDEBUGCODE(fDrawingMgr = nullptr);
Adlai Hollerd71b7b02020-06-08 15:55:00 -040036 this->setFlag(kDisowned_Flag);
Adlai Holler33d569e2020-06-16 14:30:08 -040037
Brian Salomon982127b2021-01-21 10:43:35 -050038 for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
39 if (this == drawingMgr->getLastRenderTask(target.get())) {
40 drawingMgr->setLastRenderTask(target.get(), nullptr);
Adlai Holler33d569e2020-06-16 14:30:08 -040041 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -040042 }
43}
44
Adlai Hollere9ea4142021-04-27 14:31:56 -040045void GrRenderTask::makeSkippable() {
Brian Salomond63638b2021-03-05 14:00:07 -050046 SkASSERT(this->isClosed());
Adlai Hollere9ea4142021-04-27 14:31:56 -040047 if (!this->isSkippable()) {
48 this->setFlag(kSkippable_Flag);
49 this->onMakeSkippable();
50 }
Brian Salomond63638b2021-03-05 14:00:07 -050051}
52
Adlai Holler33d569e2020-06-16 14:30:08 -040053#ifdef SK_DEBUG
Adlai Hollerd71b7b02020-06-08 15:55:00 -040054GrRenderTask::~GrRenderTask() {
55 SkASSERT(this->isSetFlag(kDisowned_Flag));
Chris Dalton6b498102019-08-01 14:14:52 -060056}
57
Adlai Holler9e2c50e2021-02-09 14:41:52 -050058bool GrRenderTask::deferredProxiesAreInstantiated() const {
59 for (int i = 0; i < fDeferredProxies.count(); ++i) {
60 if (!fDeferredProxies[i]->isInstantiated()) {
61 return false;
62 }
63 }
64
65 return true;
66}
Chris Dalton6b498102019-08-01 14:14:52 -060067#endif
68
Chris Daltonaa938ce2021-06-23 18:13:59 -060069void GrRenderTask::makeClosed(GrRecordingContext* rContext) {
Chris Daltonaa3cbb82019-08-21 00:01:21 -060070 if (this->isClosed()) {
71 return;
72 }
73
Chris Dalton16a33c62019-09-24 22:19:17 -060074 SkIRect targetUpdateBounds;
Chris Daltonaa938ce2021-06-23 18:13:59 -060075 if (ExpectedOutcome::kTargetDirty == this->onMakeClosed(rContext, &targetUpdateBounds)) {
Brian Salomon982127b2021-01-21 10:43:35 -050076 GrSurfaceProxy* proxy = this->target(0);
Greg Daniel16f5c652019-10-29 11:26:01 -040077 if (proxy->requiresManualMSAAResolve()) {
Brian Salomon982127b2021-01-21 10:43:35 -050078 SkASSERT(this->target(0)->asRenderTargetProxy());
79 this->target(0)->asRenderTargetProxy()->markMSAADirty(targetUpdateBounds);
Chris Dalton4ece96d2019-08-30 11:26:39 -060080 }
Brian Salomon982127b2021-01-21 10:43:35 -050081 GrTextureProxy* textureProxy = this->target(0)->asTextureProxy();
Brian Salomon8c82a872020-07-21 12:09:58 -040082 if (textureProxy && GrMipmapped::kYes == textureProxy->mipmapped()) {
83 textureProxy->markMipmapsDirty();
Chris Daltonaa3cbb82019-08-21 00:01:21 -060084 }
85 }
86
Chris Daltone2a903e2019-09-18 13:41:50 -060087 if (fTextureResolveTask) {
88 this->addDependency(fTextureResolveTask);
Chris Daltonaa938ce2021-06-23 18:13:59 -060089 fTextureResolveTask->makeClosed(rContext);
Chris Daltone2a903e2019-09-18 13:41:50 -060090 fTextureResolveTask = nullptr;
91 }
92
Chris Daltonaa3cbb82019-08-21 00:01:21 -060093 this->setFlag(kClosed_Flag);
94}
95
Adlai Holler9e2c50e2021-02-09 14:41:52 -050096void GrRenderTask::prepare(GrOpFlushState* flushState) {
97 for (int i = 0; i < fDeferredProxies.count(); ++i) {
98 fDeferredProxies[i]->texPriv().scheduleUpload(flushState);
99 }
100
101 this->onPrepare(flushState);
102}
103
Chris Dalton6b498102019-08-01 14:14:52 -0600104// Add a GrRenderTask-based dependency
105void GrRenderTask::addDependency(GrRenderTask* dependedOn) {
106 SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
Chris Daltondc9a74f2019-09-18 10:26:16 -0600107 SkASSERT(!this->dependsOn(dependedOn)); // caller should weed out duplicates
Chris Dalton6b498102019-08-01 14:14:52 -0600108
109 fDependencies.push_back(dependedOn);
110 dependedOn->addDependent(this);
111
112 SkDEBUGCODE(this->validate());
113}
114
Greg Danielc30f1a92019-09-06 15:28:58 -0400115void GrRenderTask::addDependenciesFromOtherTask(GrRenderTask* otherTask) {
116 SkASSERT(otherTask);
Chris Daltondc9a74f2019-09-18 10:26:16 -0600117 for (GrRenderTask* task : otherTask->fDependencies) {
Greg Danielc30f1a92019-09-06 15:28:58 -0400118 // The task should not be adding a dependency to itself.
Chris Daltondc9a74f2019-09-18 10:26:16 -0600119 SkASSERT(task != this);
120 if (!this->dependsOn(task)) {
121 this->addDependency(task);
122 }
Greg Danielc30f1a92019-09-06 15:28:58 -0400123 }
124}
125
Chris Dalton6b498102019-08-01 14:14:52 -0600126// Convert from a GrSurface-based dependency to a GrRenderTask one
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400127void GrRenderTask::addDependency(GrDrawingManager* drawingMgr, GrSurfaceProxy* dependedOn,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400128 GrMipmapped mipMapped,
Chris Dalton3d770272019-08-14 09:24:37 -0600129 GrTextureResolveManager textureResolveManager,
Chris Dalton08755122019-08-05 16:13:47 -0600130 const GrCaps& caps) {
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600131 // If it is still receiving dependencies, this GrRenderTask shouldn't be closed
132 SkASSERT(!this->isClosed());
Chris Dalton3d770272019-08-14 09:24:37 -0600133
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400134 GrRenderTask* dependedOnTask = drawingMgr->getLastRenderTask(dependedOn);
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600135
136 if (dependedOnTask == this) {
Chris Dalton4ece96d2019-08-30 11:26:39 -0600137 // self-read - presumably for dst reads. We don't need to do anything in this case. The
138 // XferProcessor will detect what is happening and insert a texture barrier.
Brian Salomon7e67dca2020-07-21 09:27:25 -0400139 SkASSERT(GrMipmapped::kNo == mipMapped);
Chris Dalton4ece96d2019-08-30 11:26:39 -0600140 // We should never attempt a self-read on a surface that has a separate MSAA renderbuffer.
141 SkASSERT(!dependedOn->requiresManualMSAAResolve());
Adlai Holler9e2c50e2021-02-09 14:41:52 -0500142 SkASSERT(!dependedOn->asTextureProxy() ||
143 !dependedOn->asTextureProxy()->texPriv().isDeferred());
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600144 return;
145 }
146
147 if (dependedOnTask) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600148 if (this->dependsOn(dependedOnTask) || fTextureResolveTask == dependedOnTask) {
149 return; // don't add duplicate dependencies
150 }
151
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600152 // We are closing 'dependedOnTask' here bc the current contents of it are what 'this'
153 // renderTask depends on. We need a break in 'dependedOnTask' so that the usage of
154 // that state has a chance to execute.
Chris Daltonaa938ce2021-06-23 18:13:59 -0600155 dependedOnTask->makeClosed(drawingMgr->getContext());
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600156 }
157
Chris Dalton4ece96d2019-08-30 11:26:39 -0600158 auto resolveFlags = GrSurfaceProxy::ResolveFlags::kNone;
159
160 if (dependedOn->requiresManualMSAAResolve()) {
161 auto* renderTargetProxy = dependedOn->asRenderTargetProxy();
162 SkASSERT(renderTargetProxy);
163 if (renderTargetProxy->isMSAADirty()) {
164 resolveFlags |= GrSurfaceProxy::ResolveFlags::kMSAA;
165 }
166 }
167
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600168 GrTextureProxy* textureProxy = dependedOn->asTextureProxy();
Brian Salomon7e67dca2020-07-21 09:27:25 -0400169 if (GrMipmapped::kYes == mipMapped) {
Chris Dalton3d770272019-08-14 09:24:37 -0600170 SkASSERT(textureProxy);
Brian Salomon8c82a872020-07-21 12:09:58 -0400171 if (GrMipmapped::kYes != textureProxy->mipmapped()) {
Chris Dalton3d770272019-08-14 09:24:37 -0600172 // There are some cases where we might be given a non-mipmapped texture with a mipmap
173 // filter. See skbug.com/7094.
Brian Salomon7e67dca2020-07-21 09:27:25 -0400174 mipMapped = GrMipmapped::kNo;
Brian Salomon8c82a872020-07-21 12:09:58 -0400175 } else if (textureProxy->mipmapsAreDirty()) {
Chris Dalton4ece96d2019-08-30 11:26:39 -0600176 resolveFlags |= GrSurfaceProxy::ResolveFlags::kMipMaps;
Chris Dalton3d770272019-08-14 09:24:37 -0600177 }
178 }
179
Chris Dalton4ece96d2019-08-30 11:26:39 -0600180 // Does this proxy have msaa to resolve and/or mipmaps to regenerate?
181 if (GrSurfaceProxy::ResolveFlags::kNone != resolveFlags) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600182 if (!fTextureResolveTask) {
Adlai Holler039f90c2020-11-19 15:20:31 +0000183 fTextureResolveTask = textureResolveManager.newTextureResolveRenderTask(caps);
Chris Daltone2a903e2019-09-18 13:41:50 -0600184 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400185 fTextureResolveTask->addProxy(drawingMgr, sk_ref_sp(dependedOn), resolveFlags, caps);
Chris Daltone2a903e2019-09-18 13:41:50 -0600186
187 // addProxy() should have closed the texture proxy's previous task.
188 SkASSERT(!dependedOnTask || dependedOnTask->isClosed());
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400189 SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
Chris Dalton3d770272019-08-14 09:24:37 -0600190
Chris Dalton4ece96d2019-08-30 11:26:39 -0600191#ifdef SK_DEBUG
Chris Daltone2a903e2019-09-18 13:41:50 -0600192 // addProxy() should have called addDependency (in this instance, recursively) on
193 // fTextureResolveTask.
Chris Dalton4ece96d2019-08-30 11:26:39 -0600194 if (dependedOnTask) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600195 SkASSERT(fTextureResolveTask->dependsOn(dependedOnTask));
Chris Dalton4ece96d2019-08-30 11:26:39 -0600196 }
Adlai Holler9e2c50e2021-02-09 14:41:52 -0500197 if (textureProxy && textureProxy->texPriv().isDeferred()) {
198 SkASSERT(fTextureResolveTask->fDeferredProxies.back() == textureProxy);
199 }
Chris Dalton3d770272019-08-14 09:24:37 -0600200
Chris Dalton4ece96d2019-08-30 11:26:39 -0600201 // The GrTextureResolveRenderTask factory should have also marked the proxy clean, set the
Greg Danielf41b2bd2019-08-22 16:19:24 -0400202 // last renderTask on the textureProxy to textureResolveTask, and closed textureResolveTask.
Chris Dalton4ece96d2019-08-30 11:26:39 -0600203 if (GrRenderTargetProxy* renderTargetProxy = dependedOn->asRenderTargetProxy()) {
204 SkASSERT(!renderTargetProxy->isMSAADirty());
205 }
206 if (textureProxy) {
Brian Salomon8c82a872020-07-21 12:09:58 -0400207 SkASSERT(!textureProxy->mipmapsAreDirty());
Chris Dalton4ece96d2019-08-30 11:26:39 -0600208 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400209 SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
Chris Dalton4ece96d2019-08-30 11:26:39 -0600210#endif
Chris Daltone2a903e2019-09-18 13:41:50 -0600211 return;
212 }
Chris Dalton3d770272019-08-14 09:24:37 -0600213
Adlai Holler9e2c50e2021-02-09 14:41:52 -0500214 if (textureProxy && textureProxy->texPriv().isDeferred()) {
215 fDeferredProxies.push_back(textureProxy);
216 }
217
Chris Dalton3d770272019-08-14 09:24:37 -0600218 if (dependedOnTask) {
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600219 this->addDependency(dependedOnTask);
Chris Dalton6b498102019-08-01 14:14:52 -0600220 }
Chris Dalton6b498102019-08-01 14:14:52 -0600221}
222
Herb Derbyf5b03fc2021-04-29 14:01:12 -0400223void GrRenderTask::replaceDependency(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
224 for (auto& target : fDependencies) {
225 if (target == toReplace) {
226 target = replaceWith;
227 replaceWith->fDependents.push_back(this);
228 break;
229 }
230 }
231}
232
233void GrRenderTask::replaceDependent(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
234 for (auto& target : fDependents) {
235 if (target == toReplace) {
236 target = replaceWith;
237 replaceWith->fDependencies.push_back(this);
238 break;
239 }
240 }
241}
242
Chris Dalton6b498102019-08-01 14:14:52 -0600243bool GrRenderTask::dependsOn(const GrRenderTask* dependedOn) const {
244 for (int i = 0; i < fDependencies.count(); ++i) {
245 if (fDependencies[i] == dependedOn) {
246 return true;
247 }
248 }
249
250 return false;
251}
252
253
254void GrRenderTask::addDependent(GrRenderTask* dependent) {
255 fDependents.push_back(dependent);
256}
257
258#ifdef SK_DEBUG
Adlai Holler78036082021-01-07 11:41:33 -0500259bool GrRenderTask::isDependent(const GrRenderTask* dependent) const {
Chris Dalton6b498102019-08-01 14:14:52 -0600260 for (int i = 0; i < fDependents.count(); ++i) {
261 if (fDependents[i] == dependent) {
262 return true;
263 }
264 }
265
266 return false;
267}
268
269void GrRenderTask::validate() const {
270 // TODO: check for loops and duplicates
271
272 for (int i = 0; i < fDependencies.count(); ++i) {
Adlai Holler78036082021-01-07 11:41:33 -0500273 SkASSERT(fDependencies[i]->isDependent(this));
Chris Dalton6b498102019-08-01 14:14:52 -0600274 }
275}
276#endif
277
Chris Dalton6b498102019-08-01 14:14:52 -0600278bool GrRenderTask::isInstantiated() const {
Brian Salomon982127b2021-01-21 10:43:35 -0500279 for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
280 GrSurfaceProxy* proxy = target.get();
Robert Phillips07f675d2020-11-16 13:44:01 -0500281 if (!proxy->isInstantiated()) {
282 return false;
283 }
Greg Danielbbfec9d2019-08-20 10:56:51 -0400284
Robert Phillips07f675d2020-11-16 13:44:01 -0500285 GrSurface* surface = proxy->peekSurface();
286 if (surface->wasDestroyed()) {
287 return false;
288 }
Chris Dalton6b498102019-08-01 14:14:52 -0600289 }
290
291 return true;
292}
293
Brian Salomon982127b2021-01-21 10:43:35 -0500294void GrRenderTask::addTarget(GrDrawingManager* drawingMgr, sk_sp<GrSurfaceProxy> proxy) {
295 SkASSERT(proxy);
Adlai Holler96ead542020-06-26 08:50:14 -0400296 SkASSERT(!this->isClosed());
297 SkASSERT(!fDrawingMgr || drawingMgr == fDrawingMgr);
298 SkDEBUGCODE(fDrawingMgr = drawingMgr);
Brian Salomon982127b2021-01-21 10:43:35 -0500299 drawingMgr->setLastRenderTask(proxy.get(), this);
Brian Salomond63638b2021-03-05 14:00:07 -0500300 proxy->isUsedAsTaskTarget();
Brian Salomon982127b2021-01-21 10:43:35 -0500301 fTargets.emplace_back(std::move(proxy));
Adlai Holler33d569e2020-06-16 14:30:08 -0400302}
303
John Stiles1e0136e2020-08-12 18:44:00 -0400304#if GR_TEST_UTILS
Robert Phillips047d5bb2021-01-08 13:39:19 -0500305void GrRenderTask::dump(const SkString& label,
306 SkString indent,
307 bool printDependencies,
308 bool close) const {
309 SkDebugf("%s%s --------------------------------------------------------------\n",
310 indent.c_str(),
311 label.c_str());
312 SkDebugf("%s%s task - renderTaskID: %d\n", indent.c_str(), this->name(), fUniqueID);
Adlai Holler33d569e2020-06-16 14:30:08 -0400313
314 if (!fTargets.empty()) {
Robert Phillips047d5bb2021-01-08 13:39:19 -0500315 SkDebugf("%sTargets: \n", indent.c_str());
Brian Salomon982127b2021-01-21 10:43:35 -0500316 for (const sk_sp<GrSurfaceProxy>& target : fTargets) {
317 SkASSERT(target);
318 SkString proxyStr = target->dump();
319 SkDebugf("%s%s\n", indent.c_str(), proxyStr.c_str());
Adlai Holler33d569e2020-06-16 14:30:08 -0400320 }
321 }
Chris Dalton6b498102019-08-01 14:14:52 -0600322
323 if (printDependencies) {
Robert Phillips047d5bb2021-01-08 13:39:19 -0500324 SkDebugf("%sI rely On (%d): ", indent.c_str(), fDependencies.count());
Chris Dalton6b498102019-08-01 14:14:52 -0600325 for (int i = 0; i < fDependencies.count(); ++i) {
326 SkDebugf("%d, ", fDependencies[i]->fUniqueID);
327 }
328 SkDebugf("\n");
329
Robert Phillips047d5bb2021-01-08 13:39:19 -0500330 SkDebugf("%s(%d) Rely On Me: ", indent.c_str(), fDependents.count());
Chris Dalton6b498102019-08-01 14:14:52 -0600331 for (int i = 0; i < fDependents.count(); ++i) {
332 SkDebugf("%d, ", fDependents[i]->fUniqueID);
333 }
334 SkDebugf("\n");
335 }
Robert Phillips047d5bb2021-01-08 13:39:19 -0500336
337 if (close) {
338 SkDebugf("%s--------------------------------------------------------------\n\n",
339 indent.c_str());
340 }
Chris Dalton6b498102019-08-01 14:14:52 -0600341}
342#endif