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 |