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