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 |