blob: 537f9e67fc0e2f98e6b0bde932320c7f48eeaecd [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2010 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
Robert Phillipsf2361d22016-10-25 14:20:06 -04008#include "GrRenderTargetOpList.h"
joshualitt086cee12016-01-12 06:45:24 -08009#include "GrAuditTrail.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070010#include "GrCaps.h"
bsalomon4061b122015-05-29 10:26:19 -070011#include "GrGpu.h"
egdaniel9cb63402016-06-23 08:37:05 -070012#include "GrGpuCommandBuffer.h"
Brian Salomona4677b52017-05-04 12:39:56 -040013#include "GrRect.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000014#include "GrRenderTarget.h"
Brian Salomon467921e2017-03-06 16:17:12 -050015#include "GrRenderTargetContext.h"
bsalomon4061b122015-05-29 10:26:19 -070016#include "GrResourceProvider.h"
Brian Salomona4677b52017-05-04 12:39:56 -040017#include "instanced/InstancedRendering.h"
Brian Salomon89527432016-12-16 09:52:16 -050018#include "ops/GrClearOp.h"
Brian Salomon89527432016-12-16 09:52:16 -050019#include "ops/GrCopySurfaceOp.h"
csmartdaltona7f29642016-07-07 08:49:11 -070020
Robert Phillipsf2361d22016-10-25 14:20:06 -040021using gr_instanced::InstancedRendering;
22
reed@google.comac10a2d2010-12-22 21:39:39 +000023////////////////////////////////////////////////////////////////////////////////
24
Brian Salomon09d994e2016-12-21 11:14:46 -050025// Experimentally we have found that most combining occurs within the first 10 comparisons.
Robert Phillips8185f592017-04-26 08:31:08 -040026static const int kMaxOpLookback = 10;
27static const int kMaxOpLookahead = 10;
bsalomon489147c2015-12-14 12:13:09 -080028
Robert Phillipsb6deea82017-05-11 14:14:30 -040029GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* proxy, GrGpu* gpu,
Robert Phillips8185f592017-04-26 08:31:08 -040030 GrAuditTrail* auditTrail)
Robert Phillipsb6deea82017-05-11 14:14:30 -040031 : INHERITED(proxy, auditTrail)
Robert Phillipsc84c0302017-05-08 15:35:11 -040032 , fLastClipStackGenID(SK_InvalidUniqueID)
Robert Phillipsb6deea82017-05-11 14:14:30 -040033 SkDEBUGCODE(, fNumClips(0)) {
Robert Phillipsee683652017-04-26 11:53:10 -040034 if (GrCaps::InstancedSupport::kNone != gpu->caps()->instancedSupport()) {
35 fInstancedRendering.reset(gpu->createInstancedRendering());
csmartdaltone0d36292016-07-29 08:14:20 -070036 }
bsalomon4061b122015-05-29 10:26:19 -070037}
38
Robert Phillipsf2361d22016-10-25 14:20:06 -040039GrRenderTargetOpList::~GrRenderTargetOpList() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000040}
41
42////////////////////////////////////////////////////////////////////////////////
43
robertphillips4beb5c12015-10-20 07:50:00 -070044#ifdef SK_DEBUG
Robert Phillipsf2361d22016-10-25 14:20:06 -040045void GrRenderTargetOpList::dump() const {
46 INHERITED::dump();
47
Brian Salomon1e41f4a2016-12-07 15:05:04 -050048 SkDebugf("ops (%d):\n", fRecordedOps.count());
49 for (int i = 0; i < fRecordedOps.count(); ++i) {
robertphillips4beb5c12015-10-20 07:50:00 -070050 SkDebugf("*******************************\n");
Brian Salomon1e41f4a2016-12-07 15:05:04 -050051 if (!fRecordedOps[i].fOp) {
bsalomonaecc0182016-03-07 11:50:44 -080052 SkDebugf("%d: <combined forward>\n", i);
53 } else {
Brian Salomon1e41f4a2016-12-07 15:05:04 -050054 SkDebugf("%d: %s\n", i, fRecordedOps[i].fOp->name());
55 SkString str = fRecordedOps[i].fOp->dumpInfo();
bsalomonaecc0182016-03-07 11:50:44 -080056 SkDebugf("%s\n", str.c_str());
Brian Salomon9e50f7b2017-03-06 12:02:34 -050057 const SkRect& bounds = fRecordedOps[i].fOp->bounds();
58 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", bounds.fLeft,
59 bounds.fTop, bounds.fRight, bounds.fBottom);
bsalomonaecc0182016-03-07 11:50:44 -080060 }
robertphillips4beb5c12015-10-20 07:50:00 -070061 }
62}
63#endif
64
Brian Salomon742e31d2016-12-07 17:06:19 -050065void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) {
Robert Phillips318c4192017-05-17 09:36:38 -040066 SkASSERT(fTarget.get()->priv().peekRenderTarget());
Robert Phillips6cdc22c2017-05-11 16:29:14 -040067 SkASSERT(this->isClosed());
robertphillipsa106c622015-10-16 09:07:06 -070068
Brian Salomon1e41f4a2016-12-07 15:05:04 -050069 // Loop over the ops that haven't yet been prepared.
70 for (int i = 0; i < fRecordedOps.count(); ++i) {
71 if (fRecordedOps[i].fOp) {
Robert Phillips318c4192017-05-17 09:36:38 -040072 GrOpFlushState::DrawOpArgs opArgs = {
73 fTarget.get()->priv().peekRenderTarget(),
74 fRecordedOps[i].fAppliedClip,
75 fRecordedOps[i].fDstTexture
76 };
77
Brian Salomon54d212e2017-03-21 14:22:38 -040078 flushState->setDrawOpArgs(&opArgs);
Brian Salomon1e41f4a2016-12-07 15:05:04 -050079 fRecordedOps[i].fOp->prepare(flushState);
Brian Salomon54d212e2017-03-21 14:22:38 -040080 flushState->setDrawOpArgs(nullptr);
bsalomonaecc0182016-03-07 11:50:44 -080081 }
bsalomon512be532015-09-10 10:42:55 -070082 }
csmartdaltona7f29642016-07-07 08:49:11 -070083
84 if (fInstancedRendering) {
85 fInstancedRendering->beginFlush(flushState->resourceProvider());
86 }
robertphillipsa13e2022015-11-11 12:01:09 -080087}
bsalomon512be532015-09-10 10:42:55 -070088
Robert Phillips178ce3e2017-04-13 09:15:47 -040089static std::unique_ptr<GrGpuCommandBuffer> create_command_buffer(GrGpu* gpu) {
90 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo {
91 GrGpuCommandBuffer::LoadOp::kLoad,
92 GrGpuCommandBuffer::StoreOp::kStore,
93 GrColor_ILLEGAL
94 };
95
96 std::unique_ptr<GrGpuCommandBuffer> buffer(
97 gpu->createCommandBuffer(kBasicLoadStoreInfo, // Color
98 kBasicLoadStoreInfo)); // Stencil
99 return buffer;
100}
101
102static inline void finish_command_buffer(GrGpuCommandBuffer* buffer) {
103 if (!buffer) {
104 return;
105 }
106
107 buffer->end();
108 buffer->submit();
109}
110
Brian Salomon25a88092016-12-01 09:36:50 -0500111// TODO: this is where GrOp::renderTarget is used (which is fine since it
Robert Phillips294870f2016-11-11 12:38:40 -0500112// is at flush time). However, we need to store the RenderTargetProxy in the
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500113// Ops and instantiate them here.
Brian Salomon742e31d2016-12-07 17:06:19 -0500114bool GrRenderTargetOpList::executeOps(GrOpFlushState* flushState) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500115 if (0 == fRecordedOps.count()) {
bsalomondc438982016-08-31 11:53:49 -0700116 return false;
egdanielb4021cf2016-07-28 08:53:07 -0700117 }
Robert Phillips4a395042017-04-24 16:27:17 +0000118
Robert Phillips318c4192017-05-17 09:36:38 -0400119 SkASSERT(fTarget.get()->priv().peekRenderTarget());
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400120
121 std::unique_ptr<GrGpuCommandBuffer> commandBuffer = create_command_buffer(flushState->gpu());
122 flushState->setCommandBuffer(commandBuffer.get());
123
124 // Draw all the generated geometry.
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500125 for (int i = 0; i < fRecordedOps.count(); ++i) {
126 if (!fRecordedOps[i].fOp) {
bsalomonaecc0182016-03-07 11:50:44 -0800127 continue;
128 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400129
Robert Phillips178ce3e2017-04-13 09:15:47 -0400130 if (fRecordedOps[i].fOp->needsCommandBufferIsolation()) {
131 // This op is a special snowflake and must occur between command buffers
132 // TODO: make this go through the command buffer
133 finish_command_buffer(commandBuffer.get());
Robert Phillips178ce3e2017-04-13 09:15:47 -0400134
135 commandBuffer.reset();
136 flushState->setCommandBuffer(commandBuffer.get());
Robert Phillips178ce3e2017-04-13 09:15:47 -0400137 } else if (!commandBuffer) {
Robert Phillipsee683652017-04-26 11:53:10 -0400138 commandBuffer = create_command_buffer(flushState->gpu());
Ben Wagner145dbcd2016-11-03 14:40:50 -0400139 flushState->setCommandBuffer(commandBuffer.get());
egdaniel9cb63402016-06-23 08:37:05 -0700140 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400141
142 GrOpFlushState::DrawOpArgs opArgs {
Robert Phillips318c4192017-05-17 09:36:38 -0400143 fTarget.get()->priv().peekRenderTarget(),
Robert Phillips178ce3e2017-04-13 09:15:47 -0400144 fRecordedOps[i].fAppliedClip,
Robert Phillipsc3757042017-05-17 13:00:14 +0000145 fRecordedOps[i].fDstTexture
Robert Phillips178ce3e2017-04-13 09:15:47 -0400146 };
147
148 flushState->setDrawOpArgs(&opArgs);
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500149 fRecordedOps[i].fOp->execute(flushState);
Brian Salomon54d212e2017-03-21 14:22:38 -0400150 flushState->setDrawOpArgs(nullptr);
bsalomon512be532015-09-10 10:42:55 -0700151 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400152
153 finish_command_buffer(commandBuffer.get());
154 flushState->setCommandBuffer(nullptr);
ethannicholas22793252016-01-30 09:59:10 -0800155
bsalomondc438982016-08-31 11:53:49 -0700156 return true;
bsalomona73239a2015-04-28 13:35:17 -0700157}
158
Robert Phillipsf2361d22016-10-25 14:20:06 -0400159void GrRenderTargetOpList::reset() {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500160 fLastFullClearOp = nullptr;
Robert Phillips33f83152017-05-18 20:57:43 +0000161 fLastFullClearResourceID.makeInvalid();
162 fLastFullClearProxyID.makeInvalid();
Robert Phillipsb6deea82017-05-11 14:14:30 -0400163 fLastClipStackGenID = SK_InvalidUniqueID;
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500164 fRecordedOps.reset();
csmartdaltona7f29642016-07-07 08:49:11 -0700165 if (fInstancedRendering) {
166 fInstancedRendering->endFlush();
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400167 fInstancedRendering = nullptr;
csmartdaltona7f29642016-07-07 08:49:11 -0700168 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400169
170 INHERITED::reset();
bsalomon512be532015-09-10 10:42:55 -0700171}
172
Robert Phillipsf2361d22016-10-25 14:20:06 -0400173void GrRenderTargetOpList::abandonGpuResources() {
Robert Phillipsee683652017-04-26 11:53:10 -0400174 if (fInstancedRendering) {
175 fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kAbandon);
Robert Phillipsf2361d22016-10-25 14:20:06 -0400176 }
177}
178
179void GrRenderTargetOpList::freeGpuResources() {
Robert Phillipsee683652017-04-26 11:53:10 -0400180 if (fInstancedRendering) {
181 fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kDestroy);
Robert Phillipsf2361d22016-10-25 14:20:06 -0400182 }
183}
184
Robert Phillips33f83152017-05-18 20:57:43 +0000185void GrRenderTargetOpList::fullClear(GrRenderTargetContext* renderTargetContext, GrColor color) {
186 // MDB TODO: remove this. Right now we need the renderTargetContext for the
187 // accessRenderTarget call. This method should just take the renderTargetProxy.
188 GrRenderTarget* renderTarget = renderTargetContext->accessRenderTarget();
189 if (!renderTarget) {
190 return;
191 }
192
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500193 // Currently this just inserts or updates the last clear op. However, once in MDB this can
194 // remove all the previously recorded ops and change the load op to clear with supplied
bsalomonfd8d0132016-08-11 11:25:33 -0700195 // color.
Robert Phillips33f83152017-05-18 20:57:43 +0000196 // TODO: this needs to be updated to use GrSurfaceProxy::UniqueID
197 // MDB TODO: re-enable once opLists are divided. This assertion fails when a rendering is
198 // aborted but the same RT is reused for the next draw. The clears really shouldn't be
199 // fused in that case.
200 //SkASSERT((fLastFullClearResourceID == renderTarget->uniqueID()) ==
201 // (fLastFullClearProxyID == renderTargetContext->asRenderTargetProxy()->uniqueID()));
202 if (fLastFullClearResourceID == renderTarget->uniqueID()) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500203 // As currently implemented, fLastFullClearOp should be the last op because we would
204 // have cleared it when another op was recorded.
205 SkASSERT(fRecordedOps.back().fOp.get() == fLastFullClearOp);
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400206 GrOP_INFO("opList: %d Fusing clears (opID: %d Color: 0x%08x -> 0x%08x)\n",
207 this->uniqueID(),
208 fLastFullClearOp->uniqueID(),
209 fLastFullClearOp->color(), color);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500210 fLastFullClearOp->setColor(color);
bsalomonfd8d0132016-08-11 11:25:33 -0700211 return;
212 }
Robert Phillips33f83152017-05-18 20:57:43 +0000213 std::unique_ptr<GrClearOp> op(GrClearOp::Make(GrFixedClip::Disabled(), color,
214 renderTargetContext));
Robert Phillipsf7a72612017-03-31 10:03:45 -0400215 if (!op) {
216 return;
217 }
Robert Phillips33f83152017-05-18 20:57:43 +0000218 if (GrOp* clearOp = this->recordOp(std::move(op), renderTargetContext)) {
Brian Salomon2790c522016-12-09 16:32:23 -0500219 // This is either the clear op we just created or another one that it combined with.
Brian Salomon7dae46a2016-12-14 16:21:37 -0500220 fLastFullClearOp = static_cast<GrClearOp*>(clearOp);
Robert Phillips33f83152017-05-18 20:57:43 +0000221 fLastFullClearResourceID = renderTarget->uniqueID();
222 fLastFullClearProxyID = renderTargetContext->asRenderTargetProxy()->uniqueID();
bsalomonfd8d0132016-08-11 11:25:33 -0700223 }
bsalomon9f129de2016-08-10 16:31:05 -0700224}
225
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000226////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000227
Robert Phillipsc84c0302017-05-08 15:35:11 -0400228// MDB TODO: fuse with GrTextureOpList::copySurface
Robert Phillipsbf25d432017-04-07 10:08:53 -0400229bool GrRenderTargetOpList::copySurface(GrResourceProvider* resourceProvider,
Robert Phillips178ce3e2017-04-13 09:15:47 -0400230 GrRenderTargetContext* dst,
Robert Phillipsbf25d432017-04-07 10:08:53 -0400231 GrSurfaceProxy* src,
Robert Phillipsf2361d22016-10-25 14:20:06 -0400232 const SkIRect& srcRect,
233 const SkIPoint& dstPoint) {
Robert Phillips178ce3e2017-04-13 09:15:47 -0400234 std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(resourceProvider, dst->asSurfaceProxy(),
235 src, srcRect, dstPoint);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500236 if (!op) {
bsalomonb8fea972016-02-16 07:34:17 -0800237 return false;
238 }
robertphillips498d7ac2015-10-30 10:11:30 -0700239#ifdef ENABLE_MDB
bsalomonb8fea972016-02-16 07:34:17 -0800240 this->addDependency(src);
robertphillips498d7ac2015-10-30 10:11:30 -0700241#endif
242
Robert Phillips33f83152017-05-18 20:57:43 +0000243 this->recordOp(std::move(op), dst);
bsalomonb8fea972016-02-16 07:34:17 -0800244 return true;
bsalomon@google.comeb851172013-04-15 13:51:00 +0000245}
246
Brian Salomona4677b52017-05-04 12:39:56 -0400247static inline bool can_reorder(const SkRect& a, const SkRect& b) { return !GrRectsOverlap(a, b); }
bsalomon88cf17d2016-07-08 06:40:56 -0700248
Brian Salomon54d212e2017-03-21 14:22:38 -0400249bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b,
250 const GrAppliedClip* bClip,
Robert Phillipsc3757042017-05-17 13:00:14 +0000251 const DstTexture* bDstTexture,
Robert Phillipsee683652017-04-26 11:53:10 -0400252 const GrCaps& caps) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400253 if (a.fAppliedClip) {
254 if (!bClip) {
255 return false;
256 }
257 if (*a.fAppliedClip != *bClip) {
258 return false;
259 }
260 } else if (bClip) {
261 return false;
262 }
Robert Phillipsc3757042017-05-17 13:00:14 +0000263 if (bDstTexture) {
264 if (a.fDstTexture != *bDstTexture) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400265 return false;
266 }
Robert Phillipsc3757042017-05-17 13:00:14 +0000267 } else if (a.fDstTexture.texture()) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400268 return false;
269 }
Robert Phillipsee683652017-04-26 11:53:10 -0400270 return a.fOp->combineIfPossible(b, caps);
Brian Salomon54d212e2017-03-21 14:22:38 -0400271}
272
Brian Salomonf8334782017-01-03 09:42:58 -0500273GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
Robert Phillips33f83152017-05-18 20:57:43 +0000274 GrRenderTargetContext* renderTargetContext,
Brian Salomon54d212e2017-03-21 14:22:38 -0400275 GrAppliedClip* clip,
Robert Phillipsc3757042017-05-17 13:00:14 +0000276 const DstTexture* dstTexture) {
Robert Phillips318c4192017-05-17 09:36:38 -0400277 SkASSERT(fTarget.get());
Robert Phillips33f83152017-05-18 20:57:43 +0000278 const GrCaps* caps = renderTargetContext->caps();
Robert Phillipsee683652017-04-26 11:53:10 -0400279
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500280 // A closed GrOpList should never receive new/more ops
robertphillips6a186652015-10-20 07:37:58 -0700281 SkASSERT(!this->isClosed());
robertphillipsa106c622015-10-16 09:07:06 -0700282
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500283 // Check if there is an op we can combine with by linearly searching back until we either
284 // 1) check every op
bsalomon512be532015-09-10 10:42:55 -0700285 // 2) intersect with something
286 // 3) find a 'blocker'
Robert Phillips33f83152017-05-18 20:57:43 +0000287 GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(),
288 renderTargetContext->asRenderTargetProxy()->uniqueID());
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400289 GrOP_INFO("opList: %d Recording (%s, opID: %u)\n"
290 "\tBounds [L: %.2f, T: %.2f R: %.2f B: %.2f]\n",
291 this->uniqueID(),
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500292 op->name(),
293 op->uniqueID(),
Robert Phillips1119dc32017-04-11 12:54:57 -0400294 op->bounds().fLeft, op->bounds().fTop,
295 op->bounds().fRight, op->bounds().fBottom);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500296 GrOP_INFO(SkTabString(op->dumpInfo(), 1).c_str());
Brian Salomon25a88092016-12-01 09:36:50 -0500297 GrOP_INFO("\tOutcome:\n");
Robert Phillips8185f592017-04-26 08:31:08 -0400298 int maxCandidates = SkTMin(kMaxOpLookback, fRecordedOps.count());
Brian Salomoncdcc33f2017-02-21 09:49:20 -0500299 // If we don't have a valid destination render target then we cannot reorder.
Robert Phillips318c4192017-05-17 09:36:38 -0400300 if (maxCandidates) {
bsalomon512be532015-09-10 10:42:55 -0700301 int i = 0;
302 while (true) {
Brian Salomon69868af2016-12-22 15:42:51 -0500303 const RecordedOp& candidate = fRecordedOps.fromBack(i);
Robert Phillips318c4192017-05-17 09:36:38 -0400304
Robert Phillips33f83152017-05-18 20:57:43 +0000305 if (this->combineIfPossible(candidate, op.get(), clip, dstTexture, *caps)) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400306 GrOP_INFO("\t\tBackward: Combining with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500307 candidate.fOp->uniqueID());
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400308 GrOP_INFO("\t\t\tBackward: Combined op info:\n");
Brian Salomon199fb872017-02-06 09:41:10 -0500309 GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str());
Brian Salomon69868af2016-12-22 15:42:51 -0500310 GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get());
Brian Salomon69868af2016-12-22 15:42:51 -0500311 return candidate.fOp.get();
bsalomon512be532015-09-10 10:42:55 -0700312 }
313 // Stop going backwards if we would cause a painter's order violation.
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500314 if (!can_reorder(fRecordedOps.fromBack(i).fOp->bounds(), op->bounds())) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400315 GrOP_INFO("\t\tBackward: Intersects with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500316 candidate.fOp->uniqueID());
bsalomon512be532015-09-10 10:42:55 -0700317 break;
318 }
319 ++i;
320 if (i == maxCandidates) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400321 GrOP_INFO("\t\tBackward: Reached max lookback or beginning of op array %d\n", i);
bsalomon512be532015-09-10 10:42:55 -0700322 break;
323 }
324 }
325 } else {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400326 GrOP_INFO("\t\tBackward: FirstOp\n");
bsalomon512be532015-09-10 10:42:55 -0700327 }
Brian Salomon42ad83a2016-12-20 16:14:45 -0500328 GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op);
Brian Salomon54d212e2017-03-21 14:22:38 -0400329 if (clip) {
330 clip = fClipAllocator.make<GrAppliedClip>(std::move(*clip));
Robert Phillipsc84c0302017-05-08 15:35:11 -0400331 SkDEBUGCODE(fNumClips++;)
Brian Salomon54d212e2017-03-21 14:22:38 -0400332 }
Robert Phillips318c4192017-05-17 09:36:38 -0400333 fRecordedOps.emplace_back(std::move(op), clip, dstTexture);
Robert Phillipse3302df2017-04-24 07:31:02 -0400334 fRecordedOps.back().fOp->wasRecorded(this);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500335 fLastFullClearOp = nullptr;
Robert Phillips33f83152017-05-18 20:57:43 +0000336 fLastFullClearResourceID.makeInvalid();
337 fLastFullClearProxyID.makeInvalid();
Brian Salomon2790c522016-12-09 16:32:23 -0500338 return fRecordedOps.back().fOp.get();
bsalomon512be532015-09-10 10:42:55 -0700339}
340
Robert Phillipsee683652017-04-26 11:53:10 -0400341void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400342 SkASSERT(!this->isClosed());
343
Brian Salomon337432d2017-03-21 17:36:10 -0400344 for (int i = 0; i < fRecordedOps.count() - 1; ++i) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500345 GrOp* op = fRecordedOps[i].fOp.get();
Robert Phillips318c4192017-05-17 09:36:38 -0400346
Robert Phillips8185f592017-04-26 08:31:08 -0400347 int maxCandidateIdx = SkTMin(i + kMaxOpLookahead, fRecordedOps.count() - 1);
bsalomonaecc0182016-03-07 11:50:44 -0800348 int j = i + 1;
349 while (true) {
Brian Salomon69868af2016-12-22 15:42:51 -0500350 const RecordedOp& candidate = fRecordedOps[j];
Robert Phillips318c4192017-05-17 09:36:38 -0400351
Brian Salomon54d212e2017-03-21 14:22:38 -0400352 if (this->combineIfPossible(fRecordedOps[i], candidate.fOp.get(),
Robert Phillipsc3757042017-05-17 13:00:14 +0000353 candidate.fAppliedClip, &candidate.fDstTexture, caps)) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400354 GrOP_INFO("\t\tForward: Combining with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500355 candidate.fOp->uniqueID());
356 GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get());
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500357 fRecordedOps[j].fOp = std::move(fRecordedOps[i].fOp);
bsalomonaecc0182016-03-07 11:50:44 -0800358 break;
359 }
Robert Phillipsc84c0302017-05-08 15:35:11 -0400360 // Stop traversing if we would cause a painter's order violation.
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500361 if (!can_reorder(fRecordedOps[j].fOp->bounds(), op->bounds())) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400362 GrOP_INFO("\t\tForward: Intersects with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500363 candidate.fOp->uniqueID());
bsalomonaecc0182016-03-07 11:50:44 -0800364 break;
365 }
366 ++j;
367 if (j > maxCandidateIdx) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400368 GrOP_INFO("\t\tForward: Reached max lookahead or end of op array %d\n", i);
bsalomonaecc0182016-03-07 11:50:44 -0800369 break;
370 }
371 }
372 }
373}
374