SkClipStack::Element tweaks.
(
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
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index ee8ad25..b92b146 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -24,6 +24,7 @@
#define SK_LEGACY_DRAWTEXT_VIRTUAL
#endif
+class SkCanvasClipVisitor;
class SkBaseDevice;
class SkDraw;
class SkDrawFilter;
@@ -1134,14 +1135,7 @@
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 @@
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
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index 028d551..4243cee 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -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 @@
//!< 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 @@
return kPath_Type == fType && fPath.get()->isInverseFillType();
}
+ /**
+ * Replay this clip into the visitor.
+ */
+ void replay(SkCanvasClipVisitor*) const;
+
private:
friend class SkClipStack;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 3134c46..bdbcd3b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1666,22 +1666,8 @@
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 @@
///////////////////////////////////////////////////////////////////////////////
-SkCanvas::ClipVisitor::~ClipVisitor() { }
+SkCanvasClipVisitor::~SkCanvasClipVisitor() { }
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index b60a6c9..d087592 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -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 @@
}
}
+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: