Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: src/core/SkClipStack.cpp

Issue 54543008: Revert "Avoid re-rendering stencil clip for every draw with reducable clip stack" (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/core/SkClipStack.h ('k') | src/gpu/GrClipMaskCache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkClipStack.h" 8 #include "SkClipStack.h"
9 #include "SkPath.h" 9 #include "SkPath.h"
10 #include "SkThread.h" 10 #include "SkThread.h"
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 fSaveCount -= 1; 445 fSaveCount -= 1;
446 restoreTo(fSaveCount); 446 restoreTo(fSaveCount);
447 } 447 }
448 448
449 void SkClipStack::restoreTo(int saveCount) { 449 void SkClipStack::restoreTo(int saveCount) {
450 while (!fDeque.empty()) { 450 while (!fDeque.empty()) {
451 Element* element = (Element*)fDeque.back(); 451 Element* element = (Element*)fDeque.back();
452 if (element->fSaveCount <= saveCount) { 452 if (element->fSaveCount <= saveCount) {
453 break; 453 break;
454 } 454 }
455 this->purgeClip(element);
455 element->~Element(); 456 element->~Element();
456 fDeque.pop_back(); 457 fDeque.pop_back();
457 } 458 }
458 } 459 }
459 460
460 void SkClipStack::getBounds(SkRect* canvFiniteBound, 461 void SkClipStack::getBounds(SkRect* canvFiniteBound,
461 BoundsType* boundType, 462 BoundsType* boundType,
462 bool* isIntersectionOfRects) const { 463 bool* isIntersectionOfRects) const {
463 SkASSERT(NULL != canvFiniteBound && NULL != boundType); 464 SkASSERT(NULL != canvFiniteBound && NULL != boundType);
464 465
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 Element* element = (Element*) iter.prev(); 533 Element* element = (Element*) iter.prev();
533 534
534 if (NULL != element) { 535 if (NULL != element) {
535 if (element->canBeIntersectedInPlace(fSaveCount, op)) { 536 if (element->canBeIntersectedInPlace(fSaveCount, op)) {
536 switch (element->fType) { 537 switch (element->fType) {
537 case Element::kEmpty_Type: 538 case Element::kEmpty_Type:
538 element->checkEmpty(); 539 element->checkEmpty();
539 return; 540 return;
540 case Element::kRect_Type: 541 case Element::kRect_Type:
541 if (element->rectRectIntersectAllowed(rect, doAA)) { 542 if (element->rectRectIntersectAllowed(rect, doAA)) {
543 this->purgeClip(element);
542 if (!element->fRect.intersect(rect)) { 544 if (!element->fRect.intersect(rect)) {
543 element->setEmpty(); 545 element->setEmpty();
544 return; 546 return;
545 } 547 }
546 548
547 element->fDoAA = doAA; 549 element->fDoAA = doAA;
548 Element* prev = (Element*) iter.prev(); 550 Element* prev = (Element*) iter.prev();
549 element->updateBoundAndGenID(prev); 551 element->updateBoundAndGenID(prev);
550 return; 552 return;
551 } 553 }
552 break; 554 break;
553 case Element::kPath_Type: 555 case Element::kPath_Type:
554 if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { 556 if (!SkRect::Intersects(element->fPath.getBounds(), rect)) {
557 this->purgeClip(element);
555 element->setEmpty(); 558 element->setEmpty();
556 return; 559 return;
557 } 560 }
558 break; 561 break;
559 } 562 }
560 } else if (SkRegion::kReplace_Op == op) { 563 } else if (SkRegion::kReplace_Op == op) {
561 this->restoreTo(fSaveCount - 1); 564 this->restoreTo(fSaveCount - 1);
562 element = (Element*) fDeque.back(); 565 element = (Element*) fDeque.back();
563 } 566 }
564 } 567 }
565 new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); 568 new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA);
566 ((Element*) fDeque.back())->updateBoundAndGenID(element); 569 ((Element*) fDeque.back())->updateBoundAndGenID(element);
570
571 if (element && element->fSaveCount == fSaveCount) {
572 this->purgeClip(element);
573 }
567 } 574 }
568 575
569 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { 576 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
570 SkRect alt; 577 SkRect alt;
571 if (path.isRect(&alt) && !path.isInverseFillType()) { 578 if (path.isRect(&alt) && !path.isInverseFillType()) {
572 return this->clipDevRect(alt, op, doAA); 579 return this->clipDevRect(alt, op, doAA);
573 } 580 }
574 581
575 Element* element = (Element*)fDeque.back(); 582 Element* element = (Element*)fDeque.back();
576 if (NULL != element) { 583 if (NULL != element) {
577 if (element->canBeIntersectedInPlace(fSaveCount, op)) { 584 if (element->canBeIntersectedInPlace(fSaveCount, op)) {
578 const SkRect& pathBounds = path.getBounds(); 585 const SkRect& pathBounds = path.getBounds();
579 switch (element->fType) { 586 switch (element->fType) {
580 case Element::kEmpty_Type: 587 case Element::kEmpty_Type:
581 element->checkEmpty(); 588 element->checkEmpty();
582 return; 589 return;
583 case Element::kRect_Type: 590 case Element::kRect_Type:
584 if (!SkRect::Intersects(element->fRect, pathBounds)) { 591 if (!SkRect::Intersects(element->fRect, pathBounds)) {
592 this->purgeClip(element);
585 element->setEmpty(); 593 element->setEmpty();
586 return; 594 return;
587 } 595 }
588 break; 596 break;
589 case Element::kPath_Type: 597 case Element::kPath_Type:
590 if (!SkRect::Intersects(element->fPath.getBounds(), pathBoun ds)) { 598 if (!SkRect::Intersects(element->fPath.getBounds(), pathBoun ds)) {
599 this->purgeClip(element);
591 element->setEmpty(); 600 element->setEmpty();
592 return; 601 return;
593 } 602 }
594 break; 603 break;
595 } 604 }
596 } else if (SkRegion::kReplace_Op == op) { 605 } else if (SkRegion::kReplace_Op == op) {
597 this->restoreTo(fSaveCount - 1); 606 this->restoreTo(fSaveCount - 1);
598 element = (Element*) fDeque.back(); 607 element = (Element*) fDeque.back();
599 } 608 }
600 } 609 }
601 new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); 610 new (fDeque.push_back()) Element(fSaveCount, path, op, doAA);
602 ((Element*) fDeque.back())->updateBoundAndGenID(element); 611 ((Element*) fDeque.back())->updateBoundAndGenID(element);
612
613 if (element && element->fSaveCount == fSaveCount) {
614 this->purgeClip(element);
615 }
603 } 616 }
604 617
605 void SkClipStack::clipEmpty() { 618 void SkClipStack::clipEmpty() {
606 619
607 Element* element = (Element*) fDeque.back(); 620 Element* element = (Element*) fDeque.back();
608 621
609 if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kInter sect_Op)) { 622 if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kInter sect_Op)) {
610 switch (element->fType) { 623 switch (element->fType) {
611 case Element::kEmpty_Type: 624 case Element::kEmpty_Type:
612 element->checkEmpty(); 625 element->checkEmpty();
613 return; 626 return;
614 case Element::kRect_Type: 627 case Element::kRect_Type:
615 case Element::kPath_Type: 628 case Element::kPath_Type:
629 this->purgeClip(element);
616 element->setEmpty(); 630 element->setEmpty();
617 return; 631 return;
618 } 632 }
619 } 633 }
620 new (fDeque.push_back()) Element(fSaveCount); 634 new (fDeque.push_back()) Element(fSaveCount);
621 635
636 if (element && element->fSaveCount == fSaveCount) {
637 this->purgeClip(element);
638 }
622 ((Element*)fDeque.back())->fGenID = kEmptyGenID; 639 ((Element*)fDeque.back())->fGenID = kEmptyGenID;
623 } 640 }
624 641
625 bool SkClipStack::isWideOpen() const { 642 bool SkClipStack::isWideOpen() const {
626 return this->getTopmostGenID() == kWideOpenGenID; 643 if (0 == fDeque.count()) {
644 return true;
645 }
646
647 const Element* back = (const Element*) fDeque.back();
648 return kWideOpenGenID == back->fGenID ||
649 (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBoun d.isEmpty());
627 } 650 }
628 651
629 /////////////////////////////////////////////////////////////////////////////// 652 ///////////////////////////////////////////////////////////////////////////////
630 653
631 SkClipStack::Iter::Iter() : fStack(NULL) { 654 SkClipStack::Iter::Iter() : fStack(NULL) {
632 } 655 }
633 656
634 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) 657 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc)
635 : fStack(&stack) { 658 : fStack(&stack) {
636 this->reset(stack, startLoc); 659 this->reset(stack, startLoc);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 } 733 }
711 734
712 // but is converted to device space here 735 // but is converted to device space here
713 temp.offset(SkIntToScalar(offsetX), SkIntToScalar(offsetY)); 736 temp.offset(SkIntToScalar(offsetX), SkIntToScalar(offsetY));
714 737
715 if (!devBounds->intersect(temp)) { 738 if (!devBounds->intersect(temp)) {
716 devBounds->setEmpty(); 739 devBounds->setEmpty();
717 } 740 }
718 } 741 }
719 742
743 void SkClipStack::addPurgeClipCallback(PFPurgeClipCB callback, void* data) const {
744 ClipCallbackData temp = { callback, data };
745 fCallbackData.append(1, &temp);
746 }
747
748 void SkClipStack::removePurgeClipCallback(PFPurgeClipCB callback, void* data) co nst {
749 ClipCallbackData temp = { callback, data };
750 int index = fCallbackData.find(temp);
751 if (index >= 0) {
752 fCallbackData.removeShuffle(index);
753 }
754 }
755
756 // The clip state represented by 'element' will never be used again. Purge it.
757 void SkClipStack::purgeClip(Element* element) {
758 SkASSERT(NULL != element);
759 if (element->fGenID >= 0 && element->fGenID < kFirstUnreservedGenID) {
760 return;
761 }
762
763 for (int i = 0; i < fCallbackData.count(); ++i) {
764 (*fCallbackData[i].fCallback)(element->fGenID, fCallbackData[i].fData);
765 }
766
767 // Invalidate element's gen ID so handlers can detect already handled record s
768 element->fGenID = kInvalidGenID;
769 }
770
720 int32_t SkClipStack::GetNextGenID() { 771 int32_t SkClipStack::GetNextGenID() {
721 // TODO: handle overflow. 772 // TODO: handle overflow.
722 return sk_atomic_inc(&gGenID); 773 return sk_atomic_inc(&gGenID);
723 } 774 }
724 775
725 int32_t SkClipStack::getTopmostGenID() const { 776 int32_t SkClipStack::getTopmostGenID() const {
777
726 if (fDeque.empty()) { 778 if (fDeque.empty()) {
727 return kWideOpenGenID; 779 return kInvalidGenID;
728 } 780 }
729 781
730 const Element* back = static_cast<const Element*>(fDeque.back()); 782 Element* element = (Element*)fDeque.back();
731 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is Empty()) { 783 return element->fGenID;
732 return kWideOpenGenID;
733 }
734
735 return back->getGenID();
736 } 784 }
OLDNEW
« no previous file with comments | « include/core/SkClipStack.h ('k') | src/gpu/GrClipMaskCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698