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