From 0557d9ea94d5435a9072c9b4141a05190d648442 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Thu, 16 Aug 2012 15:59:59 +0000 Subject: [PATCH] add SkClipStack::clipEmpty() as an optimized way to say clipDevRect(empty, intersect) if the caller knows up-front that it wants the clipstact to become empty. Review URL: https://codereview.appspot.com/6443132 git-svn-id: http://skia.googlecode.com/svn/trunk@5127 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkClipStack.h | 2 ++ src/core/SkClipStack.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h index 7ebd492..c450fa8 100644 --- a/include/core/SkClipStack.h +++ b/include/core/SkClipStack.h @@ -70,6 +70,8 @@ public: } void clipDevRect(const SkRect&, SkRegion::Op, bool doAA); void clipDevPath(const SkPath&, SkRegion::Op, bool doAA); + // An optimized version of clipDevRect(emptyRect, kIntersect, ...) + void clipEmpty(); /** * isWideOpen returns true if the clip state corresponds to the infinite diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp index ff771c1..8857244 100644 --- a/src/core/SkClipStack.cpp +++ b/src/core/SkClipStack.cpp @@ -48,6 +48,12 @@ struct SkClipStack::Rec { int fGenID; + Rec(int saveCount) + : fGenID(kInvalidGenID) { + fSaveCount = saveCount; + this->setEmpty(); + } + Rec(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) : fRect(rect) , fGenID(kInvalidGenID) { @@ -352,6 +358,8 @@ struct SkClipStack::Rec { } } else { + SkASSERT(kPath_State == fState); + fFiniteBound = fPath.getBounds(); if (fPath.isInverseFillType()) { @@ -638,6 +646,30 @@ void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { } } +void SkClipStack::clipEmpty() { + + SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); + Rec* rec = (Rec*) iter.prev(); + + if (rec && rec->canBeIntersectedInPlace(fSaveCount, SkRegion::kIntersect_Op)) { + switch (rec->fState) { + case Rec::kEmpty_State: + rec->checkEmpty(); + return; + case Rec::kRect_State: + case Rec::kPath_State: + this->purgeClip(rec); + rec->setEmpty(); + return; + } + } + new (fDeque.push_back()) Rec(fSaveCount); + + if (rec && rec->fSaveCount == fSaveCount) { + this->purgeClip(rec); + } +} + bool SkClipStack::isWideOpen() const { if (0 == fDeque.count()) { return true; -- 2.7.4