blob: 460454a7c0087899cbbd1bd0a15050cca5f5187e [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"
Chris Dalton6b498102019-08-01 14:14:52 -060012#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
38 for (const GrSurfaceProxyView& target : fTargets) {
39 if (this == drawingMgr->getLastRenderTask(target.proxy())) {
40 drawingMgr->setLastRenderTask(target.proxy(), nullptr);
41 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -040042 }
43}
44
Adlai Holler33d569e2020-06-16 14:30:08 -040045#ifdef SK_DEBUG
Adlai Hollerd71b7b02020-06-08 15:55:00 -040046GrRenderTask::~GrRenderTask() {
47 SkASSERT(this->isSetFlag(kDisowned_Flag));
Chris Dalton6b498102019-08-01 14:14:52 -060048}
49
Chris Dalton6b498102019-08-01 14:14:52 -060050bool GrRenderTask::deferredProxiesAreInstantiated() const {
51 for (int i = 0; i < fDeferredProxies.count(); ++i) {
52 if (!fDeferredProxies[i]->isInstantiated()) {
53 return false;
54 }
55 }
56
57 return true;
58}
59#endif
60
Chris Daltonaa3cbb82019-08-21 00:01:21 -060061void GrRenderTask::makeClosed(const GrCaps& caps) {
62 if (this->isClosed()) {
63 return;
64 }
65
Chris Dalton16a33c62019-09-24 22:19:17 -060066 SkIRect targetUpdateBounds;
67 if (ExpectedOutcome::kTargetDirty == this->onMakeClosed(caps, &targetUpdateBounds)) {
Adlai Holler33d569e2020-06-16 14:30:08 -040068 GrSurfaceProxy* proxy = this->target(0).proxy();
Greg Daniel16f5c652019-10-29 11:26:01 -040069 if (proxy->requiresManualMSAAResolve()) {
Adlai Holler33d569e2020-06-16 14:30:08 -040070 SkASSERT(this->target(0).asRenderTargetProxy());
71 this->target(0).asRenderTargetProxy()->markMSAADirty(targetUpdateBounds,
72 this->target(0).origin());
Chris Dalton4ece96d2019-08-30 11:26:39 -060073 }
Adlai Holler33d569e2020-06-16 14:30:08 -040074 GrTextureProxy* textureProxy = this->target(0).asTextureProxy();
Brian Salomon8c82a872020-07-21 12:09:58 -040075 if (textureProxy && GrMipmapped::kYes == textureProxy->mipmapped()) {
76 textureProxy->markMipmapsDirty();
Chris Daltonaa3cbb82019-08-21 00:01:21 -060077 }
78 }
79
Chris Daltone2a903e2019-09-18 13:41:50 -060080 if (fTextureResolveTask) {
81 this->addDependency(fTextureResolveTask);
82 fTextureResolveTask->makeClosed(caps);
83 fTextureResolveTask = nullptr;
84 }
85
Chris Daltonaa3cbb82019-08-21 00:01:21 -060086 this->setFlag(kClosed_Flag);
87}
88
Chris Dalton6b498102019-08-01 14:14:52 -060089void GrRenderTask::prepare(GrOpFlushState* flushState) {
90 for (int i = 0; i < fDeferredProxies.count(); ++i) {
91 fDeferredProxies[i]->texPriv().scheduleUpload(flushState);
92 }
93
94 this->onPrepare(flushState);
95}
96
97// Add a GrRenderTask-based dependency
98void GrRenderTask::addDependency(GrRenderTask* dependedOn) {
99 SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
Chris Daltondc9a74f2019-09-18 10:26:16 -0600100 SkASSERT(!this->dependsOn(dependedOn)); // caller should weed out duplicates
Chris Dalton6b498102019-08-01 14:14:52 -0600101
102 fDependencies.push_back(dependedOn);
103 dependedOn->addDependent(this);
104
105 SkDEBUGCODE(this->validate());
106}
107
Greg Danielc30f1a92019-09-06 15:28:58 -0400108void GrRenderTask::addDependenciesFromOtherTask(GrRenderTask* otherTask) {
109 SkASSERT(otherTask);
Chris Daltondc9a74f2019-09-18 10:26:16 -0600110 for (GrRenderTask* task : otherTask->fDependencies) {
Greg Danielc30f1a92019-09-06 15:28:58 -0400111 // The task should not be adding a dependency to itself.
Chris Daltondc9a74f2019-09-18 10:26:16 -0600112 SkASSERT(task != this);
113 if (!this->dependsOn(task)) {
114 this->addDependency(task);
115 }
Greg Danielc30f1a92019-09-06 15:28:58 -0400116 }
117}
118
Chris Dalton6b498102019-08-01 14:14:52 -0600119// Convert from a GrSurface-based dependency to a GrRenderTask one
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400120void GrRenderTask::addDependency(GrDrawingManager* drawingMgr, GrSurfaceProxy* dependedOn,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400121 GrMipmapped mipMapped,
Chris Dalton3d770272019-08-14 09:24:37 -0600122 GrTextureResolveManager textureResolveManager,
Chris Dalton08755122019-08-05 16:13:47 -0600123 const GrCaps& caps) {
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600124 // If it is still receiving dependencies, this GrRenderTask shouldn't be closed
125 SkASSERT(!this->isClosed());
Chris Dalton3d770272019-08-14 09:24:37 -0600126
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400127 GrRenderTask* dependedOnTask = drawingMgr->getLastRenderTask(dependedOn);
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600128
129 if (dependedOnTask == this) {
Chris Dalton4ece96d2019-08-30 11:26:39 -0600130 // self-read - presumably for dst reads. We don't need to do anything in this case. The
131 // XferProcessor will detect what is happening and insert a texture barrier.
Brian Salomon7e67dca2020-07-21 09:27:25 -0400132 SkASSERT(GrMipmapped::kNo == mipMapped);
Chris Dalton4ece96d2019-08-30 11:26:39 -0600133 // We should never attempt a self-read on a surface that has a separate MSAA renderbuffer.
134 SkASSERT(!dependedOn->requiresManualMSAAResolve());
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600135 SkASSERT(!dependedOn->asTextureProxy() ||
136 !dependedOn->asTextureProxy()->texPriv().isDeferred());
137 return;
138 }
139
140 if (dependedOnTask) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600141 if (this->dependsOn(dependedOnTask) || fTextureResolveTask == dependedOnTask) {
142 return; // don't add duplicate dependencies
143 }
144
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600145 // We are closing 'dependedOnTask' here bc the current contents of it are what 'this'
146 // renderTask depends on. We need a break in 'dependedOnTask' so that the usage of
147 // that state has a chance to execute.
148 dependedOnTask->makeClosed(caps);
149 }
150
Chris Dalton4ece96d2019-08-30 11:26:39 -0600151 auto resolveFlags = GrSurfaceProxy::ResolveFlags::kNone;
152
153 if (dependedOn->requiresManualMSAAResolve()) {
154 auto* renderTargetProxy = dependedOn->asRenderTargetProxy();
155 SkASSERT(renderTargetProxy);
156 if (renderTargetProxy->isMSAADirty()) {
157 resolveFlags |= GrSurfaceProxy::ResolveFlags::kMSAA;
158 }
159 }
160
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600161 GrTextureProxy* textureProxy = dependedOn->asTextureProxy();
Brian Salomon7e67dca2020-07-21 09:27:25 -0400162 if (GrMipmapped::kYes == mipMapped) {
Chris Dalton3d770272019-08-14 09:24:37 -0600163 SkASSERT(textureProxy);
Brian Salomon8c82a872020-07-21 12:09:58 -0400164 if (GrMipmapped::kYes != textureProxy->mipmapped()) {
Chris Dalton3d770272019-08-14 09:24:37 -0600165 // There are some cases where we might be given a non-mipmapped texture with a mipmap
166 // filter. See skbug.com/7094.
Brian Salomon7e67dca2020-07-21 09:27:25 -0400167 mipMapped = GrMipmapped::kNo;
Brian Salomon8c82a872020-07-21 12:09:58 -0400168 } else if (textureProxy->mipmapsAreDirty()) {
Chris Dalton4ece96d2019-08-30 11:26:39 -0600169 resolveFlags |= GrSurfaceProxy::ResolveFlags::kMipMaps;
Chris Dalton3d770272019-08-14 09:24:37 -0600170 }
171 }
172
Chris Dalton4ece96d2019-08-30 11:26:39 -0600173 // Does this proxy have msaa to resolve and/or mipmaps to regenerate?
174 if (GrSurfaceProxy::ResolveFlags::kNone != resolveFlags) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600175 if (!fTextureResolveTask) {
Adlai Holler039f90c2020-11-19 15:20:31 +0000176 fTextureResolveTask = textureResolveManager.newTextureResolveRenderTask(caps);
Chris Daltone2a903e2019-09-18 13:41:50 -0600177 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400178 fTextureResolveTask->addProxy(drawingMgr, sk_ref_sp(dependedOn), resolveFlags, caps);
Chris Daltone2a903e2019-09-18 13:41:50 -0600179
180 // addProxy() should have closed the texture proxy's previous task.
181 SkASSERT(!dependedOnTask || dependedOnTask->isClosed());
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400182 SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
Chris Dalton3d770272019-08-14 09:24:37 -0600183
Chris Dalton4ece96d2019-08-30 11:26:39 -0600184#ifdef SK_DEBUG
Chris Daltone2a903e2019-09-18 13:41:50 -0600185 // addProxy() should have called addDependency (in this instance, recursively) on
186 // fTextureResolveTask.
Chris Dalton4ece96d2019-08-30 11:26:39 -0600187 if (dependedOnTask) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600188 SkASSERT(fTextureResolveTask->dependsOn(dependedOnTask));
Chris Dalton4ece96d2019-08-30 11:26:39 -0600189 }
190 if (textureProxy && textureProxy->texPriv().isDeferred()) {
Chris Daltone2a903e2019-09-18 13:41:50 -0600191 SkASSERT(fTextureResolveTask->fDeferredProxies.back() == textureProxy);
Chris Dalton4ece96d2019-08-30 11:26:39 -0600192 }
Chris Dalton3d770272019-08-14 09:24:37 -0600193
Chris Dalton4ece96d2019-08-30 11:26:39 -0600194 // The GrTextureResolveRenderTask factory should have also marked the proxy clean, set the
Greg Danielf41b2bd2019-08-22 16:19:24 -0400195 // last renderTask on the textureProxy to textureResolveTask, and closed textureResolveTask.
Chris Dalton4ece96d2019-08-30 11:26:39 -0600196 if (GrRenderTargetProxy* renderTargetProxy = dependedOn->asRenderTargetProxy()) {
197 SkASSERT(!renderTargetProxy->isMSAADirty());
198 }
199 if (textureProxy) {
Brian Salomon8c82a872020-07-21 12:09:58 -0400200 SkASSERT(!textureProxy->mipmapsAreDirty());
Chris Dalton4ece96d2019-08-30 11:26:39 -0600201 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -0400202 SkASSERT(drawingMgr->getLastRenderTask(dependedOn) == fTextureResolveTask);
Chris Dalton4ece96d2019-08-30 11:26:39 -0600203#endif
Chris Daltone2a903e2019-09-18 13:41:50 -0600204 return;
205 }
Chris Dalton3d770272019-08-14 09:24:37 -0600206
Chris Daltone2a903e2019-09-18 13:41:50 -0600207 if (textureProxy && textureProxy->texPriv().isDeferred()) {
Chris Dalton3d770272019-08-14 09:24:37 -0600208 fDeferredProxies.push_back(textureProxy);
209 }
210
211 if (dependedOnTask) {
Chris Daltonaa3cbb82019-08-21 00:01:21 -0600212 this->addDependency(dependedOnTask);
Chris Dalton6b498102019-08-01 14:14:52 -0600213 }
Chris Dalton6b498102019-08-01 14:14:52 -0600214}
215
216bool GrRenderTask::dependsOn(const GrRenderTask* dependedOn) const {
217 for (int i = 0; i < fDependencies.count(); ++i) {
218 if (fDependencies[i] == dependedOn) {
219 return true;
220 }
221 }
222
223 return false;
224}
225
226
227void GrRenderTask::addDependent(GrRenderTask* dependent) {
228 fDependents.push_back(dependent);
229}
230
231#ifdef SK_DEBUG
232bool GrRenderTask::isDependedent(const GrRenderTask* dependent) const {
233 for (int i = 0; i < fDependents.count(); ++i) {
234 if (fDependents[i] == dependent) {
235 return true;
236 }
237 }
238
239 return false;
240}
241
242void GrRenderTask::validate() const {
243 // TODO: check for loops and duplicates
244
245 for (int i = 0; i < fDependencies.count(); ++i) {
246 SkASSERT(fDependencies[i]->isDependedent(this));
247 }
248}
249#endif
250
251void GrRenderTask::closeThoseWhoDependOnMe(const GrCaps& caps) {
252 for (int i = 0; i < fDependents.count(); ++i) {
253 if (!fDependents[i]->isClosed()) {
254 fDependents[i]->makeClosed(caps);
255 }
256 }
257}
258
259bool GrRenderTask::isInstantiated() const {
Robert Phillips07f675d2020-11-16 13:44:01 -0500260 for (const GrSurfaceProxyView& target : fTargets) {
261 GrSurfaceProxy* proxy = target.proxy();
262 if (!proxy->isInstantiated()) {
263 return false;
264 }
Greg Danielbbfec9d2019-08-20 10:56:51 -0400265
Robert Phillips07f675d2020-11-16 13:44:01 -0500266 GrSurface* surface = proxy->peekSurface();
267 if (surface->wasDestroyed()) {
268 return false;
269 }
Chris Dalton6b498102019-08-01 14:14:52 -0600270 }
271
272 return true;
273}
274
Adlai Holler33d569e2020-06-16 14:30:08 -0400275void GrRenderTask::addTarget(GrDrawingManager* drawingMgr, GrSurfaceProxyView view) {
276 SkASSERT(view);
Adlai Holler96ead542020-06-26 08:50:14 -0400277 SkASSERT(!this->isClosed());
278 SkASSERT(!fDrawingMgr || drawingMgr == fDrawingMgr);
279 SkDEBUGCODE(fDrawingMgr = drawingMgr);
Adlai Holler33d569e2020-06-16 14:30:08 -0400280 drawingMgr->setLastRenderTask(view.proxy(), this);
281 fTargets.push_back(std::move(view));
282}
283
John Stiles1e0136e2020-08-12 18:44:00 -0400284#if GR_TEST_UTILS
Chris Dalton6b498102019-08-01 14:14:52 -0600285void GrRenderTask::dump(bool printDependencies) const {
286 SkDebugf("--------------------------------------------------------------\n");
Adlai Holler33d569e2020-06-16 14:30:08 -0400287 SkDebugf("%s - renderTaskID: %d\n", this->name(), fUniqueID);
288
289 if (!fTargets.empty()) {
290 SkDebugf("Targets: \n");
Robert Phillips07f675d2020-11-16 13:44:01 -0500291 for (const GrSurfaceProxyView& target : fTargets) {
292 GrSurfaceProxy* proxy = target.proxy();
293 SkDebugf("proxyID: %d - surfaceID: %d\n",
Adlai Holler33d569e2020-06-16 14:30:08 -0400294 proxy ? proxy->uniqueID().asUInt() : -1,
295 proxy && proxy->peekSurface()
296 ? proxy->peekSurface()->uniqueID().asUInt()
297 : -1);
298 }
299 }
Chris Dalton6b498102019-08-01 14:14:52 -0600300
301 if (printDependencies) {
302 SkDebugf("I rely On (%d): ", fDependencies.count());
303 for (int i = 0; i < fDependencies.count(); ++i) {
304 SkDebugf("%d, ", fDependencies[i]->fUniqueID);
305 }
306 SkDebugf("\n");
307
308 SkDebugf("(%d) Rely On Me: ", fDependents.count());
309 for (int i = 0; i < fDependents.count(); ++i) {
310 SkDebugf("%d, ", fDependents[i]->fUniqueID);
311 }
312 SkDebugf("\n");
313 }
314}
315#endif