blob: 45deb2d59b4c8e0868cdfc596b2e7778336a8c1e [file] [log] [blame]
Brian Osman62e7b5f2016-10-26 12:02:18 -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
8#include "GrTextureOpList.h"
9
10#include "GrAuditTrail.h"
11#include "GrGpu.h"
Robert Phillipsd375dbf2017-09-14 12:45:25 -040012#include "GrResourceAllocator.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040013#include "GrTextureProxy.h"
Brian Salomon69868af2016-12-22 15:42:51 -050014#include "SkStringUtils.h"
Brian Salomon89527432016-12-16 09:52:16 -050015#include "ops/GrCopySurfaceOp.h"
Brian Osman62e7b5f2016-10-26 12:02:18 -040016
17////////////////////////////////////////////////////////////////////////////////
18
Robert Phillips5efd5ea2017-05-30 13:47:32 -040019GrTextureOpList::GrTextureOpList(GrResourceProvider* resourceProvider,
20 GrTextureProxy* proxy,
21 GrAuditTrail* auditTrail)
22 : INHERITED(resourceProvider, proxy, auditTrail) {
Brian Osman62e7b5f2016-10-26 12:02:18 -040023}
24
25GrTextureOpList::~GrTextureOpList() {
Brian Osman62e7b5f2016-10-26 12:02:18 -040026}
27
28////////////////////////////////////////////////////////////////////////////////
29
30#ifdef SK_DEBUG
31void GrTextureOpList::dump() const {
32 INHERITED::dump();
33
Brian Salomon1e41f4a2016-12-07 15:05:04 -050034 SkDebugf("ops (%d):\n", fRecordedOps.count());
35 for (int i = 0; i < fRecordedOps.count(); ++i) {
Greg Danielaa3dfbe2018-01-29 10:34:25 -050036 if (!fRecordedOps[i]) {
37 SkDebugf("%d: <failed instantiation>\n", i);
38 } else {
39 SkDebugf("*******************************\n");
40 SkDebugf("%d: %s\n", i, fRecordedOps[i]->name());
41 SkString str = fRecordedOps[i]->dumpInfo();
42 SkDebugf("%s\n", str.c_str());
43 const SkRect& clippedBounds = fRecordedOps[i]->bounds();
44 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
45 clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRight,
46 clippedBounds.fBottom);
47 }
Brian Osman62e7b5f2016-10-26 12:02:18 -040048 }
49}
Robert Phillipsc589b0b2017-04-17 07:53:07 -040050
Brian Osman62e7b5f2016-10-26 12:02:18 -040051#endif
52
Brian Osman407b3422017-08-22 15:01:32 -040053void GrTextureOpList::onPrepare(GrOpFlushState* flushState) {
Robert Phillips3a9710b2018-03-27 17:51:55 -040054 SkASSERT(fTarget.get()->priv().peekTexture());
Robert Phillips6cdc22c2017-05-11 16:29:14 -040055 SkASSERT(this->isClosed());
Brian Osman62e7b5f2016-10-26 12:02:18 -040056
Brian Salomon1e41f4a2016-12-07 15:05:04 -050057 // Loop over the ops that haven't yet generated their geometry
58 for (int i = 0; i < fRecordedOps.count(); ++i) {
59 if (fRecordedOps[i]) {
Brian Salomon29b60c92017-10-31 14:42:10 -040060 GrOpFlushState::OpArgs opArgs = {
61 fRecordedOps[i].get(),
62 nullptr,
63 nullptr,
64 GrXferProcessor::DstProxy()
65 };
66 flushState->setOpArgs(&opArgs);
Brian Salomon1e41f4a2016-12-07 15:05:04 -050067 fRecordedOps[i]->prepare(flushState);
Brian Salomon29b60c92017-10-31 14:42:10 -040068 flushState->setOpArgs(nullptr);
Brian Osman62e7b5f2016-10-26 12:02:18 -040069 }
70 }
71}
72
Brian Osman407b3422017-08-22 15:01:32 -040073bool GrTextureOpList::onExecute(GrOpFlushState* flushState) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -050074 if (0 == fRecordedOps.count()) {
Brian Osman62e7b5f2016-10-26 12:02:18 -040075 return false;
76 }
77
Robert Phillips3a9710b2018-03-27 17:51:55 -040078 SkASSERT(fTarget.get()->priv().peekTexture());
79
Greg Daniel500d58b2017-08-24 15:59:33 -040080 std::unique_ptr<GrGpuTextureCommandBuffer> commandBuffer(
81 flushState->gpu()->createCommandBuffer(fTarget.get()->priv().peekTexture(),
82 fTarget.get()->origin()));
83 flushState->setCommandBuffer(commandBuffer.get());
84
Brian Salomon1e41f4a2016-12-07 15:05:04 -050085 for (int i = 0; i < fRecordedOps.count(); ++i) {
Robert Phillips3a9710b2018-03-27 17:51:55 -040086 if (!fRecordedOps[i]) {
87 continue;
88 }
89
Brian Salomon29b60c92017-10-31 14:42:10 -040090 GrOpFlushState::OpArgs opArgs = {
91 fRecordedOps[i].get(),
92 nullptr,
93 nullptr,
94 GrXferProcessor::DstProxy()
95 };
96 flushState->setOpArgs(&opArgs);
Brian Salomon9e50f7b2017-03-06 12:02:34 -050097 fRecordedOps[i]->execute(flushState);
Brian Salomon29b60c92017-10-31 14:42:10 -040098 flushState->setOpArgs(nullptr);
Brian Osman62e7b5f2016-10-26 12:02:18 -040099 }
100
Greg Daniel500d58b2017-08-24 15:59:33 -0400101 commandBuffer->submit();
102 flushState->setCommandBuffer(nullptr);
103
Brian Osman62e7b5f2016-10-26 12:02:18 -0400104 return true;
105}
106
Chris Daltona84cacf2017-10-04 10:30:29 -0600107void GrTextureOpList::endFlush() {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500108 fRecordedOps.reset();
Chris Daltona84cacf2017-10-04 10:30:29 -0600109 INHERITED::endFlush();
Brian Osman62e7b5f2016-10-26 12:02:18 -0400110}
111
112////////////////////////////////////////////////////////////////////////////////
113
Robert Phillips81dd3e02017-06-23 11:59:24 -0400114// This closely parallels GrRenderTargetOpList::copySurface but renderTargetOpList
115// stores extra data with the op
Robert Phillipsa16f6cb2017-06-01 11:06:13 -0400116bool GrTextureOpList::copySurface(const GrCaps& caps,
Robert Phillipsbf25d432017-04-07 10:08:53 -0400117 GrSurfaceProxy* dst,
118 GrSurfaceProxy* src,
Brian Osman62e7b5f2016-10-26 12:02:18 -0400119 const SkIRect& srcRect,
120 const SkIPoint& dstPoint) {
Robert Phillipsa16f6cb2017-06-01 11:06:13 -0400121 SkASSERT(dst == fTarget.get());
122
123 std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(dst, src, srcRect, dstPoint);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500124 if (!op) {
Brian Osman62e7b5f2016-10-26 12:02:18 -0400125 return false;
126 }
Robert Phillips9d6c64f2017-09-14 10:56:45 -0400127
128 auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) {
129 this->addDependency(p, caps);
130 };
131 op->visitProxies(addDependency);
Brian Osman62e7b5f2016-10-26 12:02:18 -0400132
Robert Phillips318c4192017-05-17 09:36:38 -0400133 this->recordOp(std::move(op));
Brian Osman62e7b5f2016-10-26 12:02:18 -0400134 return true;
135}
136
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500137void GrTextureOpList::purgeOpsWithUninstantiatedProxies() {
138 bool hasUninstantiatedProxy = false;
139 auto checkInstantiation = [ &hasUninstantiatedProxy ] (GrSurfaceProxy* p) {
140 if (!p->priv().isInstantiated()) {
141 hasUninstantiatedProxy = true;
142 }
143 };
144 for (int i = 0; i < fRecordedOps.count(); ++i) {
145 const GrOp* op = fRecordedOps[i].get(); // only diff from the GrRenderTargetOpList version
146 hasUninstantiatedProxy = false;
147 if (op) {
148 op->visitProxies(checkInstantiation);
149 }
150 if (hasUninstantiatedProxy) {
151 // When instantiation of the proxy fails we drop the Op
152 fRecordedOps[i] = nullptr;
153 }
154 }
155}
156
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400157void GrTextureOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
158 unsigned int cur = alloc->numOps();
159
160 // Add the interval for all the writes to this opList's target
Robert Phillipsf8e25022017-11-08 15:24:31 -0500161 if (fRecordedOps.count()) {
162 alloc->addInterval(fTarget.get(), cur, cur+fRecordedOps.count()-1);
163 } else {
164 // This can happen if there is a loadOp (e.g., a clear) but no other draws. In this case we
165 // still need to add an interval for the destination so we create a fake op# for
166 // the missing clear op.
167 alloc->addInterval(fTarget.get());
168 alloc->incOps();
169 }
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400170
Chris Dalton8816b932017-11-29 16:48:25 -0700171 auto gather = [ alloc SkDEBUGCODE(, this) ] (GrSurfaceProxy* p) {
172 alloc->addInterval(p SkDEBUGCODE(, p == fTarget.get()));
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400173 };
174 for (int i = 0; i < fRecordedOps.count(); ++i) {
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400175 const GrOp* op = fRecordedOps[i].get(); // only diff from the GrRenderTargetOpList version
Robert Phillips8186cbe2017-11-01 17:32:39 -0400176 if (op) {
177 op->visitProxies(gather);
Greg Daniel065b41d2017-11-08 19:58:51 +0000178 }
Robert Phillipsf8e25022017-11-08 15:24:31 -0500179
180 // Even though the op may have been moved we still need to increment the op count to
181 // keep all the math consistent.
182 alloc->incOps();
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400183 }
184}
185
Robert Phillips318c4192017-05-17 09:36:38 -0400186void GrTextureOpList::recordOp(std::unique_ptr<GrOp> op) {
187 SkASSERT(fTarget.get());
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500188 // A closed GrOpList should never receive new/more ops
Brian Osman62e7b5f2016-10-26 12:02:18 -0400189 SkASSERT(!this->isClosed());
190
Robert Phillips318c4192017-05-17 09:36:38 -0400191 GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), fTarget.get()->uniqueID());
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400192 GrOP_INFO("Re-Recording (%s, opID: %u)\n"
Brian Osman62e7b5f2016-10-26 12:02:18 -0400193 "\tBounds LRTB (%f, %f, %f, %f)\n",
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500194 op->name(),
195 op->uniqueID(),
196 op->bounds().fLeft, op->bounds().fRight,
197 op->bounds().fTop, op->bounds().fBottom);
198 GrOP_INFO(SkTabString(op->dumpInfo(), 1).c_str());
Brian Salomon42ad83a2016-12-20 16:14:45 -0500199 GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op.get());
Brian Osman62e7b5f2016-10-26 12:02:18 -0400200
Brian Salomon2790c522016-12-09 16:32:23 -0500201 fRecordedOps.emplace_back(std::move(op));
Brian Osman62e7b5f2016-10-26 12:02:18 -0400202}