add SkClipStack::clipEmpty() as an optimized way to say clipDevRect(empty, intersect)
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 16 Aug 2012 15:59:59 +0000 (15:59 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 16 Aug 2012 15:59:59 +0000 (15:59 +0000)
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
src/core/SkClipStack.cpp

index 7ebd492..c450fa8 100644 (file)
@@ -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 
index ff771c1..8857244 100644 (file)
@@ -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;