Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Attributes | Friends | List of all members
SkClipStack Class Reference

#include <SkClipStack.h>

Classes

class  AutoRestore
 
class  B2TIter
 
class  Element
 
class  Iter
 

Public Types

enum  BoundsType { kNormal_BoundsType , kInsideOut_BoundsType }
 

Public Member Functions

 SkClipStack ()
 
 SkClipStack (void *storage, size_t size)
 
 SkClipStack (const SkClipStack &b)
 
 ~SkClipStack ()
 
SkClipStackoperator= (const SkClipStack &b)
 
bool operator== (const SkClipStack &b) const
 
bool operator!= (const SkClipStack &b) const
 
void reset ()
 
int getSaveCount () const
 
void save ()
 
void restore ()
 
void getBounds (SkRect *canvFiniteBound, BoundsType *boundType, bool *isIntersectionOfRects=nullptr) const
 
SkRect bounds (const SkIRect &deviceBounds) const
 
bool isEmpty (const SkIRect &deviceBounds) const
 
bool quickContains (const SkRect &devRect) const
 
bool quickContains (const SkRRect &devRRect) const
 
void clipDevRect (const SkIRect &ir, SkClipOp op)
 
void clipRect (const SkRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
 
void clipRRect (const SkRRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
 
void clipPath (const SkPath &, const SkMatrix &matrix, SkClipOp, bool doAA)
 
void clipShader (sk_sp< SkShader >)
 
void clipEmpty ()
 
void replaceClip (const SkRect &devRect, bool doAA)
 
bool isWideOpen () const
 
bool isRRect (const SkRect &bounds, SkRRect *rrect, bool *aa) const
 
uint32_t getTopmostGenID () const
 
void getConservativeBounds (int offsetX, int offsetY, int maxWidth, int maxHeight, SkRect *devBounds, bool *isIntersectionOfRects=nullptr) const
 

Static Public Attributes

static const uint32_t kInvalidGenID = 0
 
static const uint32_t kEmptyGenID = 1
 
static const uint32_t kWideOpenGenID = 2
 

Friends

class Iter
 

Detailed Description

Definition at line 32 of file SkClipStack.h.

Member Enumeration Documentation

◆ BoundsType

Enumerator
kNormal_BoundsType 
kInsideOut_BoundsType 

Definition at line 34 of file SkClipStack.h.

34 {
35 // The bounding box contains all the pixels that can be written to
37 // The bounding box contains all the pixels that cannot be written to.
38 // The real bound extends out to infinity and all the pixels outside
39 // of the bound can be written to. Note that some of the pixels inside
40 // the bound may also be writeable but all pixels that cannot be
41 // written to are guaranteed to be inside.
43 };
@ kInsideOut_BoundsType
Definition SkClipStack.h:42

Constructor & Destructor Documentation

◆ SkClipStack() [1/3]

SkClipStack::SkClipStack ( )

Definition at line 510 of file SkClipStack.cpp.

511 : fDeque(sizeof(Element), kDefaultElementAllocCnt)
512 , fSaveCount(0) {
513}
static const int kDefaultElementAllocCnt

◆ SkClipStack() [2/3]

SkClipStack::SkClipStack ( void *  storage,
size_t  size 
)

Definition at line 515 of file SkClipStack.cpp.

516 : fDeque(sizeof(Element), storage, size, kDefaultElementAllocCnt)
517 , fSaveCount(0) {
518}

◆ SkClipStack() [3/3]

SkClipStack::SkClipStack ( const SkClipStack b)

Definition at line 520 of file SkClipStack.cpp.

521 : fDeque(sizeof(Element), kDefaultElementAllocCnt) {
522 *this = b;
523}
static bool b

◆ ~SkClipStack()

SkClipStack::~SkClipStack ( )

Definition at line 525 of file SkClipStack.cpp.

525 {
526 reset();
527}

Member Function Documentation

◆ bounds()

SkRect SkClipStack::bounds ( const SkIRect deviceBounds) const

Definition at line 601 of file SkClipStack.cpp.

601 {
602 // TODO: optimize this.
603 SkRect r;
605 this->getBounds(&r, &bounds);
607 return SkRect::Make(deviceBounds);
608 }
609 return r.intersect(SkRect::Make(deviceBounds)) ? r : SkRect::MakeEmpty();
610}
void getBounds(SkRect *canvFiniteBound, BoundsType *boundType, bool *isIntersectionOfRects=nullptr) const
SkRect bounds(const SkIRect &deviceBounds) const
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595
bool intersect(const SkRect &r)
Definition SkRect.cpp:114

◆ clipDevRect()

void SkClipStack::clipDevRect ( const SkIRect ir,
SkClipOp  op 
)
inline

Definition at line 343 of file SkClipStack.h.

343 {
344 SkRect r;
345 r.set(ir);
346 this->clipRect(r, SkMatrix::I(), op, false);
347 }
void clipRect(const SkRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
static const SkMatrix & I()
void set(const SkIRect &src)
Definition SkRect.h:849

◆ clipEmpty()

void SkClipStack::clipEmpty ( )

Definition at line 773 of file SkClipStack.cpp.

773 {
774 Element* element = (Element*) fDeque.back();
775
776 if (element && element->canBeIntersectedInPlace(fSaveCount, SkClipOp::kIntersect)) {
777 element->setEmpty();
778 }
779 new (fDeque.push_back()) Element(fSaveCount);
780
781 ((Element*)fDeque.back())->fGenID = kEmptyGenID;
782}
static const uint32_t kEmptyGenID
void * push_back()
Definition SkDeque.cpp:112
const void * back() const
Definition SkDeque.h:43

◆ clipPath()

void SkClipStack::clipPath ( const SkPath path,
const SkMatrix matrix,
SkClipOp  op,
bool  doAA 
)

Definition at line 757 of file SkClipStack.cpp.

758 {
759 Element element(fSaveCount, path, matrix, op, doAA);
760 this->pushElement(element);
761}

◆ clipRect()

void SkClipStack::clipRect ( const SkRect rect,
const SkMatrix matrix,
SkClipOp  op,
bool  doAA 
)

Definition at line 752 of file SkClipStack.cpp.

752 {
753 Element element(fSaveCount, rect, matrix, op, doAA);
754 this->pushElement(element);
755}

◆ clipRRect()

void SkClipStack::clipRRect ( const SkRRect rrect,
const SkMatrix matrix,
SkClipOp  op,
bool  doAA 
)

Definition at line 747 of file SkClipStack.cpp.

747 {
748 Element element(fSaveCount, rrect, matrix, op, doAA);
749 this->pushElement(element);
750}

◆ clipShader()

void SkClipStack::clipShader ( sk_sp< SkShader shader)

Definition at line 763 of file SkClipStack.cpp.

763 {
764 Element element(fSaveCount, std::move(shader));
765 this->pushElement(element);
766}

◆ getBounds()

void SkClipStack::getBounds ( SkRect canvFiniteBound,
BoundsType boundType,
bool *  isIntersectionOfRects = nullptr 
) const

getBounds places the current finite bound in its first parameter. In its second, it indicates which kind of bound is being returned. If 'canvFiniteBound' is a normal bounding box then it encloses all writeable pixels. If 'canvFiniteBound' is an inside out bounding box then it encloses all the un-writeable pixels and the true/normal bound is the infinite plane. isIntersectionOfRects is an optional parameter that is true if 'canvFiniteBound' resulted from an intersection of rects.

Definition at line 615 of file SkClipStack.cpp.

617 {
618 SkASSERT(canvFiniteBound && boundType);
619
620 const Element* element = (const Element*)fDeque.back();
621
622 if (nullptr == element) {
623 // the clip is wide open - the infinite plane w/ no pixels un-writeable
624 canvFiniteBound->setEmpty();
625 *boundType = kInsideOut_BoundsType;
626 if (isIntersectionOfRects) {
627 *isIntersectionOfRects = false;
628 }
629 return;
630 }
631
632 *canvFiniteBound = element->fFiniteBound;
633 *boundType = element->fFiniteBoundType;
634 if (isIntersectionOfRects) {
635 *isIntersectionOfRects = element->fIsIntersectionOfRects;
636 }
637}
#define SkASSERT(cond)
Definition SkAssert.h:116
void setEmpty()
Definition SkRect.h:842

◆ getConservativeBounds()

void SkClipStack::getConservativeBounds ( int  offsetX,
int  offsetY,
int  maxWidth,
int  maxHeight,
SkRect devBounds,
bool *  isIntersectionOfRects = nullptr 
) const

GetConservativeBounds returns a conservative bound of the current clip. Since this could be the infinite plane (if inverse fills were involved) the maxWidth and maxHeight parameters can be used to limit the returned bound to the expected drawing area. Similarly, the offsetX and offsetY parameters allow the caller to offset the returned bound to account for translated drawing areas (i.e., those resulting from a saveLayer). For finite bounds, the translation (+offsetX, +offsetY) is applied before the clamp to the maximum rectangle: [0,maxWidth) x [0,maxHeight). isIntersectionOfRects is an optional parameter that is true when 'devBounds' is the result of an intersection of rects. In this case 'devBounds' is the exact answer/clip.

Definition at line 846 of file SkClipStack.cpp.

851 {
852 SkASSERT(devBounds);
853
854 devBounds->setLTRB(0, 0,
855 SkIntToScalar(maxWidth), SkIntToScalar(maxHeight));
856
857 SkRect temp;
858 SkClipStack::BoundsType boundType;
859
860 // temp starts off in canvas space here
861 this->getBounds(&temp, &boundType, isIntersectionOfRects);
862 if (SkClipStack::kInsideOut_BoundsType == boundType) {
863 return;
864 }
865
866 // but is converted to device space here
868
869 if (!devBounds->intersect(temp)) {
870 devBounds->setEmpty();
871 }
872}
#define SkIntToScalar(x)
Definition SkScalar.h:57
SkScalar offsetX
SkScalar offsetY
void offset(float dx, float dy)
Definition SkRect.h:1016
void setLTRB(float left, float top, float right, float bottom)
Definition SkRect.h:865

◆ getSaveCount()

int SkClipStack::getSaveCount ( ) const
inline

Definition at line 289 of file SkClipStack.h.

289{ return fSaveCount; }

◆ getTopmostGenID()

uint32_t SkClipStack::getTopmostGenID ( ) const

Definition at line 941 of file SkClipStack.cpp.

941 {
942 if (fDeque.empty()) {
943 return kWideOpenGenID;
944 }
945
946 const Element* back = static_cast<const Element*>(fDeque.back());
947 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.isEmpty() &&
948 Element::DeviceSpaceType::kShader != back->fDeviceSpaceType) {
949 return kWideOpenGenID;
950 }
951
952 return back->getGenID();
953}
static const uint32_t kWideOpenGenID
bool empty() const
Definition SkDeque.h:38

◆ isEmpty()

bool SkClipStack::isEmpty ( const SkIRect deviceBounds) const

Definition at line 613 of file SkClipStack.cpp.

613{ return this->bounds(r).isEmpty(); }
bool isEmpty() const
Definition SkRect.h:693

◆ isRRect()

bool SkClipStack::isRRect ( const SkRect bounds,
SkRRect rrect,
bool *  aa 
) const

This method quickly and conservatively determines whether the entire stack is equivalent to intersection with a rrect given a bounds, where the rrect must not contain the entire bounds.

Parameters
boundsA bounds on what will be drawn through the clip. The clip only need be equivalent to a intersection with a rrect for draws within the bounds. The returned rrect must intersect the bounds but need not be contained by the bounds.
rrectIf return is true rrect will contain the rrect equivalent to the stack.
aaIf return is true aa will indicate whether the equivalent rrect clip is antialiased.
Returns
true if the stack is equivalent to a single rrect intersect clip, false otherwise.

Definition at line 874 of file SkClipStack.cpp.

874 {
875 const Element* back = static_cast<const Element*>(fDeque.back());
876 if (!back) {
877 // TODO: return bounds?
878 return false;
879 }
880 // First check if the entire stack is known to be a rect by the top element.
881 if (back->fIsIntersectionOfRects && back->fFiniteBoundType == BoundsType::kNormal_BoundsType) {
882 rrect->setRect(back->fFiniteBound);
883 *aa = back->isAA();
884 return true;
885 }
886
887 if (back->getDeviceSpaceType() != SkClipStack::Element::DeviceSpaceType::kRect &&
888 back->getDeviceSpaceType() != SkClipStack::Element::DeviceSpaceType::kRRect) {
889 return false;
890 }
891 if (back->isReplaceOp()) {
892 *rrect = back->asDeviceSpaceRRect();
893 *aa = back->isAA();
894 return true;
895 }
896
897 if (back->getOp() == SkClipOp::kIntersect) {
898 SkRect backBounds;
899 if (!backBounds.intersect(bounds, back->asDeviceSpaceRRect().rect())) {
900 return false;
901 }
902 // We limit to 17 elements. This means the back element will be bounds checked at most 16
903 // times if it is an rrect.
904 int cnt = fDeque.count();
905 if (cnt > 17) {
906 return false;
907 }
908 if (cnt > 1) {
910 SkAssertResult(static_cast<const Element*>(iter.prev()) == back);
911 while (const Element* prior = (const Element*)iter.prev()) {
912 // TODO: Once expanding clip ops are removed, this is equiv. to op == kDifference
913 if ((prior->getOp() != SkClipOp::kIntersect && !prior->isReplaceOp()) ||
914 !prior->contains(backBounds)) {
915 return false;
916 }
917 if (prior->isReplaceOp()) {
918 break;
919 }
920 }
921 }
922 *rrect = back->asDeviceSpaceRRect();
923 *aa = back->isAA();
924 return true;
925 }
926 return false;
927}
#define SkAssertResult(cond)
Definition SkAssert.h:123
@ kRect
This element combines a device space round-rect with the current clip.
@ kRRect
This element combines a device space path with the current clip.
@ kBack_IterStart
Definition SkDeque.h:66
int count() const
Definition SkDeque.h:39
void setRect(const SkRect &rect)
Definition SkRRect.h:126
SkRRect rrect
Definition SkRecords.h:232

◆ isWideOpen()

bool SkClipStack::isWideOpen ( ) const
inline

isWideOpen returns true if the clip state corresponds to the infinite plane (i.e., draws are not limited at all)

Definition at line 361 of file SkClipStack.h.

361{ return this->getTopmostGenID() == kWideOpenGenID; }
uint32_t getTopmostGenID() const

◆ operator!=()

bool SkClipStack::operator!= ( const SkClipStack b) const
inline

Definition at line 285 of file SkClipStack.h.

285{ return !(*this == b); }

◆ operator=()

SkClipStack & SkClipStack::operator= ( const SkClipStack b)

Definition at line 529 of file SkClipStack.cpp.

529 {
530 if (this == &b) {
531 return *this;
532 }
533 reset();
534
535 fSaveCount = b.fSaveCount;
536 SkDeque::F2BIter recIter(b.fDeque);
537 for (const Element* element = (const Element*)recIter.next();
538 element != nullptr;
539 element = (const Element*)recIter.next()) {
540 new (fDeque.push_back()) Element(*element);
541 }
542
543 return *this;
544}

◆ operator==()

bool SkClipStack::operator== ( const SkClipStack b) const

Definition at line 546 of file SkClipStack.cpp.

546 {
547 if (this->getTopmostGenID() == b.getTopmostGenID()) {
548 return true;
549 }
550 if (fSaveCount != b.fSaveCount ||
551 fDeque.count() != b.fDeque.count()) {
552 return false;
553 }
554 SkDeque::F2BIter myIter(fDeque);
555 SkDeque::F2BIter bIter(b.fDeque);
556 const Element* myElement = (const Element*)myIter.next();
557 const Element* bElement = (const Element*)bIter.next();
558
559 while (myElement != nullptr && bElement != nullptr) {
560 if (*myElement != *bElement) {
561 return false;
562 }
563 myElement = (const Element*)myIter.next();
564 bElement = (const Element*)bIter.next();
565 }
566 return myElement == nullptr && bElement == nullptr;
567}

◆ quickContains() [1/2]

bool SkClipStack::quickContains ( const SkRect devRect) const
inline

Returns true if the input (r)rect in device space is entirely contained by the clip. A return value of false does not guarantee that the (r)rect is not contained by the clip.

Definition at line 335 of file SkClipStack.h.

335 {
336 return this->isWideOpen() || this->internalQuickContains(devRect);
337 }
bool isWideOpen() const

◆ quickContains() [2/2]

bool SkClipStack::quickContains ( const SkRRect devRRect) const
inline

Definition at line 339 of file SkClipStack.h.

339 {
340 return this->isWideOpen() || this->internalQuickContains(devRRect);
341 }

◆ replaceClip()

void SkClipStack::replaceClip ( const SkRect devRect,
bool  doAA 
)

Definition at line 768 of file SkClipStack.cpp.

768 {
769 Element element(fSaveCount, rect, doAA);
770 this->pushElement(element);
771}

◆ reset()

void SkClipStack::reset ( )

Definition at line 569 of file SkClipStack.cpp.

569 {
570 // We used a placement new for each object in fDeque, so we're responsible
571 // for calling the destructor on each of them as well.
572 while (!fDeque.empty()) {
573 Element* element = (Element*)fDeque.back();
574 element->~Element();
575 fDeque.pop_back();
576 }
577
578 fSaveCount = 0;
579}
void pop_back()
Definition SkDeque.cpp:187

◆ restore()

void SkClipStack::restore ( )

Definition at line 585 of file SkClipStack.cpp.

585 {
586 fSaveCount -= 1;
587 restoreTo(fSaveCount);
588}

◆ save()

void SkClipStack::save ( )

Definition at line 581 of file SkClipStack.cpp.

581 {
582 fSaveCount += 1;
583}

Friends And Related Symbol Documentation

◆ Iter

friend class Iter
friend

Definition at line 488 of file SkClipStack.h.

Member Data Documentation

◆ kEmptyGenID

const uint32_t SkClipStack::kEmptyGenID = 1
static

Definition at line 385 of file SkClipStack.h.

◆ kInvalidGenID

const uint32_t SkClipStack::kInvalidGenID = 0
static

The generation ID has three reserved values to indicate special (potentially ignorable) cases Invalid id that is never returned by SkClipStack. Useful when caching clips based on GenID.

Definition at line 382 of file SkClipStack.h.

◆ kWideOpenGenID

const uint32_t SkClipStack::kWideOpenGenID = 2
static

Definition at line 386 of file SkClipStack.h.


The documentation for this class was generated from the following files: