reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * 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.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 8 | #include "GrRenderTargetOpList.h" |
joshualitt | 086cee1 | 2016-01-12 06:45:24 -0800 | [diff] [blame] | 9 | #include "GrAuditTrail.h" |
bsalomon | eb1cb5c | 2015-05-22 08:01:09 -0700 | [diff] [blame] | 10 | #include "GrCaps.h" |
bsalomon | 4061b12 | 2015-05-29 10:26:19 -0700 | [diff] [blame] | 11 | #include "GrGpu.h" |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 12 | #include "GrGpuCommandBuffer.h" |
Brian Salomon | a4677b5 | 2017-05-04 12:39:56 -0400 | [diff] [blame] | 13 | #include "GrRect.h" |
bsalomon@google.com | 8f9cbd6 | 2011-12-09 15:55:34 +0000 | [diff] [blame] | 14 | #include "GrRenderTarget.h" |
Brian Salomon | 467921e | 2017-03-06 16:17:12 -0500 | [diff] [blame] | 15 | #include "GrRenderTargetContext.h" |
bsalomon | 4061b12 | 2015-05-29 10:26:19 -0700 | [diff] [blame] | 16 | #include "GrResourceProvider.h" |
Brian Salomon | a4677b5 | 2017-05-04 12:39:56 -0400 | [diff] [blame] | 17 | #include "instanced/InstancedRendering.h" |
Brian Salomon | 8952743 | 2016-12-16 09:52:16 -0500 | [diff] [blame] | 18 | #include "ops/GrClearOp.h" |
Brian Salomon | 8952743 | 2016-12-16 09:52:16 -0500 | [diff] [blame] | 19 | #include "ops/GrCopySurfaceOp.h" |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 20 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 21 | using gr_instanced::InstancedRendering; |
| 22 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 23 | //////////////////////////////////////////////////////////////////////////////// |
| 24 | |
Brian Salomon | 09d994e | 2016-12-21 11:14:46 -0500 | [diff] [blame] | 25 | // Experimentally we have found that most combining occurs within the first 10 comparisons. |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 26 | static const int kMaxOpLookback = 10; |
| 27 | static const int kMaxOpLookahead = 10; |
bsalomon | 489147c | 2015-12-14 12:13:09 -0800 | [diff] [blame] | 28 | |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 29 | GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* proxy, GrGpu* gpu, |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 30 | GrAuditTrail* auditTrail) |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 31 | : INHERITED(proxy, auditTrail) |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 32 | , fLastClipStackGenID(SK_InvalidUniqueID) |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 33 | SkDEBUGCODE(, fNumClips(0)) { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 34 | if (GrCaps::InstancedSupport::kNone != gpu->caps()->instancedSupport()) { |
| 35 | fInstancedRendering.reset(gpu->createInstancedRendering()); |
csmartdalton | e0d3629 | 2016-07-29 08:14:20 -0700 | [diff] [blame] | 36 | } |
bsalomon | 4061b12 | 2015-05-29 10:26:19 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 39 | GrRenderTargetOpList::~GrRenderTargetOpList() { |
bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | //////////////////////////////////////////////////////////////////////////////// |
| 43 | |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 44 | #ifdef SK_DEBUG |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 45 | void GrRenderTargetOpList::dump() const { |
| 46 | INHERITED::dump(); |
| 47 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 48 | SkDebugf("ops (%d):\n", fRecordedOps.count()); |
| 49 | for (int i = 0; i < fRecordedOps.count(); ++i) { |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 50 | SkDebugf("*******************************\n"); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 51 | if (!fRecordedOps[i].fOp) { |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 52 | SkDebugf("%d: <combined forward>\n", i); |
| 53 | } else { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 54 | SkDebugf("%d: %s\n", i, fRecordedOps[i].fOp->name()); |
| 55 | SkString str = fRecordedOps[i].fOp->dumpInfo(); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 56 | SkDebugf("%s\n", str.c_str()); |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 57 | 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); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 60 | } |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 61 | } |
| 62 | } |
| 63 | #endif |
| 64 | |
Brian Salomon | 742e31d | 2016-12-07 17:06:19 -0500 | [diff] [blame] | 65 | void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) { |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 66 | SkASSERT(fTarget.get()->priv().peekRenderTarget()); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 67 | SkASSERT(this->isClosed()); |
robertphillips | a106c62 | 2015-10-16 09:07:06 -0700 | [diff] [blame] | 68 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 69 | // 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 Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 72 | GrOpFlushState::DrawOpArgs opArgs = { |
| 73 | fTarget.get()->priv().peekRenderTarget(), |
| 74 | fRecordedOps[i].fAppliedClip, |
| 75 | fRecordedOps[i].fDstTexture |
| 76 | }; |
| 77 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 78 | flushState->setDrawOpArgs(&opArgs); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 79 | fRecordedOps[i].fOp->prepare(flushState); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 80 | flushState->setDrawOpArgs(nullptr); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 81 | } |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 82 | } |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 83 | |
| 84 | if (fInstancedRendering) { |
| 85 | fInstancedRendering->beginFlush(flushState->resourceProvider()); |
| 86 | } |
robertphillips | a13e202 | 2015-11-11 12:01:09 -0800 | [diff] [blame] | 87 | } |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 88 | |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 89 | static 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 | |
| 102 | static inline void finish_command_buffer(GrGpuCommandBuffer* buffer) { |
| 103 | if (!buffer) { |
| 104 | return; |
| 105 | } |
| 106 | |
| 107 | buffer->end(); |
| 108 | buffer->submit(); |
| 109 | } |
| 110 | |
Brian Salomon | 25a8809 | 2016-12-01 09:36:50 -0500 | [diff] [blame] | 111 | // TODO: this is where GrOp::renderTarget is used (which is fine since it |
Robert Phillips | 294870f | 2016-11-11 12:38:40 -0500 | [diff] [blame] | 112 | // is at flush time). However, we need to store the RenderTargetProxy in the |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 113 | // Ops and instantiate them here. |
Brian Salomon | 742e31d | 2016-12-07 17:06:19 -0500 | [diff] [blame] | 114 | bool GrRenderTargetOpList::executeOps(GrOpFlushState* flushState) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 115 | if (0 == fRecordedOps.count()) { |
bsalomon | dc43898 | 2016-08-31 11:53:49 -0700 | [diff] [blame] | 116 | return false; |
egdaniel | b4021cf | 2016-07-28 08:53:07 -0700 | [diff] [blame] | 117 | } |
Robert Phillips | 4a39504 | 2017-04-24 16:27:17 +0000 | [diff] [blame] | 118 | |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 119 | SkASSERT(fTarget.get()->priv().peekRenderTarget()); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 120 | |
| 121 | std::unique_ptr<GrGpuCommandBuffer> commandBuffer = create_command_buffer(flushState->gpu()); |
| 122 | flushState->setCommandBuffer(commandBuffer.get()); |
| 123 | |
| 124 | // Draw all the generated geometry. |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 125 | for (int i = 0; i < fRecordedOps.count(); ++i) { |
| 126 | if (!fRecordedOps[i].fOp) { |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 127 | continue; |
| 128 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 129 | |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 130 | 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 Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 134 | |
| 135 | commandBuffer.reset(); |
| 136 | flushState->setCommandBuffer(commandBuffer.get()); |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 137 | } else if (!commandBuffer) { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 138 | commandBuffer = create_command_buffer(flushState->gpu()); |
Ben Wagner | 145dbcd | 2016-11-03 14:40:50 -0400 | [diff] [blame] | 139 | flushState->setCommandBuffer(commandBuffer.get()); |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 140 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 141 | |
| 142 | GrOpFlushState::DrawOpArgs opArgs { |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 143 | fTarget.get()->priv().peekRenderTarget(), |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 144 | fRecordedOps[i].fAppliedClip, |
Robert Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 145 | fRecordedOps[i].fDstTexture |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 146 | }; |
| 147 | |
| 148 | flushState->setDrawOpArgs(&opArgs); |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 149 | fRecordedOps[i].fOp->execute(flushState); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 150 | flushState->setDrawOpArgs(nullptr); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 151 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 152 | |
| 153 | finish_command_buffer(commandBuffer.get()); |
| 154 | flushState->setCommandBuffer(nullptr); |
ethannicholas | 2279325 | 2016-01-30 09:59:10 -0800 | [diff] [blame] | 155 | |
bsalomon | dc43898 | 2016-08-31 11:53:49 -0700 | [diff] [blame] | 156 | return true; |
bsalomon | a73239a | 2015-04-28 13:35:17 -0700 | [diff] [blame] | 157 | } |
| 158 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 159 | void GrRenderTargetOpList::reset() { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 160 | fLastFullClearOp = nullptr; |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 161 | fLastFullClearResourceID.makeInvalid(); |
| 162 | fLastFullClearProxyID.makeInvalid(); |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 163 | fLastClipStackGenID = SK_InvalidUniqueID; |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 164 | fRecordedOps.reset(); |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 165 | if (fInstancedRendering) { |
| 166 | fInstancedRendering->endFlush(); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 167 | fInstancedRendering = nullptr; |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 168 | } |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 169 | |
| 170 | INHERITED::reset(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 171 | } |
| 172 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 173 | void GrRenderTargetOpList::abandonGpuResources() { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 174 | if (fInstancedRendering) { |
| 175 | fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kAbandon); |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 176 | } |
| 177 | } |
| 178 | |
| 179 | void GrRenderTargetOpList::freeGpuResources() { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 180 | if (fInstancedRendering) { |
| 181 | fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kDestroy); |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 182 | } |
| 183 | } |
| 184 | |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 185 | void 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 Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 193 | // 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 |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 195 | // color. |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 196 | // 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 Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 203 | // 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 Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 206 | 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 Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 210 | fLastFullClearOp->setColor(color); |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 211 | return; |
| 212 | } |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 213 | std::unique_ptr<GrClearOp> op(GrClearOp::Make(GrFixedClip::Disabled(), color, |
| 214 | renderTargetContext)); |
Robert Phillips | f7a7261 | 2017-03-31 10:03:45 -0400 | [diff] [blame] | 215 | if (!op) { |
| 216 | return; |
| 217 | } |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 218 | if (GrOp* clearOp = this->recordOp(std::move(op), renderTargetContext)) { |
Brian Salomon | 2790c52 | 2016-12-09 16:32:23 -0500 | [diff] [blame] | 219 | // This is either the clear op we just created or another one that it combined with. |
Brian Salomon | 7dae46a | 2016-12-14 16:21:37 -0500 | [diff] [blame] | 220 | fLastFullClearOp = static_cast<GrClearOp*>(clearOp); |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 221 | fLastFullClearResourceID = renderTarget->uniqueID(); |
| 222 | fLastFullClearProxyID = renderTargetContext->asRenderTargetProxy()->uniqueID(); |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 223 | } |
bsalomon | 9f129de | 2016-08-10 16:31:05 -0700 | [diff] [blame] | 224 | } |
| 225 | |
bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 226 | //////////////////////////////////////////////////////////////////////////////// |
bsalomon@google.com | 86afc2a | 2011-02-16 16:12:19 +0000 | [diff] [blame] | 227 | |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 228 | // MDB TODO: fuse with GrTextureOpList::copySurface |
Robert Phillips | bf25d43 | 2017-04-07 10:08:53 -0400 | [diff] [blame] | 229 | bool GrRenderTargetOpList::copySurface(GrResourceProvider* resourceProvider, |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 230 | GrRenderTargetContext* dst, |
Robert Phillips | bf25d43 | 2017-04-07 10:08:53 -0400 | [diff] [blame] | 231 | GrSurfaceProxy* src, |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 232 | const SkIRect& srcRect, |
| 233 | const SkIPoint& dstPoint) { |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 234 | std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(resourceProvider, dst->asSurfaceProxy(), |
| 235 | src, srcRect, dstPoint); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 236 | if (!op) { |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 237 | return false; |
| 238 | } |
robertphillips | 498d7ac | 2015-10-30 10:11:30 -0700 | [diff] [blame] | 239 | #ifdef ENABLE_MDB |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 240 | this->addDependency(src); |
robertphillips | 498d7ac | 2015-10-30 10:11:30 -0700 | [diff] [blame] | 241 | #endif |
| 242 | |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 243 | this->recordOp(std::move(op), dst); |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 244 | return true; |
bsalomon@google.com | eb85117 | 2013-04-15 13:51:00 +0000 | [diff] [blame] | 245 | } |
| 246 | |
Brian Salomon | a4677b5 | 2017-05-04 12:39:56 -0400 | [diff] [blame] | 247 | static inline bool can_reorder(const SkRect& a, const SkRect& b) { return !GrRectsOverlap(a, b); } |
bsalomon | 88cf17d | 2016-07-08 06:40:56 -0700 | [diff] [blame] | 248 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 249 | bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b, |
| 250 | const GrAppliedClip* bClip, |
Robert Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 251 | const DstTexture* bDstTexture, |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 252 | const GrCaps& caps) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 253 | 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 Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 263 | if (bDstTexture) { |
| 264 | if (a.fDstTexture != *bDstTexture) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 265 | return false; |
| 266 | } |
Robert Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 267 | } else if (a.fDstTexture.texture()) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 268 | return false; |
| 269 | } |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 270 | return a.fOp->combineIfPossible(b, caps); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 271 | } |
| 272 | |
Brian Salomon | f833478 | 2017-01-03 09:42:58 -0500 | [diff] [blame] | 273 | GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op, |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 274 | GrRenderTargetContext* renderTargetContext, |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 275 | GrAppliedClip* clip, |
Robert Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 276 | const DstTexture* dstTexture) { |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 277 | SkASSERT(fTarget.get()); |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 278 | const GrCaps* caps = renderTargetContext->caps(); |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 279 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 280 | // A closed GrOpList should never receive new/more ops |
robertphillips | 6a18665 | 2015-10-20 07:37:58 -0700 | [diff] [blame] | 281 | SkASSERT(!this->isClosed()); |
robertphillips | a106c62 | 2015-10-16 09:07:06 -0700 | [diff] [blame] | 282 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 283 | // Check if there is an op we can combine with by linearly searching back until we either |
| 284 | // 1) check every op |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 285 | // 2) intersect with something |
| 286 | // 3) find a 'blocker' |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 287 | GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), |
| 288 | renderTargetContext->asRenderTargetProxy()->uniqueID()); |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 289 | GrOP_INFO("opList: %d Recording (%s, opID: %u)\n" |
| 290 | "\tBounds [L: %.2f, T: %.2f R: %.2f B: %.2f]\n", |
| 291 | this->uniqueID(), |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 292 | op->name(), |
| 293 | op->uniqueID(), |
Robert Phillips | 1119dc3 | 2017-04-11 12:54:57 -0400 | [diff] [blame] | 294 | op->bounds().fLeft, op->bounds().fTop, |
| 295 | op->bounds().fRight, op->bounds().fBottom); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 296 | GrOP_INFO(SkTabString(op->dumpInfo(), 1).c_str()); |
Brian Salomon | 25a8809 | 2016-12-01 09:36:50 -0500 | [diff] [blame] | 297 | GrOP_INFO("\tOutcome:\n"); |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 298 | int maxCandidates = SkTMin(kMaxOpLookback, fRecordedOps.count()); |
Brian Salomon | cdcc33f | 2017-02-21 09:49:20 -0500 | [diff] [blame] | 299 | // If we don't have a valid destination render target then we cannot reorder. |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 300 | if (maxCandidates) { |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 301 | int i = 0; |
| 302 | while (true) { |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 303 | const RecordedOp& candidate = fRecordedOps.fromBack(i); |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 304 | |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 305 | if (this->combineIfPossible(candidate, op.get(), clip, dstTexture, *caps)) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 306 | GrOP_INFO("\t\tBackward: Combining with (%s, opID: %u)\n", candidate.fOp->name(), |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 307 | candidate.fOp->uniqueID()); |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 308 | GrOP_INFO("\t\t\tBackward: Combined op info:\n"); |
Brian Salomon | 199fb87 | 2017-02-06 09:41:10 -0500 | [diff] [blame] | 309 | GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str()); |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 310 | GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get()); |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 311 | return candidate.fOp.get(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 312 | } |
| 313 | // Stop going backwards if we would cause a painter's order violation. |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 314 | if (!can_reorder(fRecordedOps.fromBack(i).fOp->bounds(), op->bounds())) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 315 | GrOP_INFO("\t\tBackward: Intersects with (%s, opID: %u)\n", candidate.fOp->name(), |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 316 | candidate.fOp->uniqueID()); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 317 | break; |
| 318 | } |
| 319 | ++i; |
| 320 | if (i == maxCandidates) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 321 | GrOP_INFO("\t\tBackward: Reached max lookback or beginning of op array %d\n", i); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 322 | break; |
| 323 | } |
| 324 | } |
| 325 | } else { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 326 | GrOP_INFO("\t\tBackward: FirstOp\n"); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 327 | } |
Brian Salomon | 42ad83a | 2016-12-20 16:14:45 -0500 | [diff] [blame] | 328 | GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 329 | if (clip) { |
| 330 | clip = fClipAllocator.make<GrAppliedClip>(std::move(*clip)); |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 331 | SkDEBUGCODE(fNumClips++;) |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 332 | } |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 333 | fRecordedOps.emplace_back(std::move(op), clip, dstTexture); |
Robert Phillips | e3302df | 2017-04-24 07:31:02 -0400 | [diff] [blame] | 334 | fRecordedOps.back().fOp->wasRecorded(this); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 335 | fLastFullClearOp = nullptr; |
Robert Phillips | 33f8315 | 2017-05-18 20:57:43 +0000 | [diff] [blame] | 336 | fLastFullClearResourceID.makeInvalid(); |
| 337 | fLastFullClearProxyID.makeInvalid(); |
Brian Salomon | 2790c52 | 2016-12-09 16:32:23 -0500 | [diff] [blame] | 338 | return fRecordedOps.back().fOp.get(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 339 | } |
| 340 | |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 341 | void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 342 | SkASSERT(!this->isClosed()); |
| 343 | |
Brian Salomon | 337432d | 2017-03-21 17:36:10 -0400 | [diff] [blame] | 344 | for (int i = 0; i < fRecordedOps.count() - 1; ++i) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 345 | GrOp* op = fRecordedOps[i].fOp.get(); |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 346 | |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 347 | int maxCandidateIdx = SkTMin(i + kMaxOpLookahead, fRecordedOps.count() - 1); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 348 | int j = i + 1; |
| 349 | while (true) { |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 350 | const RecordedOp& candidate = fRecordedOps[j]; |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 351 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 352 | if (this->combineIfPossible(fRecordedOps[i], candidate.fOp.get(), |
Robert Phillips | c375704 | 2017-05-17 13:00:14 +0000 | [diff] [blame] | 353 | candidate.fAppliedClip, &candidate.fDstTexture, caps)) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 354 | GrOP_INFO("\t\tForward: Combining with (%s, opID: %u)\n", candidate.fOp->name(), |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 355 | candidate.fOp->uniqueID()); |
| 356 | GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get()); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 357 | fRecordedOps[j].fOp = std::move(fRecordedOps[i].fOp); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 358 | break; |
| 359 | } |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 360 | // Stop traversing if we would cause a painter's order violation. |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 361 | if (!can_reorder(fRecordedOps[j].fOp->bounds(), op->bounds())) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 362 | GrOP_INFO("\t\tForward: Intersects with (%s, opID: %u)\n", candidate.fOp->name(), |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 363 | candidate.fOp->uniqueID()); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 364 | break; |
| 365 | } |
| 366 | ++j; |
| 367 | if (j > maxCandidateIdx) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 368 | GrOP_INFO("\t\tForward: Reached max lookahead or end of op array %d\n", i); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 369 | break; |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | } |
| 374 | |