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" |
Brian Salomon | 467921e | 2017-03-06 16:17:12 -0500 | [diff] [blame] | 14 | #include "GrRenderTargetContext.h" |
Brian Salomon | a4677b5 | 2017-05-04 12:39:56 -0400 | [diff] [blame] | 15 | #include "instanced/InstancedRendering.h" |
Brian Salomon | 8952743 | 2016-12-16 09:52:16 -0500 | [diff] [blame] | 16 | #include "ops/GrClearOp.h" |
Brian Salomon | 8952743 | 2016-12-16 09:52:16 -0500 | [diff] [blame] | 17 | #include "ops/GrCopySurfaceOp.h" |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 18 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 19 | using gr_instanced::InstancedRendering; |
| 20 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 21 | //////////////////////////////////////////////////////////////////////////////// |
| 22 | |
Brian Salomon | 09d994e | 2016-12-21 11:14:46 -0500 | [diff] [blame] | 23 | // 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] | 24 | static const int kMaxOpLookback = 10; |
| 25 | static const int kMaxOpLookahead = 10; |
bsalomon | 489147c | 2015-12-14 12:13:09 -0800 | [diff] [blame] | 26 | |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 27 | GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* proxy, GrGpu* gpu, |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 28 | GrAuditTrail* auditTrail) |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 29 | : INHERITED(gpu->getContext()->resourceProvider(), proxy, auditTrail) |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 30 | , fLastClipStackGenID(SK_InvalidUniqueID) |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 31 | SkDEBUGCODE(, fNumClips(0)) { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 32 | if (GrCaps::InstancedSupport::kNone != gpu->caps()->instancedSupport()) { |
| 33 | fInstancedRendering.reset(gpu->createInstancedRendering()); |
csmartdalton | e0d3629 | 2016-07-29 08:14:20 -0700 | [diff] [blame] | 34 | } |
bsalomon | 4061b12 | 2015-05-29 10:26:19 -0700 | [diff] [blame] | 35 | } |
| 36 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 37 | GrRenderTargetOpList::~GrRenderTargetOpList() { |
bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | //////////////////////////////////////////////////////////////////////////////// |
| 41 | |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 42 | #ifdef SK_DEBUG |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 43 | void GrRenderTargetOpList::dump() const { |
| 44 | INHERITED::dump(); |
| 45 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 46 | SkDebugf("ops (%d):\n", fRecordedOps.count()); |
| 47 | for (int i = 0; i < fRecordedOps.count(); ++i) { |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 48 | SkDebugf("*******************************\n"); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 49 | if (!fRecordedOps[i].fOp) { |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 50 | SkDebugf("%d: <combined forward>\n", i); |
| 51 | } else { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 52 | SkDebugf("%d: %s\n", i, fRecordedOps[i].fOp->name()); |
| 53 | SkString str = fRecordedOps[i].fOp->dumpInfo(); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 54 | SkDebugf("%s\n", str.c_str()); |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 55 | 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); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 58 | } |
robertphillips | 4beb5c1 | 2015-10-20 07:50:00 -0700 | [diff] [blame] | 59 | } |
| 60 | } |
| 61 | #endif |
| 62 | |
Brian Salomon | 742e31d | 2016-12-07 17:06:19 -0500 | [diff] [blame] | 63 | void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) { |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 64 | SkASSERT(fTarget.get()->priv().peekRenderTarget()); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 65 | SkASSERT(this->isClosed()); |
robertphillips | a106c62 | 2015-10-16 09:07:06 -0700 | [diff] [blame] | 66 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 67 | // 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 Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 70 | GrOpFlushState::DrawOpArgs opArgs = { |
Robert Phillips | 2890fbf | 2017-07-26 15:48:41 -0400 | [diff] [blame] | 71 | fTarget.get()->asRenderTargetProxy(), |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 72 | fRecordedOps[i].fAppliedClip, |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 73 | fRecordedOps[i].fDstProxy |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 74 | }; |
| 75 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 76 | flushState->setDrawOpArgs(&opArgs); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 77 | fRecordedOps[i].fOp->prepare(flushState); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 78 | flushState->setDrawOpArgs(nullptr); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 79 | } |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 80 | } |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 81 | |
| 82 | if (fInstancedRendering) { |
| 83 | fInstancedRendering->beginFlush(flushState->resourceProvider()); |
| 84 | } |
robertphillips | a13e202 | 2015-11-11 12:01:09 -0800 | [diff] [blame] | 85 | } |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 86 | |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 87 | static std::unique_ptr<GrGpuCommandBuffer> create_command_buffer(GrGpu* gpu, |
| 88 | GrRenderTarget* rt, |
| 89 | GrSurfaceOrigin origin, |
Robert Phillips | 54190c4 | 2017-08-09 20:09:38 +0000 | [diff] [blame] | 90 | bool clearSB) { |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 91 | static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo { |
Robert Phillips | 54190c4 | 2017-08-09 20:09:38 +0000 | [diff] [blame] | 92 | GrGpuCommandBuffer::LoadOp::kLoad, |
| 93 | GrGpuCommandBuffer::StoreOp::kStore, |
| 94 | GrColor_ILLEGAL |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 95 | }; |
| 96 | |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 97 | // 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 Phillips | 54190c4 | 2017-08-09 20:09:38 +0000 | [diff] [blame] | 103 | clearSB ? GrGpuCommandBuffer::LoadOp::kClear : GrGpuCommandBuffer::LoadOp::kLoad, |
| 104 | GrGpuCommandBuffer::StoreOp::kStore, |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 105 | }; |
| 106 | |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 107 | std::unique_ptr<GrGpuCommandBuffer> buffer( |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 108 | gpu->createCommandBuffer(rt, origin, |
| 109 | kBasicLoadStoreInfo, // Color |
| 110 | stencilLoadAndStoreInfo)); // Stencil |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 111 | return buffer; |
| 112 | } |
| 113 | |
| 114 | static inline void finish_command_buffer(GrGpuCommandBuffer* buffer) { |
| 115 | if (!buffer) { |
| 116 | return; |
| 117 | } |
| 118 | |
| 119 | buffer->end(); |
| 120 | buffer->submit(); |
| 121 | } |
| 122 | |
Brian Salomon | 25a8809 | 2016-12-01 09:36:50 -0500 | [diff] [blame] | 123 | // 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] | 124 | // 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] | 125 | // Ops and instantiate them here. |
Brian Salomon | 742e31d | 2016-12-07 17:06:19 -0500 | [diff] [blame] | 126 | bool GrRenderTargetOpList::executeOps(GrOpFlushState* flushState) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 127 | if (0 == fRecordedOps.count()) { |
bsalomon | dc43898 | 2016-08-31 11:53:49 -0700 | [diff] [blame] | 128 | return false; |
egdaniel | b4021cf | 2016-07-28 08:53:07 -0700 | [diff] [blame] | 129 | } |
Robert Phillips | 4a39504 | 2017-04-24 16:27:17 +0000 | [diff] [blame] | 130 | |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 131 | SkASSERT(fTarget.get()->priv().peekRenderTarget()); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 132 | |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 133 | std::unique_ptr<GrGpuCommandBuffer> commandBuffer = create_command_buffer( |
| 134 | flushState->gpu(), |
| 135 | fTarget.get()->priv().peekRenderTarget(), |
| 136 | fTarget.get()->origin(), |
Robert Phillips | 54190c4 | 2017-08-09 20:09:38 +0000 | [diff] [blame] | 137 | this->requiresStencil()); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 138 | flushState->setCommandBuffer(commandBuffer.get()); |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 139 | commandBuffer->begin(); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 140 | |
| 141 | // Draw all the generated geometry. |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 142 | for (int i = 0; i < fRecordedOps.count(); ++i) { |
| 143 | if (!fRecordedOps[i].fOp) { |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 144 | continue; |
| 145 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 146 | |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 147 | 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 Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 151 | |
| 152 | commandBuffer.reset(); |
| 153 | flushState->setCommandBuffer(commandBuffer.get()); |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 154 | } else if (!commandBuffer) { |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 155 | commandBuffer = create_command_buffer(flushState->gpu(), |
| 156 | fTarget.get()->priv().peekRenderTarget(), |
| 157 | fTarget.get()->origin(), |
Robert Phillips | 54190c4 | 2017-08-09 20:09:38 +0000 | [diff] [blame] | 158 | false); |
Ben Wagner | 145dbcd | 2016-11-03 14:40:50 -0400 | [diff] [blame] | 159 | flushState->setCommandBuffer(commandBuffer.get()); |
Robert Phillips | 9521447 | 2017-08-08 18:00:03 -0400 | [diff] [blame] | 160 | commandBuffer->begin(); |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 161 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 162 | |
| 163 | GrOpFlushState::DrawOpArgs opArgs { |
Robert Phillips | 2890fbf | 2017-07-26 15:48:41 -0400 | [diff] [blame] | 164 | fTarget.get()->asRenderTargetProxy(), |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 165 | fRecordedOps[i].fAppliedClip, |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 166 | fRecordedOps[i].fDstProxy |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 167 | }; |
| 168 | |
| 169 | flushState->setDrawOpArgs(&opArgs); |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 170 | fRecordedOps[i].fOp->execute(flushState); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 171 | flushState->setDrawOpArgs(nullptr); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 172 | } |
Robert Phillips | 178ce3e | 2017-04-13 09:15:47 -0400 | [diff] [blame] | 173 | |
| 174 | finish_command_buffer(commandBuffer.get()); |
| 175 | flushState->setCommandBuffer(nullptr); |
ethannicholas | 2279325 | 2016-01-30 09:59:10 -0800 | [diff] [blame] | 176 | |
bsalomon | dc43898 | 2016-08-31 11:53:49 -0700 | [diff] [blame] | 177 | return true; |
bsalomon | a73239a | 2015-04-28 13:35:17 -0700 | [diff] [blame] | 178 | } |
| 179 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 180 | void GrRenderTargetOpList::reset() { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 181 | fLastFullClearOp = nullptr; |
Robert Phillips | b6deea8 | 2017-05-11 14:14:30 -0400 | [diff] [blame] | 182 | fLastClipStackGenID = SK_InvalidUniqueID; |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 183 | fRecordedOps.reset(); |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 184 | if (fInstancedRendering) { |
| 185 | fInstancedRendering->endFlush(); |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 186 | fInstancedRendering = nullptr; |
csmartdalton | a7f2964 | 2016-07-07 08:49:11 -0700 | [diff] [blame] | 187 | } |
Robert Phillips | 6cdc22c | 2017-05-11 16:29:14 -0400 | [diff] [blame] | 188 | |
| 189 | INHERITED::reset(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 190 | } |
| 191 | |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 192 | void GrRenderTargetOpList::abandonGpuResources() { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 193 | if (fInstancedRendering) { |
| 194 | fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kAbandon); |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 195 | } |
| 196 | } |
| 197 | |
| 198 | void GrRenderTargetOpList::freeGpuResources() { |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 199 | if (fInstancedRendering) { |
| 200 | fInstancedRendering->resetGpuResources(InstancedRendering::ResetType::kDestroy); |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 201 | } |
| 202 | } |
| 203 | |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 204 | void GrRenderTargetOpList::fullClear(const GrCaps& caps, GrColor color) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 205 | // 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 |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 207 | // color. |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 208 | if (fLastFullClearOp) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 209 | // 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 Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 212 | 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 Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 216 | fLastFullClearOp->setColor(color); |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 217 | return; |
| 218 | } |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 219 | std::unique_ptr<GrClearOp> op(GrClearOp::Make(GrFixedClip::Disabled(), color, fTarget.get())); |
Robert Phillips | f7a7261 | 2017-03-31 10:03:45 -0400 | [diff] [blame] | 220 | if (!op) { |
| 221 | return; |
| 222 | } |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 223 | |
| 224 | if (GrOp* clearOp = this->recordOp(std::move(op), caps)) { |
Brian Salomon | 2790c52 | 2016-12-09 16:32:23 -0500 | [diff] [blame] | 225 | // 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] | 226 | fLastFullClearOp = static_cast<GrClearOp*>(clearOp); |
bsalomon | fd8d013 | 2016-08-11 11:25:33 -0700 | [diff] [blame] | 227 | } |
bsalomon | 9f129de | 2016-08-10 16:31:05 -0700 | [diff] [blame] | 228 | } |
| 229 | |
bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 230 | //////////////////////////////////////////////////////////////////////////////// |
bsalomon@google.com | 86afc2a | 2011-02-16 16:12:19 +0000 | [diff] [blame] | 231 | |
Robert Phillips | 81dd3e0 | 2017-06-23 11:59:24 -0400 | [diff] [blame] | 232 | // This closely parallels GrTextureOpList::copySurface but renderTargetOpLists |
| 233 | // also store the applied clip and dest proxy with the op |
Robert Phillips | a16f6cb | 2017-06-01 11:06:13 -0400 | [diff] [blame] | 234 | bool GrRenderTargetOpList::copySurface(const GrCaps& caps, |
| 235 | GrSurfaceProxy* dst, |
Robert Phillips | bf25d43 | 2017-04-07 10:08:53 -0400 | [diff] [blame] | 236 | GrSurfaceProxy* src, |
Robert Phillips | f2361d2 | 2016-10-25 14:20:06 -0400 | [diff] [blame] | 237 | const SkIRect& srcRect, |
| 238 | const SkIPoint& dstPoint) { |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 239 | SkASSERT(dst->asRenderTargetProxy() == fTarget.get()); |
Robert Phillips | a16f6cb | 2017-06-01 11:06:13 -0400 | [diff] [blame] | 240 | std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(dst, src, srcRect, dstPoint); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 241 | if (!op) { |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 242 | return false; |
| 243 | } |
robertphillips | 498d7ac | 2015-10-30 10:11:30 -0700 | [diff] [blame] | 244 | #ifdef ENABLE_MDB |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 245 | this->addDependency(src); |
robertphillips | 498d7ac | 2015-10-30 10:11:30 -0700 | [diff] [blame] | 246 | #endif |
| 247 | |
Robert Phillips | a16f6cb | 2017-06-01 11:06:13 -0400 | [diff] [blame] | 248 | this->recordOp(std::move(op), caps); |
bsalomon | b8fea97 | 2016-02-16 07:34:17 -0800 | [diff] [blame] | 249 | return true; |
bsalomon@google.com | eb85117 | 2013-04-15 13:51:00 +0000 | [diff] [blame] | 250 | } |
| 251 | |
Brian Salomon | a4677b5 | 2017-05-04 12:39:56 -0400 | [diff] [blame] | 252 | 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] | 253 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 254 | bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b, |
| 255 | const GrAppliedClip* bClip, |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 256 | const DstProxy* bDstProxy, |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 257 | const GrCaps& caps) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 258 | 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 Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 268 | if (bDstProxy) { |
| 269 | if (a.fDstProxy != *bDstProxy) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 270 | return false; |
| 271 | } |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 272 | } else if (a.fDstProxy.proxy()) { |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 273 | return false; |
| 274 | } |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 275 | return a.fOp->combineIfPossible(b, caps); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 276 | } |
| 277 | |
Brian Salomon | f833478 | 2017-01-03 09:42:58 -0500 | [diff] [blame] | 278 | GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op, |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 279 | const GrCaps& caps, |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 280 | GrAppliedClip* clip, |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 281 | const DstProxy* dstProxy) { |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 282 | SkASSERT(fTarget.get()); |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 283 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 284 | // A closed GrOpList should never receive new/more ops |
robertphillips | 6a18665 | 2015-10-20 07:37:58 -0700 | [diff] [blame] | 285 | SkASSERT(!this->isClosed()); |
robertphillips | a106c62 | 2015-10-16 09:07:06 -0700 | [diff] [blame] | 286 | |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 287 | // Check if there is an op we can combine with by linearly searching back until we either |
| 288 | // 1) check every op |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 289 | // 2) intersect with something |
| 290 | // 3) find a 'blocker' |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 291 | GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), fTarget.get()->uniqueID()); |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 292 | GrOP_INFO("opList: %d Recording (%s, opID: %u)\n" |
| 293 | "\tBounds [L: %.2f, T: %.2f R: %.2f B: %.2f]\n", |
| 294 | this->uniqueID(), |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 295 | op->name(), |
| 296 | op->uniqueID(), |
Robert Phillips | 1119dc3 | 2017-04-11 12:54:57 -0400 | [diff] [blame] | 297 | op->bounds().fLeft, op->bounds().fTop, |
| 298 | op->bounds().fRight, op->bounds().fBottom); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 299 | GrOP_INFO(SkTabString(op->dumpInfo(), 1).c_str()); |
Brian Salomon | 25a8809 | 2016-12-01 09:36:50 -0500 | [diff] [blame] | 300 | GrOP_INFO("\tOutcome:\n"); |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 301 | int maxCandidates = SkTMin(kMaxOpLookback, fRecordedOps.count()); |
Brian Salomon | cdcc33f | 2017-02-21 09:49:20 -0500 | [diff] [blame] | 302 | // 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] | 303 | if (maxCandidates) { |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 304 | int i = 0; |
| 305 | while (true) { |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 306 | const RecordedOp& candidate = fRecordedOps.fromBack(i); |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 307 | |
Robert Phillips | 5efd5ea | 2017-05-30 13:47:32 -0400 | [diff] [blame] | 308 | if (this->combineIfPossible(candidate, op.get(), clip, dstProxy, caps)) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 309 | 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] | 310 | candidate.fOp->uniqueID()); |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 311 | GrOP_INFO("\t\t\tBackward: Combined op info:\n"); |
Brian Salomon | 199fb87 | 2017-02-06 09:41:10 -0500 | [diff] [blame] | 312 | GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str()); |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 313 | GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get()); |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 314 | return candidate.fOp.get(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 315 | } |
| 316 | // Stop going backwards if we would cause a painter's order violation. |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 317 | if (!can_reorder(fRecordedOps.fromBack(i).fOp->bounds(), op->bounds())) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 318 | 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] | 319 | candidate.fOp->uniqueID()); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 320 | break; |
| 321 | } |
| 322 | ++i; |
| 323 | if (i == maxCandidates) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 324 | 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] | 325 | break; |
| 326 | } |
| 327 | } |
| 328 | } else { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 329 | GrOP_INFO("\t\tBackward: FirstOp\n"); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 330 | } |
Brian Salomon | 42ad83a | 2016-12-20 16:14:45 -0500 | [diff] [blame] | 331 | GR_AUDIT_TRAIL_OP_RESULT_NEW(fAuditTrail, op); |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 332 | if (clip) { |
| 333 | clip = fClipAllocator.make<GrAppliedClip>(std::move(*clip)); |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 334 | SkDEBUGCODE(fNumClips++;) |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 335 | } |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 336 | fRecordedOps.emplace_back(std::move(op), clip, dstProxy); |
Robert Phillips | e3302df | 2017-04-24 07:31:02 -0400 | [diff] [blame] | 337 | fRecordedOps.back().fOp->wasRecorded(this); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 338 | fLastFullClearOp = nullptr; |
Brian Salomon | 2790c52 | 2016-12-09 16:32:23 -0500 | [diff] [blame] | 339 | return fRecordedOps.back().fOp.get(); |
bsalomon | 512be53 | 2015-09-10 10:42:55 -0700 | [diff] [blame] | 340 | } |
| 341 | |
Robert Phillips | ee68365 | 2017-04-26 11:53:10 -0400 | [diff] [blame] | 342 | void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) { |
Robert Phillips | f5442bb | 2017-04-17 14:18:34 -0400 | [diff] [blame] | 343 | SkASSERT(!this->isClosed()); |
| 344 | |
Robert Phillips | 48567ac | 2017-06-01 08:46:00 -0400 | [diff] [blame] | 345 | GrOP_INFO("opList: %d ForwardCombine %d ops:\n", this->uniqueID(), fRecordedOps.count()); |
| 346 | |
Brian Salomon | 337432d | 2017-03-21 17:36:10 -0400 | [diff] [blame] | 347 | for (int i = 0; i < fRecordedOps.count() - 1; ++i) { |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 348 | GrOp* op = fRecordedOps[i].fOp.get(); |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 349 | |
Robert Phillips | 8185f59 | 2017-04-26 08:31:08 -0400 | [diff] [blame] | 350 | int maxCandidateIdx = SkTMin(i + kMaxOpLookahead, fRecordedOps.count() - 1); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 351 | int j = i + 1; |
| 352 | while (true) { |
Brian Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 353 | const RecordedOp& candidate = fRecordedOps[j]; |
Robert Phillips | 318c419 | 2017-05-17 09:36:38 -0400 | [diff] [blame] | 354 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 355 | if (this->combineIfPossible(fRecordedOps[i], candidate.fOp.get(), |
Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 356 | candidate.fAppliedClip, &candidate.fDstProxy, caps)) { |
Robert Phillips | 48567ac | 2017-06-01 08:46:00 -0400 | [diff] [blame] | 357 | 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 Salomon | 69868af | 2016-12-22 15:42:51 -0500 | [diff] [blame] | 360 | GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get()); |
Brian Salomon | 1e41f4a | 2016-12-07 15:05:04 -0500 | [diff] [blame] | 361 | fRecordedOps[j].fOp = std::move(fRecordedOps[i].fOp); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 362 | break; |
| 363 | } |
Robert Phillips | c84c030 | 2017-05-08 15:35:11 -0400 | [diff] [blame] | 364 | // Stop traversing if we would cause a painter's order violation. |
Brian Salomon | 9e50f7b | 2017-03-06 12:02:34 -0500 | [diff] [blame] | 365 | if (!can_reorder(fRecordedOps[j].fOp->bounds(), op->bounds())) { |
Robert Phillips | 48567ac | 2017-06-01 08:46:00 -0400 | [diff] [blame] | 366 | 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()); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 369 | break; |
| 370 | } |
| 371 | ++j; |
| 372 | if (j > maxCandidateIdx) { |
Robert Phillips | 48567ac | 2017-06-01 08:46:00 -0400 | [diff] [blame] | 373 | GrOP_INFO("\t\t%d: (%s opID: %u) -> Reached max lookahead or end of array\n", |
| 374 | i, op->name(), op->uniqueID()); |
bsalomon | aecc018 | 2016-03-07 11:50:44 -0800 | [diff] [blame] | 375 | break; |
| 376 | } |
| 377 | } |
| 378 | } |
| 379 | } |
| 380 | |