OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrDrawTarget.h" | 9 #include "GrDrawTarget.h" |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "batches/GrCopySurfaceBatch.h" | 28 #include "batches/GrCopySurfaceBatch.h" |
29 #include "batches/GrDiscardBatch.h" | 29 #include "batches/GrDiscardBatch.h" |
30 #include "batches/GrDrawBatch.h" | 30 #include "batches/GrDrawBatch.h" |
31 #include "batches/GrDrawPathBatch.h" | 31 #include "batches/GrDrawPathBatch.h" |
32 #include "batches/GrRectBatchFactory.h" | 32 #include "batches/GrRectBatchFactory.h" |
33 #include "batches/GrStencilPathBatch.h" | 33 #include "batches/GrStencilPathBatch.h" |
34 | 34 |
35 //////////////////////////////////////////////////////////////////////////////// | 35 //////////////////////////////////////////////////////////////////////////////// |
36 | 36 |
37 // Experimentally we have found that most batching occurs within the first 10 co
mparisons. | 37 // Experimentally we have found that most batching occurs within the first 10 co
mparisons. |
38 static const int kDefaultMaxBatchLookback = 10; | 38 static const int kDefaultMaxBatchLookback = 10; |
| 39 static const int kDefaultMaxBatchLookahead = 10; |
39 | 40 |
40 GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* r
esourceProvider, | 41 GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* r
esourceProvider, |
41 GrAuditTrail* auditTrail, const Options& options) | 42 GrAuditTrail* auditTrail, const Options& options) |
42 : fGpu(SkRef(gpu)) | 43 : fGpu(SkRef(gpu)) |
43 , fResourceProvider(resourceProvider) | 44 , fResourceProvider(resourceProvider) |
44 , fAuditTrail(auditTrail) | 45 , fAuditTrail(auditTrail) |
45 , fFlags(0) | 46 , fFlags(0) |
46 , fRenderTarget(rt) { | 47 , fRenderTarget(rt) { |
47 // TODO: Stop extracting the context (currently needed by GrClipMaskManager) | 48 // TODO: Stop extracting the context (currently needed by GrClipMaskManager) |
48 fContext = fGpu->getContext(); | 49 fContext = fGpu->getContext(); |
49 fClipMaskManager.reset(new GrClipMaskManager(this, options.fClipBatchToBound
s)); | 50 fClipMaskManager.reset(new GrClipMaskManager(this, options.fClipBatchToBound
s)); |
50 | 51 |
51 fDrawBatchBounds = options.fDrawBatchBounds; | 52 fDrawBatchBounds = options.fDrawBatchBounds; |
52 fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookba
ck : | 53 fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookba
ck : |
53 options.fMaxBatchLookb
ack; | 54 options.fMaxBatchLookb
ack; |
| 55 fMaxBatchLookahead = (options.fMaxBatchLookahead < 0) ? kDefaultMaxBatchLook
ahead : |
| 56 options.fMaxBatchLook
ahead; |
54 | 57 |
55 rt->setLastDrawTarget(this); | 58 rt->setLastDrawTarget(this); |
56 | 59 |
57 #ifdef SK_DEBUG | 60 #ifdef SK_DEBUG |
58 static int debugID = 0; | 61 static int debugID = 0; |
59 fDebugID = debugID++; | 62 fDebugID = debugID++; |
60 #endif | 63 #endif |
61 } | 64 } |
62 | 65 |
63 GrDrawTarget::~GrDrawTarget() { | 66 GrDrawTarget::~GrDrawTarget() { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 SkDebugf("relies On (%d): ", fDependencies.count()); | 109 SkDebugf("relies On (%d): ", fDependencies.count()); |
107 for (int i = 0; i < fDependencies.count(); ++i) { | 110 for (int i = 0; i < fDependencies.count(); ++i) { |
108 SkDebugf("%d, ", fDependencies[i]->fDebugID); | 111 SkDebugf("%d, ", fDependencies[i]->fDebugID); |
109 } | 112 } |
110 SkDebugf("\n"); | 113 SkDebugf("\n"); |
111 SkDebugf("batches (%d):\n", fBatches.count()); | 114 SkDebugf("batches (%d):\n", fBatches.count()); |
112 for (int i = 0; i < fBatches.count(); ++i) { | 115 for (int i = 0; i < fBatches.count(); ++i) { |
113 #if 0 | 116 #if 0 |
114 SkDebugf("*******************************\n"); | 117 SkDebugf("*******************************\n"); |
115 #endif | 118 #endif |
116 SkDebugf("%d: %s\n", i, fBatches[i]->name()); | 119 if (fBatches[i]) { |
| 120 SkDebugf("%d: <combined forward>\n", i); |
| 121 } else { |
| 122 SkDebugf("%d: %s\n", i, fBatches[i]->name()); |
117 #if 0 | 123 #if 0 |
118 SkString str = fBatches[i]->dumpInfo(); | 124 SkString str = fBatches[i]->dumpInfo(); |
119 SkDebugf("%s\n", str.c_str()); | 125 SkDebugf("%s\n", str.c_str()); |
120 #endif | 126 #endif |
| 127 } |
121 } | 128 } |
122 } | 129 } |
123 #endif | 130 #endif |
124 | 131 |
125 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, | 132 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, |
126 const GrPipelineOptimizations& optimi
zations, | 133 const GrPipelineOptimizations& optimi
zations, |
127 GrXferProcessor::DstTexture* dstTextu
re, | 134 GrXferProcessor::DstTexture* dstTextu
re, |
128 const SkRect& batchBounds) { | 135 const SkRect& batchBounds) { |
129 SkRect bounds = batchBounds; | 136 SkRect bounds = batchBounds; |
130 bounds.outset(0.5f, 0.5f); | 137 bounds.outset(0.5f, 0.5f); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 193 |
187 void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) { | 194 void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) { |
188 // Semi-usually the drawTargets are already closed at this point, but someti
mes Ganesh | 195 // Semi-usually the drawTargets are already closed at this point, but someti
mes Ganesh |
189 // needs to flush mid-draw. In that case, the SkGpuDevice's drawTargets won'
t be closed | 196 // needs to flush mid-draw. In that case, the SkGpuDevice's drawTargets won'
t be closed |
190 // but need to be flushed anyway. Closing such drawTargets here will mean ne
w | 197 // but need to be flushed anyway. Closing such drawTargets here will mean ne
w |
191 // drawTargets will be created to replace them if the SkGpuDevice(s) write t
o them again. | 198 // drawTargets will be created to replace them if the SkGpuDevice(s) write t
o them again. |
192 this->makeClosed(); | 199 this->makeClosed(); |
193 | 200 |
194 // Loop over the batches that haven't yet generated their geometry | 201 // Loop over the batches that haven't yet generated their geometry |
195 for (int i = 0; i < fBatches.count(); ++i) { | 202 for (int i = 0; i < fBatches.count(); ++i) { |
196 fBatches[i]->prepare(flushState); | 203 if (fBatches[i]) { |
| 204 fBatches[i]->prepare(flushState); |
| 205 } |
197 } | 206 } |
198 } | 207 } |
199 | 208 |
200 void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) { | 209 void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) { |
201 // Draw all the generated geometry. | 210 // Draw all the generated geometry. |
202 SkRandom random; | 211 SkRandom random; |
203 for (int i = 0; i < fBatches.count(); ++i) { | 212 for (int i = 0; i < fBatches.count(); ++i) { |
| 213 if (!fBatches[i]) { |
| 214 continue; |
| 215 } |
204 if (fDrawBatchBounds) { | 216 if (fDrawBatchBounds) { |
205 const SkRect& bounds = fBatches[i]->bounds(); | 217 const SkRect& bounds = fBatches[i]->bounds(); |
206 SkIRect ibounds; | 218 SkIRect ibounds; |
207 bounds.roundOut(&ibounds); | 219 bounds.roundOut(&ibounds); |
208 // In multi-draw buffer all the batches use the same render target a
nd we won't need to | 220 // In multi-draw buffer all the batches use the same render target a
nd we won't need to |
209 // get the batchs bounds. | 221 // get the batchs bounds. |
210 if (GrRenderTarget* rt = fBatches[i]->renderTarget()) { | 222 if (GrRenderTarget* rt = fBatches[i]->renderTarget()) { |
211 fGpu->drawDebugWireRect(rt, ibounds, 0xFF000000 | random.nextU()
); | 223 fGpu->drawDebugWireRect(rt, ibounds, 0xFF000000 | random.nextU()
); |
212 } | 224 } |
213 } | 225 } |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 break; | 501 break; |
490 } | 502 } |
491 } | 503 } |
492 } else { | 504 } else { |
493 GrBATCH_INFO("\t\tFirstBatch\n"); | 505 GrBATCH_INFO("\t\tFirstBatch\n"); |
494 } | 506 } |
495 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch); | 507 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch); |
496 fBatches.push_back().reset(SkRef(batch)); | 508 fBatches.push_back().reset(SkRef(batch)); |
497 } | 509 } |
498 | 510 |
| 511 void GrDrawTarget::forwardCombine() { |
| 512 for (int i = 0; i < fBatches.count() - 2; ++i) { |
| 513 GrBatch* batch = fBatches[i]; |
| 514 int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fBatches.count() -
1); |
| 515 int j = i + 1; |
| 516 while (true) { |
| 517 GrBatch* candidate = fBatches[j]; |
| 518 // We cannot continue to search if the render target changes |
| 519 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID
()) { |
| 520 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", |
| 521 candidate->name(), candidate->uniqueID()); |
| 522 break; |
| 523 } |
| 524 if (j == i +1) { |
| 525 // We assume batch would have combined with candidate when the c
andidate was added |
| 526 // via backwards combining in recordBatch. |
| 527 SkASSERT(!batch->combineIfPossible(candidate, *this->caps())); |
| 528 } else if (batch->combineIfPossible(candidate, *this->caps())) { |
| 529 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, |
| 530 candidate->uniqueID()); |
| 531 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate); |
| 532 fBatches[j].reset(SkRef(batch)); |
| 533 fBatches[i].reset(nullptr); |
| 534 break; |
| 535 } |
| 536 // Stop going traversing if we would cause a painter's order violati
on. |
| 537 // TODO: The bounds used here do not fully consider the clip. It may
be advantageous |
| 538 // to clip each batch's bounds to the clip. |
| 539 if (intersect(candidate->bounds(), batch->bounds())) { |
| 540 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), |
| 541 candidate->uniqueID()); |
| 542 break; |
| 543 } |
| 544 ++j; |
| 545 if (j > maxCandidateIdx) { |
| 546 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d
\n", i); |
| 547 break; |
| 548 } |
| 549 } |
| 550 } |
| 551 } |
| 552 |
499 /////////////////////////////////////////////////////////////////////////////// | 553 /////////////////////////////////////////////////////////////////////////////// |
500 | 554 |
501 bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineB
uilder, | 555 bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineB
uilder, |
502 const GrScissorState* scissor, | 556 const GrScissorState* scissor, |
503 GrDrawBatch* batch) { | 557 GrDrawBatch* batch) { |
504 GrPipeline::CreateArgs args; | 558 GrPipeline::CreateArgs args; |
505 args.fPipelineBuilder = pipelineBuilder; | 559 args.fPipelineBuilder = pipelineBuilder; |
506 args.fCaps = this->caps(); | 560 args.fCaps = this->caps(); |
507 args.fScissor = scissor; | 561 args.fScissor = scissor; |
508 batch->getPipelineOptimizations(&args.fOpts); | 562 batch->getPipelineOptimizations(&args.fOpts); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } | 600 } |
547 | 601 |
548 return true; | 602 return true; |
549 } | 603 } |
550 | 604 |
551 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 605 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
552 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 606 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
553 this->recordBatch(batch); | 607 this->recordBatch(batch); |
554 batch->unref(); | 608 batch->unref(); |
555 } | 609 } |
OLD | NEW |