OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrDrawTarget.h" | 8 #include "GrDrawTarget.h" |
9 | 9 |
10 #include "GrAuditTrail.h" | 10 #include "GrAuditTrail.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "instanced/InstancedRendering.h" | 38 #include "instanced/InstancedRendering.h" |
39 | 39 |
40 //////////////////////////////////////////////////////////////////////////////// | 40 //////////////////////////////////////////////////////////////////////////////// |
41 | 41 |
42 // Experimentally we have found that most batching occurs within the first 10 co
mparisons. | 42 // Experimentally we have found that most batching occurs within the first 10 co
mparisons. |
43 static const int kDefaultMaxBatchLookback = 10; | 43 static const int kDefaultMaxBatchLookback = 10; |
44 static const int kDefaultMaxBatchLookahead = 10; | 44 static const int kDefaultMaxBatchLookahead = 10; |
45 | 45 |
46 GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* r
esourceProvider, | 46 GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* r
esourceProvider, |
47 GrAuditTrail* auditTrail, const Options& options) | 47 GrAuditTrail* auditTrail, const Options& options) |
48 : fGpu(SkRef(gpu)) | 48 : fLastFullClearBatch(nullptr) |
| 49 , fGpu(SkRef(gpu)) |
49 , fResourceProvider(resourceProvider) | 50 , fResourceProvider(resourceProvider) |
50 , fAuditTrail(auditTrail) | 51 , fAuditTrail(auditTrail) |
51 , fFlags(0) | 52 , fFlags(0) |
52 , fRenderTarget(rt) { | 53 , fRenderTarget(rt) { |
53 // TODO: Stop extracting the context (currently needed by GrClip) | 54 // TODO: Stop extracting the context (currently needed by GrClip) |
54 fContext = fGpu->getContext(); | 55 fContext = fGpu->getContext(); |
55 | 56 |
56 fClipBatchToBounds = options.fClipBatchToBounds; | 57 fClipBatchToBounds = options.fClipBatchToBounds; |
57 fDrawBatchBounds = options.fDrawBatchBounds; | 58 fDrawBatchBounds = options.fDrawBatchBounds; |
58 fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookba
ck : | 59 fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookba
ck : |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 bounds.roundOut(&iBounds); | 281 bounds.roundOut(&iBounds); |
281 commandBuffer->submit(iBounds); | 282 commandBuffer->submit(iBounds); |
282 } | 283 } |
283 flushState->setCommandBuffer(nullptr); | 284 flushState->setCommandBuffer(nullptr); |
284 } | 285 } |
285 | 286 |
286 fGpu->finishDrawTarget(); | 287 fGpu->finishDrawTarget(); |
287 } | 288 } |
288 | 289 |
289 void GrDrawTarget::reset() { | 290 void GrDrawTarget::reset() { |
| 291 fLastFullClearBatch = nullptr; |
290 fRecordedBatches.reset(); | 292 fRecordedBatches.reset(); |
291 if (fInstancedRendering) { | 293 if (fInstancedRendering) { |
292 fInstancedRendering->endFlush(); | 294 fInstancedRendering->endFlush(); |
293 } | 295 } |
294 } | 296 } |
295 | 297 |
296 static void batch_bounds(SkRect* bounds, const GrBatch* batch) { | 298 static void batch_bounds(SkRect* bounds, const GrBatch* batch) { |
297 *bounds = batch->bounds(); | 299 *bounds = batch->bounds(); |
298 if (batch->hasZeroArea()) { | 300 if (batch->hasZeroArea()) { |
299 if (batch->hasAABloat()) { | 301 if (batch->hasAABloat()) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 path); | 453 path); |
452 this->recordBatch(batch, appliedClip.deviceBounds()); | 454 this->recordBatch(batch, appliedClip.deviceBounds()); |
453 batch->unref(); | 455 batch->unref(); |
454 } | 456 } |
455 | 457 |
456 void GrDrawTarget::addBatch(sk_sp<GrBatch> batch) { | 458 void GrDrawTarget::addBatch(sk_sp<GrBatch> batch) { |
457 this->recordBatch(batch.get(), batch->bounds()); | 459 this->recordBatch(batch.get(), batch->bounds()); |
458 } | 460 } |
459 | 461 |
460 void GrDrawTarget::fullClear(GrRenderTarget* renderTarget, GrColor color) { | 462 void GrDrawTarget::fullClear(GrRenderTarget* renderTarget, GrColor color) { |
461 // Currently this just inserts a clear batch. However, once in MDB this can
remove all the | 463 // Currently this just inserts or updates the last clear batch. However, onc
e in MDB this can |
462 // previously recorded batches and change the load op to clear with supplied
color. | 464 // remove all the previously recorded batches and change the load op to clea
r with supplied |
463 sk_sp<GrBatch> batch = GrClearBatch::Make(SkIRect::MakeWH(renderTarget->widt
h(), | 465 // color. |
464 renderTarget->heig
ht()), | 466 if (fLastFullClearBatch && |
465 color, renderTarget); | 467 fLastFullClearBatch->renderTargetUniqueID() == renderTarget->getUniqueID
()) { |
466 this->recordBatch(batch.get(), batch->bounds()); | 468 // As currently implemented, fLastFullClearBatch should be the last batc
h because we would |
| 469 // have cleared it when another batch was recorded. |
| 470 SkASSERT(fRecordedBatches.back().fBatch.get() == fLastFullClearBatch); |
| 471 fLastFullClearBatch->setColor(color); |
| 472 return; |
| 473 } |
| 474 sk_sp<GrClearBatch> batch(GrClearBatch::Make(SkIRect::MakeWH(renderTarget->w
idth(), |
| 475 renderTarget->h
eight()), |
| 476 color, renderTarget)); |
| 477 if (batch.get() == this->recordBatch(batch.get(), batch->bounds())) { |
| 478 fLastFullClearBatch = batch.get(); |
| 479 } |
467 } | 480 } |
468 | 481 |
469 void GrDrawTarget::discard(GrRenderTarget* renderTarget) { | 482 void GrDrawTarget::discard(GrRenderTarget* renderTarget) { |
470 // Currently this just inserts a discard batch. However, once in MDB this ca
n remove all the | 483 // Currently this just inserts a discard batch. However, once in MDB this ca
n remove all the |
471 // previously recorded batches and change the load op to discard. | 484 // previously recorded batches and change the load op to discard. |
472 if (this->caps()->discardRenderTargetSupport()) { | 485 if (this->caps()->discardRenderTargetSupport()) { |
473 GrBatch* batch = new GrDiscardBatch(renderTarget); | 486 GrBatch* batch = new GrDiscardBatch(renderTarget); |
474 this->recordBatch(batch, batch->bounds()); | 487 this->recordBatch(batch, batch->bounds()); |
475 batch->unref(); | 488 batch->unref(); |
476 } | 489 } |
(...skipping 25 matching lines...) Expand all Loading... |
502 | 515 |
503 static void join(SkRect* out, const SkRect& a, const SkRect& b) { | 516 static void join(SkRect* out, const SkRect& a, const SkRect& b) { |
504 SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom); | 517 SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom); |
505 SkASSERT(b.fLeft <= b.fRight && b.fTop <= b.fBottom); | 518 SkASSERT(b.fLeft <= b.fRight && b.fTop <= b.fBottom); |
506 out->fLeft = SkTMin(a.fLeft, b.fLeft); | 519 out->fLeft = SkTMin(a.fLeft, b.fLeft); |
507 out->fTop = SkTMin(a.fTop, b.fTop); | 520 out->fTop = SkTMin(a.fTop, b.fTop); |
508 out->fRight = SkTMax(a.fRight, b.fRight); | 521 out->fRight = SkTMax(a.fRight, b.fRight); |
509 out->fBottom = SkTMax(a.fBottom, b.fBottom); | 522 out->fBottom = SkTMax(a.fBottom, b.fBottom); |
510 } | 523 } |
511 | 524 |
512 void GrDrawTarget::recordBatch(GrBatch* batch, const SkRect& clippedBounds) { | 525 GrBatch* GrDrawTarget::recordBatch(GrBatch* batch, const SkRect& clippedBounds)
{ |
513 // A closed drawTarget should never receive new/more batches | 526 // A closed drawTarget should never receive new/more batches |
514 SkASSERT(!this->isClosed()); | 527 SkASSERT(!this->isClosed()); |
515 | 528 |
516 // Check if there is a Batch Draw we can batch with by linearly searching ba
ck until we either | 529 // Check if there is a Batch Draw we can batch with by linearly searching ba
ck until we either |
517 // 1) check every draw | 530 // 1) check every draw |
518 // 2) intersect with something | 531 // 2) intersect with something |
519 // 3) find a 'blocker' | 532 // 3) find a 'blocker' |
520 GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch); | 533 GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch); |
521 GrBATCH_INFO("Re-Recording (%s, B%u)\n" | 534 GrBATCH_INFO("Re-Recording (%s, B%u)\n" |
522 "\tBounds LRTB (%f, %f, %f, %f)\n", | 535 "\tBounds LRTB (%f, %f, %f, %f)\n", |
(...skipping 16 matching lines...) Expand all Loading... |
539 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", | 552 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", |
540 candidate->name(), candidate->uniqueID()); | 553 candidate->name(), candidate->uniqueID()); |
541 break; | 554 break; |
542 } | 555 } |
543 if (candidate->combineIfPossible(batch, *this->caps())) { | 556 if (candidate->combineIfPossible(batch, *this->caps())) { |
544 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, | 557 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, |
545 candidate->uniqueID()); | 558 candidate->uniqueID()); |
546 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate,
batch); | 559 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate,
batch); |
547 join(&fRecordedBatches.fromBack(i).fClippedBounds, | 560 join(&fRecordedBatches.fromBack(i).fClippedBounds, |
548 fRecordedBatches.fromBack(i).fClippedBounds, clippedBounds)
; | 561 fRecordedBatches.fromBack(i).fClippedBounds, clippedBounds)
; |
549 return; | 562 return candidate; |
550 } | 563 } |
551 // Stop going backwards if we would cause a painter's order violatio
n. | 564 // Stop going backwards if we would cause a painter's order violatio
n. |
552 const SkRect& candidateBounds = fRecordedBatches.fromBack(i).fClippe
dBounds; | 565 const SkRect& candidateBounds = fRecordedBatches.fromBack(i).fClippe
dBounds; |
553 if (!can_reorder(candidateBounds, clippedBounds)) { | 566 if (!can_reorder(candidateBounds, clippedBounds)) { |
554 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), | 567 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), |
555 candidate->uniqueID()); | 568 candidate->uniqueID()); |
556 break; | 569 break; |
557 } | 570 } |
558 ++i; | 571 ++i; |
559 if (i == maxCandidates) { | 572 if (i == maxCandidates) { |
560 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr
ay %d\n", i); | 573 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr
ay %d\n", i); |
561 break; | 574 break; |
562 } | 575 } |
563 } | 576 } |
564 } else { | 577 } else { |
565 GrBATCH_INFO("\t\tFirstBatch\n"); | 578 GrBATCH_INFO("\t\tFirstBatch\n"); |
566 } | 579 } |
567 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch); | 580 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch); |
568 fRecordedBatches.emplace_back(RecordedBatch{sk_ref_sp(batch), clippedBounds}
); | 581 fRecordedBatches.emplace_back(RecordedBatch{sk_ref_sp(batch), clippedBounds}
); |
| 582 fLastFullClearBatch = nullptr; |
| 583 return batch; |
569 } | 584 } |
570 | 585 |
571 void GrDrawTarget::forwardCombine() { | 586 void GrDrawTarget::forwardCombine() { |
572 for (int i = 0; i < fRecordedBatches.count() - 2; ++i) { | 587 for (int i = 0; i < fRecordedBatches.count() - 2; ++i) { |
573 GrBatch* batch = fRecordedBatches[i].fBatch.get(); | 588 GrBatch* batch = fRecordedBatches[i].fBatch.get(); |
574 const SkRect& batchBounds = fRecordedBatches[i].fClippedBounds; | 589 const SkRect& batchBounds = fRecordedBatches[i].fClippedBounds; |
575 int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fRecordedBatches.co
unt() - 1); | 590 int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fRecordedBatches.co
unt() - 1); |
576 int j = i + 1; | 591 int j = i + 1; |
577 while (true) { | 592 while (true) { |
578 GrBatch* candidate = fRecordedBatches[j].fBatch.get(); | 593 GrBatch* candidate = fRecordedBatches[j].fBatch.get(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 } | 626 } |
612 } | 627 } |
613 | 628 |
614 /////////////////////////////////////////////////////////////////////////////// | 629 /////////////////////////////////////////////////////////////////////////////// |
615 | 630 |
616 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 631 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
617 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 632 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
618 this->recordBatch(batch, batch->bounds()); | 633 this->recordBatch(batch, batch->bounds()); |
619 batch->unref(); | 634 batch->unref(); |
620 } | 635 } |
OLD | NEW |