blob: ffa1e43746161e21069069e57c6f11ad305fcf2e [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"
Brian Salomon467921e2017-03-06 16:17:12 -050014#include "GrRenderTargetContext.h"
Brian Salomona4677b52017-05-04 12:39:56 -040015#include "instanced/InstancedRendering.h"
Brian Salomon89527432016-12-16 09:52:16 -050016#include "ops/GrClearOp.h"
Brian Salomon89527432016-12-16 09:52:16 -050017#include "ops/GrCopySurfaceOp.h"
csmartdaltona7f29642016-07-07 08:49:11 -070018
Robert Phillipsf2361d22016-10-25 14:20:06 -040019using gr_instanced::InstancedRendering;
20
reed@google.comac10a2d2010-12-22 21:39:39 +000021////////////////////////////////////////////////////////////////////////////////
22
Brian Salomon09d994e2016-12-21 11:14:46 -050023// Experimentally we have found that most combining occurs within the first 10 comparisons.
Robert Phillips8185f592017-04-26 08:31:08 -040024static const int kMaxOpLookback = 10;
25static const int kMaxOpLookahead = 10;
bsalomon489147c2015-12-14 12:13:09 -080026
Robert Phillipsb6deea82017-05-11 14:14:30 -040027GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* proxy, GrGpu* gpu,
Robert Phillips8185f592017-04-26 08:31:08 -040028 GrAuditTrail* auditTrail)
Robert Phillips5efd5ea2017-05-30 13:47:32 -040029 : INHERITED(gpu->getContext()->resourceProvider(), proxy, auditTrail)
Robert Phillipsc84c0302017-05-08 15:35:11 -040030 , fLastClipStackGenID(SK_InvalidUniqueID)
Robert Phillipsb6deea82017-05-11 14:14:30 -040031 SkDEBUGCODE(, fNumClips(0)) {
Robert Phillipsee683652017-04-26 11:53:10 -040032 if (GrCaps::InstancedSupport::kNone != gpu->caps()->instancedSupport()) {
33 fInstancedRendering.reset(gpu->createInstancedRendering());
csmartdaltone0d36292016-07-29 08:14:20 -070034 }
bsalomon4061b122015-05-29 10:26:19 -070035}
36
Robert Phillipsf2361d22016-10-25 14:20:06 -040037GrRenderTargetOpList::~GrRenderTargetOpList() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000038}
39
40////////////////////////////////////////////////////////////////////////////////
41
robertphillips4beb5c12015-10-20 07:50:00 -070042#ifdef SK_DEBUG
Robert Phillipsf2361d22016-10-25 14:20:06 -040043void GrRenderTargetOpList::dump() const {
44 INHERITED::dump();
45
Brian Salomon1e41f4a2016-12-07 15:05:04 -050046 SkDebugf("ops (%d):\n", fRecordedOps.count());
47 for (int i = 0; i < fRecordedOps.count(); ++i) {
robertphillips4beb5c12015-10-20 07:50:00 -070048 SkDebugf("*******************************\n");
Brian Salomon1e41f4a2016-12-07 15:05:04 -050049 if (!fRecordedOps[i].fOp) {
bsalomonaecc0182016-03-07 11:50:44 -080050 SkDebugf("%d: <combined forward>\n", i);
51 } else {
Brian Salomon1e41f4a2016-12-07 15:05:04 -050052 SkDebugf("%d: %s\n", i, fRecordedOps[i].fOp->name());
53 SkString str = fRecordedOps[i].fOp->dumpInfo();
bsalomonaecc0182016-03-07 11:50:44 -080054 SkDebugf("%s\n", str.c_str());
Brian Salomon9e50f7b2017-03-06 12:02:34 -050055 const SkRect& bounds = fRecordedOps[i].fOp->bounds();
56 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", bounds.fLeft,
57 bounds.fTop, bounds.fRight, bounds.fBottom);
bsalomonaecc0182016-03-07 11:50:44 -080058 }
robertphillips4beb5c12015-10-20 07:50:00 -070059 }
60}
61#endif
62
Brian Salomon742e31d2016-12-07 17:06:19 -050063void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) {
Robert Phillips318c4192017-05-17 09:36:38 -040064 SkASSERT(fTarget.get()->priv().peekRenderTarget());
Robert Phillips6cdc22c2017-05-11 16:29:14 -040065 SkASSERT(this->isClosed());
robertphillipsa106c622015-10-16 09:07:06 -070066
Brian Salomon1e41f4a2016-12-07 15:05:04 -050067 // Loop over the ops that haven't yet been prepared.
68 for (int i = 0; i < fRecordedOps.count(); ++i) {
69 if (fRecordedOps[i].fOp) {
Robert Phillips318c4192017-05-17 09:36:38 -040070 GrOpFlushState::DrawOpArgs opArgs = {
Robert Phillips2890fbf2017-07-26 15:48:41 -040071 fTarget.get()->asRenderTargetProxy(),
Robert Phillips318c4192017-05-17 09:36:38 -040072 fRecordedOps[i].fAppliedClip,
Robert Phillipsbb581ce2017-05-29 15:05:15 -040073 fRecordedOps[i].fDstProxy
Robert Phillips318c4192017-05-17 09:36:38 -040074 };
75
Brian Salomon54d212e2017-03-21 14:22:38 -040076 flushState->setDrawOpArgs(&opArgs);
Brian Salomon1e41f4a2016-12-07 15:05:04 -050077 fRecordedOps[i].fOp->prepare(flushState);
Brian Salomon54d212e2017-03-21 14:22:38 -040078 flushState->setDrawOpArgs(nullptr);
bsalomonaecc0182016-03-07 11:50:44 -080079 }
bsalomon512be532015-09-10 10:42:55 -070080 }
csmartdaltona7f29642016-07-07 08:49:11 -070081
82 if (fInstancedRendering) {
83 fInstancedRendering->beginFlush(flushState->resourceProvider());
84 }
robertphillipsa13e2022015-11-11 12:01:09 -080085}
bsalomon512be532015-09-10 10:42:55 -070086
Robert Phillips95214472017-08-08 18:00:03 -040087static std::unique_ptr<GrGpuCommandBuffer> create_command_buffer(GrGpu* gpu,
88 GrRenderTarget* rt,
89 GrSurfaceOrigin origin,
Robert Phillips54190c42017-08-09 20:09:38 +000090 bool clearSB) {
Robert Phillips178ce3e2017-04-13 09:15:47 -040091 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo {
Robert Phillips54190c42017-08-09 20:09:38 +000092 GrGpuCommandBuffer::LoadOp::kLoad,
93 GrGpuCommandBuffer::StoreOp::kStore,
94 GrColor_ILLEGAL
Robert Phillips178ce3e2017-04-13 09:15:47 -040095 };
96
Robert Phillips95214472017-08-08 18:00:03 -040097 // TODO:
98 // We would like to (at this level) only ever clear & discard. We would need
99 // to stop splitting up higher level opLists for copyOps to achieve that.
100 // Note: we would still need SB loads and stores but they would happen at a
101 // lower level (inside the VK command buffer).
102 const GrGpuCommandBuffer::StencilLoadAndStoreInfo stencilLoadAndStoreInfo {
Robert Phillips54190c42017-08-09 20:09:38 +0000103 clearSB ? GrGpuCommandBuffer::LoadOp::kClear : GrGpuCommandBuffer::LoadOp::kLoad,
104 GrGpuCommandBuffer::StoreOp::kStore,
Robert Phillips95214472017-08-08 18:00:03 -0400105 };
106
Robert Phillips178ce3e2017-04-13 09:15:47 -0400107 std::unique_ptr<GrGpuCommandBuffer> buffer(
Robert Phillips95214472017-08-08 18:00:03 -0400108 gpu->createCommandBuffer(rt, origin,
109 kBasicLoadStoreInfo, // Color
110 stencilLoadAndStoreInfo)); // Stencil
Robert Phillips178ce3e2017-04-13 09:15:47 -0400111 return buffer;
112}
113
114static inline void finish_command_buffer(GrGpuCommandBuffer* buffer) {
115 if (!buffer) {
116 return;
117 }
118
119 buffer->end();
120 buffer->submit();
121}
122
Brian Salomon25a88092016-12-01 09:36:50 -0500123// TODO: this is where GrOp::renderTarget is used (which is fine since it
Robert Phillips294870f2016-11-11 12:38:40 -0500124// is at flush time). However, we need to store the RenderTargetProxy in the
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500125// Ops and instantiate them here.
Brian Salomon742e31d2016-12-07 17:06:19 -0500126bool GrRenderTargetOpList::executeOps(GrOpFlushState* flushState) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500127 if (0 == fRecordedOps.count()) {
bsalomondc438982016-08-31 11:53:49 -0700128 return false;
egdanielb4021cf2016-07-28 08:53:07 -0700129 }
Robert Phillips4a395042017-04-24 16:27:17 +0000130
Robert Phillips318c4192017-05-17 09:36:38 -0400131 SkASSERT(fTarget.get()->priv().peekRenderTarget());
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400132
Robert Phillips95214472017-08-08 18:00:03 -0400133 std::unique_ptr<GrGpuCommandBuffer> commandBuffer = create_command_buffer(
134 flushState->gpu(),
135 fTarget.get()->priv().peekRenderTarget(),
136 fTarget.get()->origin(),
Robert Phillips54190c42017-08-09 20:09:38 +0000137 this->requiresStencil());
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400138 flushState->setCommandBuffer(commandBuffer.get());
Robert Phillips95214472017-08-08 18:00:03 -0400139 commandBuffer->begin();
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400140
141 // Draw all the generated geometry.
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500142 for (int i = 0; i < fRecordedOps.count(); ++i) {
143 if (!fRecordedOps[i].fOp) {
bsalomonaecc0182016-03-07 11:50:44 -0800144 continue;
145 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400146
Robert Phillips178ce3e2017-04-13 09:15:47 -0400147 if (fRecordedOps[i].fOp->needsCommandBufferIsolation()) {
148 // This op is a special snowflake and must occur between command buffers
149 // TODO: make this go through the command buffer
150 finish_command_buffer(commandBuffer.get());
Robert Phillips178ce3e2017-04-13 09:15:47 -0400151
152 commandBuffer.reset();
153 flushState->setCommandBuffer(commandBuffer.get());
Robert Phillips178ce3e2017-04-13 09:15:47 -0400154 } else if (!commandBuffer) {
Robert Phillips95214472017-08-08 18:00:03 -0400155 commandBuffer = create_command_buffer(flushState->gpu(),
156 fTarget.get()->priv().peekRenderTarget(),
157 fTarget.get()->origin(),
Robert Phillips54190c42017-08-09 20:09:38 +0000158 false);
Ben Wagner145dbcd2016-11-03 14:40:50 -0400159 flushState->setCommandBuffer(commandBuffer.get());
Robert Phillips95214472017-08-08 18:00:03 -0400160 commandBuffer->begin();
egdaniel9cb63402016-06-23 08:37:05 -0700161 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400162
163 GrOpFlushState::DrawOpArgs opArgs {
Robert Phillips2890fbf2017-07-26 15:48:41 -0400164 fTarget.get()->asRenderTargetProxy(),
Robert Phillips178ce3e2017-04-13 09:15:47 -0400165 fRecordedOps[i].fAppliedClip,
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400166 fRecordedOps[i].fDstProxy
Robert Phillips178ce3e2017-04-13 09:15:47 -0400167 };
168
169 flushState->setDrawOpArgs(&opArgs);
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500170 fRecordedOps[i].fOp->execute(flushState);
Brian Salomon54d212e2017-03-21 14:22:38 -0400171 flushState->setDrawOpArgs(nullptr);
bsalomon512be532015-09-10 10:42:55 -0700172 }
Robert Phillips178ce3e2017-04-13 09:15:47 -0400173
174 finish_command_buffer(commandBuffer.get());
175 flushState->setCommandBuffer(nullptr);
ethannicholas22793252016-01-30 09:59:10 -0800176
bsalomondc438982016-08-31 11:53:49 -0700177 return true;
bsalomona73239a2015-04-28 13:35:17 -0700178}
179
Robert Phillipsf2361d22016-10-25 14:20:06 -0400180void GrRenderTargetOpList::reset() {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500181 fLastFullClearOp = nullptr;
Robert Phillipsb6deea82017-05-11 14:14:30 -0400182 fLastClipStackGenID = SK_InvalidUniqueID;
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500183 fRecordedOps.reset();
csmartdaltona7f29642016-07-07 08:49:11 -0700184 if (fInstancedRendering) {
185 fInstancedRendering->endFlush();
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400186 fInstancedRendering = nullptr;
csmartdaltona7f29642016-07-07 08:49:11 -0700187 }
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400188
189 INHERITED::reset();
bsalomon512be532015-09-10 10:42:55 -0700190}
191
Robert Phillipsf2361d22016-10-25 14:20:06 -0400192void GrRenderTargetOpList::abandonGpuResources() {
Robert Phillipsee683652017-04-26 11:53:10 -0400193 if (fInstancedRendering) {
194 fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kAbandon);
Robert Phillipsf2361d22016-10-25 14:20:06 -0400195 }
196}
197
198void GrRenderTargetOpList::freeGpuResources() {
Robert Phillipsee683652017-04-26 11:53:10 -0400199 if (fInstancedRendering) {
200 fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kDestroy);
Robert Phillipsf2361d22016-10-25 14:20:06 -0400201 }
202}
203
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400204void GrRenderTargetOpList::fullClear(const GrCaps& caps, GrColor color) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500205 // Currently this just inserts or updates the last clear op. However, once in MDB this can
206 // remove all the previously recorded ops and change the load op to clear with supplied
bsalomonfd8d0132016-08-11 11:25:33 -0700207 // color.
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400208 if (fLastFullClearOp) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500209 // As currently implemented, fLastFullClearOp should be the last op because we would
210 // have cleared it when another op was recorded.
211 SkASSERT(fRecordedOps.back().fOp.get() == fLastFullClearOp);
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400212 GrOP_INFO("opList: %d Fusing clears (opID: %d Color: 0x%08x -> 0x%08x)\n",
213 this->uniqueID(),
214 fLastFullClearOp->uniqueID(),
215 fLastFullClearOp->color(), color);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500216 fLastFullClearOp->setColor(color);
bsalomonfd8d0132016-08-11 11:25:33 -0700217 return;
218 }
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400219 std::unique_ptr<GrClearOp> op(GrClearOp::Make(GrFixedClip::Disabled(), color, fTarget.get()));
Robert Phillipsf7a72612017-03-31 10:03:45 -0400220 if (!op) {
221 return;
222 }
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400223
224 if (GrOp* clearOp = this->recordOp(std::move(op), caps)) {
Brian Salomon2790c522016-12-09 16:32:23 -0500225 // This is either the clear op we just created or another one that it combined with.
Brian Salomon7dae46a2016-12-14 16:21:37 -0500226 fLastFullClearOp = static_cast<GrClearOp*>(clearOp);
bsalomonfd8d0132016-08-11 11:25:33 -0700227 }
bsalomon9f129de2016-08-10 16:31:05 -0700228}
229
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000230////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000231
Robert Phillips81dd3e02017-06-23 11:59:24 -0400232// This closely parallels GrTextureOpList::copySurface but renderTargetOpLists
233// also store the applied clip and dest proxy with the op
Robert Phillipsa16f6cb2017-06-01 11:06:13 -0400234bool GrRenderTargetOpList::copySurface(const GrCaps& caps,
235 GrSurfaceProxy* dst,
Robert Phillipsbf25d432017-04-07 10:08:53 -0400236 GrSurfaceProxy* src,
Robert Phillipsf2361d22016-10-25 14:20:06 -0400237 const SkIRect& srcRect,
238 const SkIPoint& dstPoint) {
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400239 SkASSERT(dst->asRenderTargetProxy() == fTarget.get());
Robert Phillipsa16f6cb2017-06-01 11:06:13 -0400240 std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(dst, src, srcRect, dstPoint);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500241 if (!op) {
bsalomonb8fea972016-02-16 07:34:17 -0800242 return false;
243 }
robertphillips498d7ac2015-10-30 10:11:30 -0700244#ifdef ENABLE_MDB
bsalomonb8fea972016-02-16 07:34:17 -0800245 this->addDependency(src);
robertphillips498d7ac2015-10-30 10:11:30 -0700246#endif
247
Robert Phillipsa16f6cb2017-06-01 11:06:13 -0400248 this->recordOp(std::move(op), caps);
bsalomonb8fea972016-02-16 07:34:17 -0800249 return true;
bsalomon@google.comeb851172013-04-15 13:51:00 +0000250}
251
Brian Salomona4677b52017-05-04 12:39:56 -0400252static inline bool can_reorder(const SkRect& a, const SkRect& b) { return !GrRectsOverlap(a, b); }
bsalomon88cf17d2016-07-08 06:40:56 -0700253
Brian Salomon54d212e2017-03-21 14:22:38 -0400254bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b,
255 const GrAppliedClip* bClip,
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400256 const DstProxy* bDstProxy,
Robert Phillipsee683652017-04-26 11:53:10 -0400257 const GrCaps& caps) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400258 if (a.fAppliedClip) {
259 if (!bClip) {
260 return false;
261 }
262 if (*a.fAppliedClip != *bClip) {
263 return false;
264 }
265 } else if (bClip) {
266 return false;
267 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400268 if (bDstProxy) {
269 if (a.fDstProxy != *bDstProxy) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400270 return false;
271 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400272 } else if (a.fDstProxy.proxy()) {
Brian Salomon54d212e2017-03-21 14:22:38 -0400273 return false;
274 }
Robert Phillipsee683652017-04-26 11:53:10 -0400275 return a.fOp->combineIfPossible(b, caps);
Brian Salomon54d212e2017-03-21 14:22:38 -0400276}
277
Brian Salomonf8334782017-01-03 09:42:58 -0500278GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400279 const GrCaps& caps,
Brian Salomon54d212e2017-03-21 14:22:38 -0400280 GrAppliedClip* clip,
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400281 const DstProxy* dstProxy) {
Robert Phillips318c4192017-05-17 09:36:38 -0400282 SkASSERT(fTarget.get());
Robert Phillipsee683652017-04-26 11:53:10 -0400283
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500284 // A closed GrOpList should never receive new/more ops
robertphillips6a186652015-10-20 07:37:58 -0700285 SkASSERT(!this->isClosed());
robertphillipsa106c622015-10-16 09:07:06 -0700286
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500287 // Check if there is an op we can combine with by linearly searching back until we either
288 // 1) check every op
bsalomon512be532015-09-10 10:42:55 -0700289 // 2) intersect with something
290 // 3) find a 'blocker'
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400291 GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), fTarget.get()->uniqueID());
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400292 GrOP_INFO("opList: %d Recording (%s, opID: %u)\n"
293 "\tBounds [L: %.2f, T: %.2f R: %.2f B: %.2f]\n",
294 this->uniqueID(),
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500295 op->name(),
296 op->uniqueID(),
Robert Phillips1119dc32017-04-11 12:54:57 -0400297 op->bounds().fLeft, op->bounds().fTop,
298 op->bounds().fRight, op->bounds().fBottom);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500299 GrOP_INFO(SkTabString(op->dumpInfo(), 1).c_str());
Brian Salomon25a88092016-12-01 09:36:50 -0500300 GrOP_INFO("\tOutcome:\n");
Robert Phillips8185f592017-04-26 08:31:08 -0400301 int maxCandidates = SkTMin(kMaxOpLookback, fRecordedOps.count());
Brian Salomoncdcc33f2017-02-21 09:49:20 -0500302 // If we don't have a valid destination render target then we cannot reorder.
Robert Phillips318c4192017-05-17 09:36:38 -0400303 if (maxCandidates) {
bsalomon512be532015-09-10 10:42:55 -0700304 int i = 0;
305 while (true) {
Brian Salomon69868af2016-12-22 15:42:51 -0500306 const RecordedOp& candidate = fRecordedOps.fromBack(i);
Robert Phillips318c4192017-05-17 09:36:38 -0400307
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400308 if (this->combineIfPossible(candidate, op.get(), clip, dstProxy, caps)) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400309 GrOP_INFO("\t\tBackward: Combining with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500310 candidate.fOp->uniqueID());
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400311 GrOP_INFO("\t\t\tBackward: Combined op info:\n");
Brian Salomon199fb872017-02-06 09:41:10 -0500312 GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str());
Brian Salomon69868af2016-12-22 15:42:51 -0500313 GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get());
Brian Salomon69868af2016-12-22 15:42:51 -0500314 return candidate.fOp.get();
bsalomon512be532015-09-10 10:42:55 -0700315 }
316 // Stop going backwards if we would cause a painter's order violation.
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500317 if (!can_reorder(fRecordedOps.fromBack(i).fOp->bounds(), op->bounds())) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400318 GrOP_INFO("\t\tBackward: Intersects with (%s, opID: %u)\n", candidate.fOp->name(),
Brian Salomon69868af2016-12-22 15:42:51 -0500319 candidate.fOp->uniqueID());
bsalomon512be532015-09-10 10:42:55 -0700320 break;
321 }
322 ++i;
323 if (i == maxCandidates) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400324 GrOP_INFO("\t\tBackward: Reached max lookback or beginning of op array %d\n", i);
bsalomon512be532015-09-10 10:42:55 -0700325 break;
326 }
327 }
328 } else {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400329 GrOP_INFO("\t\tBackward: FirstOp\n");
bsalomon512be532015-09-10 10:42:55 -0700330 }
Brian Salomon42ad83a2016-12-20 16:14:45 -0500331 GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op);
Brian Salomon54d212e2017-03-21 14:22:38 -0400332 if (clip) {
333 clip = fClipAllocator.make<GrAppliedClip>(std::move(*clip));
Robert Phillipsc84c0302017-05-08 15:35:11 -0400334 SkDEBUGCODE(fNumClips++;)
Brian Salomon54d212e2017-03-21 14:22:38 -0400335 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400336 fRecordedOps.emplace_back(std::move(op), clip, dstProxy);
Robert Phillipse3302df2017-04-24 07:31:02 -0400337 fRecordedOps.back().fOp->wasRecorded(this);
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500338 fLastFullClearOp = nullptr;
Brian Salomon2790c522016-12-09 16:32:23 -0500339 return fRecordedOps.back().fOp.get();
bsalomon512be532015-09-10 10:42:55 -0700340}
341
Robert Phillipsee683652017-04-26 11:53:10 -0400342void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) {
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400343 SkASSERT(!this->isClosed());
344
Robert Phillips48567ac2017-06-01 08:46:00 -0400345 GrOP_INFO("opList: %d ForwardCombine %d ops:\n", this->uniqueID(), fRecordedOps.count());
346
Brian Salomon337432d2017-03-21 17:36:10 -0400347 for (int i = 0; i < fRecordedOps.count() - 1; ++i) {
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500348 GrOp* op = fRecordedOps[i].fOp.get();
Robert Phillips318c4192017-05-17 09:36:38 -0400349
Robert Phillips8185f592017-04-26 08:31:08 -0400350 int maxCandidateIdx = SkTMin(i + kMaxOpLookahead, fRecordedOps.count() - 1);
bsalomonaecc0182016-03-07 11:50:44 -0800351 int j = i + 1;
352 while (true) {
Brian Salomon69868af2016-12-22 15:42:51 -0500353 const RecordedOp& candidate = fRecordedOps[j];
Robert Phillips318c4192017-05-17 09:36:38 -0400354
Brian Salomon54d212e2017-03-21 14:22:38 -0400355 if (this->combineIfPossible(fRecordedOps[i], candidate.fOp.get(),
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400356 candidate.fAppliedClip, &candidate.fDstProxy, caps)) {
Robert Phillips48567ac2017-06-01 08:46:00 -0400357 GrOP_INFO("\t\t%d: (%s opID: %u) -> Combining with (%s, opID: %u)\n",
358 i, op->name(), op->uniqueID(),
359 candidate.fOp->name(), candidate.fOp->uniqueID());
Brian Salomon69868af2016-12-22 15:42:51 -0500360 GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get());
Brian Salomon1e41f4a2016-12-07 15:05:04 -0500361 fRecordedOps[j].fOp = std::move(fRecordedOps[i].fOp);
bsalomonaecc0182016-03-07 11:50:44 -0800362 break;
363 }
Robert Phillipsc84c0302017-05-08 15:35:11 -0400364 // Stop traversing if we would cause a painter's order violation.
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500365 if (!can_reorder(fRecordedOps[j].fOp->bounds(), op->bounds())) {
Robert Phillips48567ac2017-06-01 08:46:00 -0400366 GrOP_INFO("\t\t%d: (%s opID: %u) -> Intersects with (%s, opID: %u)\n",
367 i, op->name(), op->uniqueID(),
368 candidate.fOp->name(), candidate.fOp->uniqueID());
bsalomonaecc0182016-03-07 11:50:44 -0800369 break;
370 }
371 ++j;
372 if (j > maxCandidateIdx) {
Robert Phillips48567ac2017-06-01 08:46:00 -0400373 GrOP_INFO("\t\t%d: (%s opID: %u) -> Reached max lookahead or end of array\n",
374 i, op->name(), op->uniqueID());
bsalomonaecc0182016-03-07 11:50:44 -0800375 break;
376 }
377 }
378 }
379}
380