blob: 9a9ff1496da7bf709bdb32b698c65ddd317519b6 [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
Greg Danielf91aeb22019-06-18 09:58:02 -04008#include "src/gpu/GrOpList.h"
Robert Phillips5efd5ea2017-05-30 13:47:32 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/GrDeferredProxyUploader.h"
12#include "src/gpu/GrMemoryPool.h"
13#include "src/gpu/GrRenderTargetPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040014#include "src/gpu/GrSurfaceProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#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 Phillipsb5204762019-06-19 14:12:13 -040035 fTarget = std::move(surfaceProxy);
36 fTarget->setLastOpList(this);
Robert Phillipsf2361d22016-10-25 14:20:06 -040037}
38
39GrOpList::~GrOpList() {
Robert Phillipsb5204762019-06-19 14:12:13 -040040 if (fTarget && this == fTarget->getLastOpList()) {
Chris Daltona84cacf2017-10-04 10:30:29 -060041 // Ensure the target proxy doesn't keep hold of a dangling back pointer.
Robert Phillipsb5204762019-06-19 14:12:13 -040042 fTarget->setLastOpList(nullptr);
Chris Daltona84cacf2017-10-04 10:30:29 -060043 }
Robert Phillipsf2361d22016-10-25 14:20:06 -040044}
45
Chris Daltona84cacf2017-10-04 10:30:29 -060046void GrOpList::endFlush() {
Robert Phillipsb5204762019-06-19 14:12:13 -040047 if (fTarget && this == fTarget->getLastOpList()) {
48 fTarget->setLastOpList(nullptr);
Robert Phillips6cdc22c2017-05-11 16:29:14 -040049 }
50
Robert Phillips5efd5ea2017-05-30 13:47:32 -040051 fTarget.reset();
Brian Osman099fa0f2017-10-02 16:38:32 -040052 fDeferredProxies.reset();
Robert Phillips6cdc22c2017-05-11 16:29:14 -040053 fAuditTrail = nullptr;
54}
55
Robert Phillips82774f82019-06-20 14:38:27 -040056#ifdef SK_DEBUG
57bool GrOpList::deferredProxiesAreInstantiated() const {
Brian Osman099fa0f2017-10-02 16:38:32 -040058 for (int i = 0; i < fDeferredProxies.count(); ++i) {
Robert Phillips82774f82019-06-20 14:38:27 -040059 if (!fDeferredProxies[i]->isInstantiated()) {
60 return false;
61 }
Brian Osman099fa0f2017-10-02 16:38:32 -040062 }
Robert Phillips82774f82019-06-20 14:38:27 -040063
64 return true;
Brian Osman5d034742017-09-11 13:38:55 -040065}
Robert Phillips82774f82019-06-20 14:38:27 -040066#endif
Brian Osman5d034742017-09-11 13:38:55 -040067
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
Robert Phillips46acf9d2018-10-09 09:31:40 -0400151void GrOpList::closeThoseWhoDependOnMe(const GrCaps& caps) {
152 for (int i = 0; i < fDependents.count(); ++i) {
153 if (!fDependents[i]->isClosed()) {
154 fDependents[i]->makeClosed(caps);
155 }
156 }
157}
158
Robert Phillips82774f82019-06-20 14:38:27 -0400159bool GrOpList::isInstantiated() const {
160 if (!fTarget->isInstantiated()) {
Robert Phillips01a91282018-07-26 08:03:04 -0400161 return false;
162 }
163
Robert Phillipsb5204762019-06-19 14:12:13 -0400164 bool needsStencil = fTarget->asRenderTargetProxy()
165 ? fTarget->asRenderTargetProxy()->needsStencil()
Robert Phillips01a91282018-07-26 08:03:04 -0400166 : false;
167
168 if (needsStencil) {
Robert Phillipsb5204762019-06-19 14:12:13 -0400169 GrRenderTarget* rt = fTarget->peekRenderTarget();
Robert Phillips01a91282018-07-26 08:03:04 -0400170
171 if (!rt->renderTargetPriv().getStencilAttachment()) {
172 return false;
173 }
174 }
175
Robert Phillipsb5204762019-06-19 14:12:13 -0400176 GrSurface* surface = fTarget->peekSurface();
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400177 if (surface->wasDestroyed()) {
178 return false;
179 }
180
Robert Phillips01a91282018-07-26 08:03:04 -0400181 return true;
182}
183
Robert Phillips4150eea2018-02-07 17:08:21 -0500184#ifdef SK_DEBUG
Michael Ludwig6e17f1d2019-05-15 14:00:20 +0000185static const char* op_to_name(GrLoadOp op) {
186 return GrLoadOp::kLoad == op ? "load" : GrLoadOp::kClear == op ? "clear" : "discard";
187}
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400188
Robert Phillips27483912018-04-20 12:43:18 -0400189void GrOpList::dump(bool printDependencies) const {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400190 SkDebugf("--------------------------------------------------------------\n");
Robert Phillipsba5c4392018-07-25 12:37:14 -0400191 SkDebugf("opListID: %d - proxyID: %d - surfaceID: %d\n", fUniqueID,
Robert Phillipsb5204762019-06-19 14:12:13 -0400192 fTarget ? fTarget->uniqueID().asUInt() : -1,
193 fTarget && fTarget->peekSurface()
194 ? fTarget->peekSurface()->uniqueID().asUInt()
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400195 : -1);
Michael Ludwig6e17f1d2019-05-15 14:00:20 +0000196 SkDebugf("ColorLoadOp: %s %x StencilLoadOp: %s\n",
197 op_to_name(fColorLoadOp),
198 GrLoadOp::kClear == fColorLoadOp ? fLoadClearColor.toBytes_RGBA() : 0x0,
199 op_to_name(fStencilLoadOp));
Robert Phillips27483912018-04-20 12:43:18 -0400200
201 if (printDependencies) {
Robert Phillipsce3c28f2018-07-18 13:52:40 -0400202 SkDebugf("I rely On (%d): ", fDependencies.count());
Robert Phillips27483912018-04-20 12:43:18 -0400203 for (int i = 0; i < fDependencies.count(); ++i) {
204 SkDebugf("%d, ", fDependencies[i]->fUniqueID);
205 }
206 SkDebugf("\n");
Robert Phillipse6d06182018-08-06 16:56:26 -0400207
208 SkDebugf("(%d) Rely On Me: ", fDependents.count());
209 for (int i = 0; i < fDependents.count(); ++i) {
210 SkDebugf("%d, ", fDependents[i]->fUniqueID);
211 }
212 SkDebugf("\n");
Robert Phillipsf2361d22016-10-25 14:20:06 -0400213 }
Robert Phillipsf2361d22016-10-25 14:20:06 -0400214}
215#endif