blob: 6704a434f4d861eb0faa3168bc50bd326115d4c5 [file] [log] [blame]
Robert Phillipsf2361d22016-10-25 14:20:06 -04001/*
2 * Copyright 2016 Google Inc.
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/private/GrOpList.h"
Robert Phillips5efd5ea2017-05-30 13:47:32 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContext.h"
11#include "include/private/GrSurfaceProxy.h"
12#include "src/gpu/GrDeferredProxyUploader.h"
13#include "src/gpu/GrMemoryPool.h"
14#include "src/gpu/GrRenderTargetPriv.h"
15#include "src/gpu/GrTextureProxyPriv.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050016#include <atomic>
Robert Phillipsc589b0b2017-04-17 07:53:07 -040017
Robert Phillipsc0138922017-03-08 11:50:55 -050018uint32_t GrOpList::CreateUniqueID() {
Mike Klein0ec1c572018-12-04 11:52:51 -050019 static std::atomic<uint32_t> nextID{1};
Robert Phillipsc0138922017-03-08 11:50:55 -050020 uint32_t id;
Robert Phillipsc0138922017-03-08 11:50:55 -050021 do {
Mike Klein0ec1c572018-12-04 11:52:51 -050022 id = nextID++;
Robert Phillipsc0138922017-03-08 11:50:55 -050023 } while (id == SK_InvalidUniqueID);
24 return id;
25}
26
Robert Phillips12c46292019-04-23 07:36:17 -040027GrOpList::GrOpList(sk_sp<GrOpMemoryPool> opMemoryPool,
28 sk_sp<GrSurfaceProxy> surfaceProxy,
29 GrAuditTrail* auditTrail)
Robert Phillipsc994a932018-06-19 13:09:54 -040030 : fOpMemoryPool(std::move(opMemoryPool))
31 , fAuditTrail(auditTrail)
32 , fUniqueID(CreateUniqueID())
33 , fFlags(0) {
34 SkASSERT(fOpMemoryPool);
Robert Phillips3d4cac52019-06-11 08:08:08 -040035 fTarget.setProxy(std::move(surfaceProxy));
Robert Phillips6cdc22c2017-05-11 16:29:14 -040036 fTarget.get()->setLastOpList(this);
Robert Phillipsf2361d22016-10-25 14:20:06 -040037}
38
39GrOpList::~GrOpList() {
Chris Daltona84cacf2017-10-04 10:30:29 -060040 if (fTarget.get() && this == fTarget.get()->getLastOpList()) {
41 // Ensure the target proxy doesn't keep hold of a dangling back pointer.
42 fTarget.get()->setLastOpList(nullptr);
43 }
Robert Phillipsf2361d22016-10-25 14:20:06 -040044}
45
Robert Phillips7eeb74f2019-03-29 07:26:46 -040046// TODO: this can go away when explicit allocation has stuck
Robert Phillips318c4192017-05-17 09:36:38 -040047bool GrOpList::instantiate(GrResourceProvider* resourceProvider) {
Robert Phillips12c46292019-04-23 07:36:17 -040048 SkASSERT(fTarget.get()->isInstantiated());
49 return true;
Robert Phillips318c4192017-05-17 09:36:38 -040050}
51
Chris Daltona84cacf2017-10-04 10:30:29 -060052void GrOpList::endFlush() {
Robert Phillips6cdc22c2017-05-11 16:29:14 -040053 if (fTarget.get() && this == fTarget.get()->getLastOpList()) {
54 fTarget.get()->setLastOpList(nullptr);
55 }
56
Robert Phillips5efd5ea2017-05-30 13:47:32 -040057 fTarget.reset();
Brian Osman099fa0f2017-10-02 16:38:32 -040058 fDeferredProxies.reset();
Robert Phillips6cdc22c2017-05-11 16:29:14 -040059 fAuditTrail = nullptr;
60}
61
Brian Osman099fa0f2017-10-02 16:38:32 -040062void GrOpList::instantiateDeferredProxies(GrResourceProvider* resourceProvider) {
63 for (int i = 0; i < fDeferredProxies.count(); ++i) {
Robert Phillips12c46292019-04-23 07:36:17 -040064 SkASSERT(fDeferredProxies[i]->isInstantiated());
Brian Osman099fa0f2017-10-02 16:38:32 -040065 }
Brian Osman5d034742017-09-11 13:38:55 -040066}
67
Brian Osman407b3422017-08-22 15:01:32 -040068void GrOpList::prepare(GrOpFlushState* flushState) {
Brian Osman099fa0f2017-10-02 16:38:32 -040069 for (int i = 0; i < fDeferredProxies.count(); ++i) {
70 fDeferredProxies[i]->texPriv().scheduleUpload(flushState);
Brian Osman407b3422017-08-22 15:01:32 -040071 }
72
73 this->onPrepare(flushState);
74}
75
Robert Phillipsf2361d22016-10-25 14:20:06 -040076// Add a GrOpList-based dependency
77void GrOpList::addDependency(GrOpList* dependedOn) {
78 SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
79
80 if (this->dependsOn(dependedOn)) {
81 return; // don't add duplicate dependencies
82 }
83
Robert Phillips73fd0d62017-09-15 11:48:08 +000084 fDependencies.push_back(dependedOn);
Robert Phillipse6d06182018-08-06 16:56:26 -040085 dependedOn->addDependent(this);
86
87 SkDEBUGCODE(this->validate());
Robert Phillipsf2361d22016-10-25 14:20:06 -040088}
89
90// Convert from a GrSurface-based dependency to a GrOpList one
Robert Phillipsee683652017-04-26 11:53:10 -040091void GrOpList::addDependency(GrSurfaceProxy* dependedOn, const GrCaps& caps) {
Robert Phillipsf2361d22016-10-25 14:20:06 -040092 if (dependedOn->getLastOpList()) {
93 // If it is still receiving dependencies, this GrOpList shouldn't be closed
94 SkASSERT(!this->isClosed());
95
96 GrOpList* opList = dependedOn->getLastOpList();
97 if (opList == this) {
Robert Phillipsce3c28f2018-07-18 13:52:40 -040098 // self-read - presumably for dst reads. We can't make it closed in the self-read case.
Robert Phillipsf2361d22016-10-25 14:20:06 -040099 } else {
100 this->addDependency(opList);
101
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400102 // We are closing 'opList' here bc the current contents of it are what 'this' opList
103 // depends on. We need a break in 'opList' so that the usage of that state has a
104 // chance to execute.
Robert Phillipsee683652017-04-26 11:53:10 -0400105 opList->makeClosed(caps);
Robert Phillipsf2361d22016-10-25 14:20:06 -0400106 }
107 }
Brian Osman099fa0f2017-10-02 16:38:32 -0400108
109 if (GrTextureProxy* textureProxy = dependedOn->asTextureProxy()) {
110 if (textureProxy->texPriv().isDeferred()) {
111 fDeferredProxies.push_back(textureProxy);
112 }
113 }
Robert Phillipsf2361d22016-10-25 14:20:06 -0400114}
115
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400116bool GrOpList::dependsOn(const GrOpList* dependedOn) const {
117 for (int i = 0; i < fDependencies.count(); ++i) {
118 if (fDependencies[i] == dependedOn) {
119 return true;
120 }
121 }
122
123 return false;
124}
125
Robert Phillipse6d06182018-08-06 16:56:26 -0400126
127void GrOpList::addDependent(GrOpList* dependent) {
128 fDependents.push_back(dependent);
129}
130
131#ifdef SK_DEBUG
132bool GrOpList::isDependedent(const GrOpList* dependent) const {
133 for (int i = 0; i < fDependents.count(); ++i) {
134 if (fDependents[i] == dependent) {
135 return true;
136 }
137 }
138
139 return false;
140}
141
142void GrOpList::validate() const {
143 // TODO: check for loops and duplicates
144
145 for (int i = 0; i < fDependencies.count(); ++i) {
146 SkASSERT(fDependencies[i]->isDependedent(this));
147 }
148}
149#endif
150
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400151bool GrOpList::isInstantiated() const { return fTarget.get()->isInstantiated(); }
Robert Phillips09dfc472017-09-13 15:25:47 -0400152
Robert Phillips46acf9d2018-10-09 09:31:40 -0400153void GrOpList::closeThoseWhoDependOnMe(const GrCaps& caps) {
154 for (int i = 0; i < fDependents.count(); ++i) {
155 if (!fDependents[i]->isClosed()) {
156 fDependents[i]->makeClosed(caps);
157 }
158 }
159}
160
Robert Phillips01a91282018-07-26 08:03:04 -0400161bool GrOpList::isFullyInstantiated() const {
162 if (!this->isInstantiated()) {
163 return false;
164 }
165
166 GrSurfaceProxy* proxy = fTarget.get();
167 bool needsStencil = proxy->asRenderTargetProxy()
168 ? proxy->asRenderTargetProxy()->needsStencil()
169 : false;
170
171 if (needsStencil) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400172 GrRenderTarget* rt = proxy->peekRenderTarget();
Robert Phillips01a91282018-07-26 08:03:04 -0400173
174 if (!rt->renderTargetPriv().getStencilAttachment()) {
175 return false;
176 }
177 }
178
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400179 GrSurface* surface = proxy->peekSurface();
180 if (surface->wasDestroyed()) {
181 return false;
182 }
183
Robert Phillips01a91282018-07-26 08:03:04 -0400184 return true;
185}
186
Robert Phillips4150eea2018-02-07 17:08:21 -0500187#ifdef SK_DEBUG
Michael Ludwig6e17f1d2019-05-15 14:00:20 +0000188static const char* op_to_name(GrLoadOp op) {
189 return GrLoadOp::kLoad == op ? "load" : GrLoadOp::kClear == op ? "clear" : "discard";
190}
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400191
Robert Phillips27483912018-04-20 12:43:18 -0400192void GrOpList::dump(bool printDependencies) const {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400193 SkDebugf("--------------------------------------------------------------\n");
Robert Phillipsba5c4392018-07-25 12:37:14 -0400194 SkDebugf("opListID: %d - proxyID: %d - surfaceID: %d\n", fUniqueID,
195 fTarget.get() ? fTarget.get()->uniqueID().asUInt() : -1,
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400196 fTarget.get() && fTarget.get()->peekSurface()
197 ? fTarget.get()->peekSurface()->uniqueID().asUInt()
198 : -1);
Michael Ludwig6e17f1d2019-05-15 14:00:20 +0000199 SkDebugf("ColorLoadOp: %s %x StencilLoadOp: %s\n",
200 op_to_name(fColorLoadOp),
201 GrLoadOp::kClear == fColorLoadOp ? fLoadClearColor.toBytes_RGBA() : 0x0,
202 op_to_name(fStencilLoadOp));
Robert Phillips27483912018-04-20 12:43:18 -0400203
204 if (printDependencies) {
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400205 SkDebugf("I rely On (%d): ", fDependencies.count());
Robert Phillips27483912018-04-20 12:43:18 -0400206 for (int i = 0; i < fDependencies.count(); ++i) {
207 SkDebugf("%d, ", fDependencies[i]->fUniqueID);
208 }
209 SkDebugf("\n");
Robert Phillipse6d06182018-08-06 16:56:26 -0400210
211 SkDebugf("(%d) Rely On Me: ", fDependents.count());
212 for (int i = 0; i < fDependents.count(); ++i) {
213 SkDebugf("%d, ", fDependents[i]->fUniqueID);
214 }
215 SkDebugf("\n");
Robert Phillipsf2361d22016-10-25 14:20:06 -0400216 }
Robert Phillipsf2361d22016-10-25 14:20:06 -0400217}
218#endif