| 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 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 fGpu->finishDrawTarget(); | 274 fGpu->finishDrawTarget(); |
| 275 } | 275 } |
| 276 | 276 |
| 277 void GrDrawTarget::reset() { | 277 void GrDrawTarget::reset() { |
| 278 fBatches.reset(); | 278 fBatches.reset(); |
| 279 if (fInstancedRendering) { | 279 if (fInstancedRendering) { |
| 280 fInstancedRendering->endFlush(); | 280 fInstancedRendering->endFlush(); |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 | 283 |
| 284 static void batch_bounds(SkRect* bounds, const GrBatch* batch) { |
| 285 *bounds = batch->bounds(); |
| 286 if (batch->hasZeroArea()) { |
| 287 if (batch->hasAABloat()) { |
| 288 bounds->outset(0.5f, 0.5f); |
| 289 } else { |
| 290 // We don't know which way the particular GPU will snap lines or poi
nts at integer |
| 291 // coords. So we ensure that the bounds is large enough for either s
nap. |
| 292 SkRect before = *bounds; |
| 293 bounds->roundOut(bounds); |
| 294 if (bounds->fLeft == before.fLeft) { |
| 295 bounds->fLeft -= 1; |
| 296 } |
| 297 if (bounds->fTop == before.fTop) { |
| 298 bounds->fTop -= 1; |
| 299 } |
| 300 if (bounds->fRight == before.fRight) { |
| 301 bounds->fRight += 1; |
| 302 } |
| 303 if (bounds->fBottom == before.fBottom) { |
| 304 bounds->fBottom += 1; |
| 305 } |
| 306 } |
| 307 } |
| 308 } |
| 309 |
| 284 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, | 310 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, |
| 285 GrDrawContext* drawContext, | 311 GrDrawContext* drawContext, |
| 286 const GrClip& clip, | 312 const GrClip& clip, |
| 287 GrDrawBatch* batch) { | 313 GrDrawBatch* batch) { |
| 288 // Setup clip | 314 // Setup clip |
| 289 GrAppliedClip appliedClip; | 315 GrAppliedClip appliedClip; |
| 290 if (!clip.apply(fContext, pipelineBuilder, drawContext, &batch->bounds(), &a
ppliedClip)) { | 316 SkRect bounds; |
| 317 batch_bounds(&bounds, batch); |
| 318 if (!clip.apply(fContext, pipelineBuilder, drawContext, &bounds, &appliedCli
p)) { |
| 291 return; | 319 return; |
| 292 } | 320 } |
| 293 | 321 |
| 294 // TODO: this is the only remaining usage of the AutoRestoreFragmentProcesso
rState - remove it | 322 // TODO: this is the only remaining usage of the AutoRestoreFragmentProcesso
rState - remove it |
| 295 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 323 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
| 296 if (appliedClip.getClipCoverageFragmentProcessor()) { | 324 if (appliedClip.getClipCoverageFragmentProcessor()) { |
| 297 arfps.set(&pipelineBuilder); | 325 arfps.set(&pipelineBuilder); |
| 298 arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverage
FragmentProcessor())); | 326 arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverage
FragmentProcessor())); |
| 299 } | 327 } |
| 300 | 328 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 490 } |
| 463 #ifdef ENABLE_MDB | 491 #ifdef ENABLE_MDB |
| 464 this->addDependency(src); | 492 this->addDependency(src); |
| 465 #endif | 493 #endif |
| 466 | 494 |
| 467 this->recordBatch(batch); | 495 this->recordBatch(batch); |
| 468 batch->unref(); | 496 batch->unref(); |
| 469 return true; | 497 return true; |
| 470 } | 498 } |
| 471 | 499 |
| 472 template <class Left, class Right> static bool intersect(const Left& a, const Ri
ght& b) { | 500 static inline bool exclusive_no_intersection(const SkRect& a, const SkRect& b) { |
| 473 SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom && | 501 return a.fRight <= b.fLeft || a.fBottom <= b.fTop || |
| 474 b.fLeft <= b.fRight && b.fTop <= b.fBottom); | 502 b.fRight <= a.fLeft || b.fBottom <= a.fTop; |
| 475 return a.fLeft < b.fRight && b.fLeft < a.fRight && a.fTop < b.fBottom && b.f
Top < a.fBottom; | 503 } |
| 504 |
| 505 static inline bool can_reorder(const GrBatch* a, const GrBatch* b) { |
| 506 SkRect ra; |
| 507 SkRect rb; |
| 508 batch_bounds(&ra, a); |
| 509 batch_bounds(&rb, a); |
| 510 return exclusive_no_intersection(ra, rb); |
| 476 } | 511 } |
| 477 | 512 |
| 478 void GrDrawTarget::recordBatch(GrBatch* batch) { | 513 void GrDrawTarget::recordBatch(GrBatch* batch) { |
| 479 // A closed drawTarget should never receive new/more batches | 514 // A closed drawTarget should never receive new/more batches |
| 480 SkASSERT(!this->isClosed()); | 515 SkASSERT(!this->isClosed()); |
| 481 | 516 |
| 482 // Check if there is a Batch Draw we can batch with by linearly searching ba
ck until we either | 517 // Check if there is a Batch Draw we can batch with by linearly searching ba
ck until we either |
| 483 // 1) check every draw | 518 // 1) check every draw |
| 484 // 2) intersect with something | 519 // 2) intersect with something |
| 485 // 3) find a 'blocker' | 520 // 3) find a 'blocker' |
| (...skipping 19 matching lines...) Expand all Loading... |
| 505 } | 540 } |
| 506 if (candidate->combineIfPossible(batch, *this->caps())) { | 541 if (candidate->combineIfPossible(batch, *this->caps())) { |
| 507 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, | 542 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, |
| 508 candidate->uniqueID()); | 543 candidate->uniqueID()); |
| 509 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate,
batch); | 544 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate,
batch); |
| 510 return; | 545 return; |
| 511 } | 546 } |
| 512 // Stop going backwards if we would cause a painter's order violatio
n. | 547 // Stop going backwards if we would cause a painter's order violatio
n. |
| 513 // TODO: The bounds used here do not fully consider the clip. It may
be advantageous | 548 // TODO: The bounds used here do not fully consider the clip. It may
be advantageous |
| 514 // to clip each batch's bounds to the clip. | 549 // to clip each batch's bounds to the clip. |
| 515 if (intersect(candidate->bounds(), batch->bounds())) { | 550 if (!can_reorder(candidate, batch)) { |
| 516 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), | 551 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), |
| 517 candidate->uniqueID()); | 552 candidate->uniqueID()); |
| 518 break; | 553 break; |
| 519 } | 554 } |
| 520 ++i; | 555 ++i; |
| 521 if (i == maxCandidates) { | 556 if (i == maxCandidates) { |
| 522 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr
ay %d\n", i); | 557 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr
ay %d\n", i); |
| 523 break; | 558 break; |
| 524 } | 559 } |
| 525 } | 560 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 551 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, | 586 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name()
, |
| 552 candidate->uniqueID()); | 587 candidate->uniqueID()); |
| 553 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, batch, cand
idate); | 588 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, batch, cand
idate); |
| 554 fBatches[j].reset(SkRef(batch)); | 589 fBatches[j].reset(SkRef(batch)); |
| 555 fBatches[i].reset(nullptr); | 590 fBatches[i].reset(nullptr); |
| 556 break; | 591 break; |
| 557 } | 592 } |
| 558 // Stop going traversing if we would cause a painter's order violati
on. | 593 // Stop going traversing if we would cause a painter's order violati
on. |
| 559 // TODO: The bounds used here do not fully consider the clip. It may
be advantageous | 594 // TODO: The bounds used here do not fully consider the clip. It may
be advantageous |
| 560 // to clip each batch's bounds to the clip. | 595 // to clip each batch's bounds to the clip. |
| 561 if (intersect(candidate->bounds(), batch->bounds())) { | 596 if (!can_reorder(candidate, batch)) { |
| 562 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), | 597 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(
), |
| 563 candidate->uniqueID()); | 598 candidate->uniqueID()); |
| 564 break; | 599 break; |
| 565 } | 600 } |
| 566 ++j; | 601 ++j; |
| 567 if (j > maxCandidateIdx) { | 602 if (j > maxCandidateIdx) { |
| 568 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d
\n", i); | 603 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d
\n", i); |
| 569 break; | 604 break; |
| 570 } | 605 } |
| 571 } | 606 } |
| 572 } | 607 } |
| 573 } | 608 } |
| 574 | 609 |
| 575 /////////////////////////////////////////////////////////////////////////////// | 610 /////////////////////////////////////////////////////////////////////////////// |
| 576 | 611 |
| 577 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 612 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
| 578 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 613 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
| 579 this->recordBatch(batch); | 614 this->recordBatch(batch); |
| 580 batch->unref(); | 615 batch->unref(); |
| 581 } | 616 } |
| OLD | NEW |