SkClipStack::Element tweaks.
authorfmalita <fmalita@chromium.org>
Thu, 5 Jun 2014 19:40:07 +0000 (12:40 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 5 Jun 2014 19:40:07 +0000 (12:40 -0700)
(
This is intended to facilitate efficient kMatrix_SaveFlags emulation
on restore():

  * collect all clip stack elements for the current save count into a
    side clip stack
  * canvas.restore(everything)
  * replay the collected clip ops to restore the initial clip state
  => we restored the matrix but the clip state is unchanged
)

Two main changes:

  * expose the save count for SkClipStack::Element
  * expose a replay method for the same (logic relocated from
    SkCanvas::replayClips)

The SkCanvas::ClipVisitor shuffling is to enable forward decl
in SkClipStack.h (cannot fwdecl a nested class).

R=reed@google.com, robertphillips@google.com
TBR=reed@google.com

Author: fmalita@chromium.org

Review URL: https://codereview.chromium.org/269693003

include/core/SkCanvas.h
include/core/SkClipStack.h
src/core/SkCanvas.cpp
src/core/SkClipStack.cpp

index ee8ad25..b92b146 100644 (file)
@@ -24,6 +24,7 @@
     #define SK_LEGACY_DRAWTEXT_VIRTUAL
 #endif
 
+class SkCanvasClipVisitor;
 class SkBaseDevice;
 class SkDraw;
 class SkDrawFilter;
@@ -1134,14 +1135,7 @@ public:
         return &fClipStack;
     }
 
-    class ClipVisitor {
-    public:
-        virtual ~ClipVisitor();
-        virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
-        virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
-        virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
-    };
-
+    typedef SkCanvasClipVisitor ClipVisitor;
     /**
      *  Replays the clip operations, back to front, that have been applied to
      *  the canvas, calling the appropriate method on the visitor for each
@@ -1504,5 +1498,12 @@ static inline SkCanvas::SaveFlags& operator|=(SkCanvas::SaveFlags& lhs,
     return lhs;
 }
 
+class SkCanvasClipVisitor {
+public:
+    virtual ~SkCanvasClipVisitor();
+    virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
+    virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
+    virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
+};
 
 #endif
index 028d551..4243cee 100644 (file)
@@ -16,6 +16,7 @@
 #include "SkTDArray.h"
 #include "SkTLazy.h"
 
+class SkCanvasClipVisitor;
 
 // Because a single save/restore state can have multiple clips, this class
 // stores the stack depth (fSaveCount) and clips (fDeque) separately.
@@ -74,6 +75,9 @@ public:
         //!< Call to get the type of the clip element.
         Type getType() const { return fType; }
 
+        //!< Call to get the save count associated with this clip element.
+        int getSaveCount() const { return fSaveCount; }
+
         //!< Call if getType() is kPath to get the path.
         const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); }
 
@@ -156,6 +160,11 @@ public:
             return kPath_Type == fType && fPath.get()->isInverseFillType();
         }
 
+        /**
+        * Replay this clip into the visitor.
+        */
+        void replay(SkCanvasClipVisitor*) const;
+
     private:
         friend class SkClipStack;
 
index 3134c46..bdbcd3b 100644 (file)
@@ -1666,22 +1666,8 @@ void SkCanvas::replayClips(ClipVisitor* visitor) const {
     SkClipStack::B2TIter                iter(fClipStack);
     const SkClipStack::Element*         element;
 
-    static const SkRect kEmpty = { 0, 0, 0, 0 };
     while ((element = iter.next()) != NULL) {
-        switch (element->getType()) {
-            case SkClipStack::Element::kPath_Type:
-                visitor->clipPath(element->getPath(), element->getOp(), element->isAA());
-                break;
-            case SkClipStack::Element::kRRect_Type:
-                visitor->clipRRect(element->getRRect(), element->getOp(), element->isAA());
-                break;
-            case SkClipStack::Element::kRect_Type:
-                visitor->clipRect(element->getRect(), element->getOp(), element->isAA());
-                break;
-            case SkClipStack::Element::kEmpty_Type:
-                visitor->clipRect(kEmpty, SkRegion::kIntersect_Op, false);
-                break;
-        }
+        element->replay(visitor);
     }
 }
 
@@ -2556,7 +2542,7 @@ int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkCanvas::ClipVisitor::~ClipVisitor() { }
+SkCanvasClipVisitor::~SkCanvasClipVisitor() { }
 
 ///////////////////////////////////////////////////////////////////////////////
 
index b60a6c9..d087592 100644 (file)
@@ -1,10 +1,11 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
+#include "SkCanvas.h"
 #include "SkClipStack.h"
 #include "SkPath.h"
 #include "SkThread.h"
@@ -66,6 +67,25 @@ bool SkClipStack::Element::operator== (const Element& element) const {
     }
 }
 
+void SkClipStack::Element::replay(SkCanvasClipVisitor* visitor) const {
+    static const SkRect kEmptyRect = { 0, 0, 0, 0 };
+
+    switch (fType) {
+        case kPath_Type:
+            visitor->clipPath(this->getPath(), this->getOp(), this->isAA());
+            break;
+        case kRRect_Type:
+            visitor->clipRRect(this->getRRect(), this->getOp(), this->isAA());
+            break;
+        case kRect_Type:
+            visitor->clipRect(this->getRect(), this->getOp(), this->isAA());
+            break;
+        case kEmpty_Type:
+            visitor->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false);
+            break;
+    }
+}
+
 void SkClipStack::Element::invertShapeFillType() {
     switch (fType) {
         case kRect_Type: