Add support for clipstack to Gr. GrClip is now a list of rects and paths with set operations to combine them. The stencil buffer is used to perform the set operations to put the clip into the stencil buffer. Building Gr's clip from Skia's clipStack is currently disabled due to the fact that Skia's clipStack is relative to the root layer not the current layer. This will be fixed in a subsequent CL.
git-svn-id: http://skia.googlecode.com/svn/trunk@878 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrPathRenderer.h b/gpu/src/GrPathRenderer.h
index e3fd715..467b0a0 100644
--- a/gpu/src/GrPathRenderer.h
+++ b/gpu/src/GrPathRenderer.h
@@ -34,31 +34,107 @@
* @param stages indicates which stages the are already
* in use. All enabled stages expect positions
* as texture coordinates. The path renderer
- * use the remaining stages for its path
+ * use the remaining stages for its path
* filling algorithm.
* @param path the path to draw.
* @param fill the fill rule to apply.
* @param translate optional additional translation to apply to
- * the path NULL means (0,0).
+ * the path. NULL means (0,0).
*/
virtual void drawPath(GrDrawTarget* target,
GrDrawTarget::StageBitfield stages,
GrPathIter* path,
GrPathFill fill,
const GrPoint* translate) = 0;
+
+ void drawPath(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ const GrPath& path,
+ GrPathFill fill,
+ const GrPoint* translate) {
+ GrPath::Iter iter(path);
+ this->drawPath(target, stages, &iter, fill, translate);
+ }
+
+ /**
+ * For complex clips Gr uses the stencil buffer. The path renderer must be
+ * able to render paths into the stencil buffer. However, the path renderer
+ * itself may require the stencil buffer to resolve the path fill rule. This
+ * function queries whether the path render requires its own stencil
+ * pass. If this returns false then drawPath() should not modify the
+ * the target's stencil settings.
+ *
+ * @return false if this path renderer can generate interior-only fragments
+ * without changing the stencil settings on the target. If it
+ * returns true the drawPathToStencil will be used when rendering
+ * clips.
+ */
+ virtual bool requiresStencilPass(GrPathIter*) const { return false; }
+
+ bool requiresStencilPass(const GrPath& path) const {
+ GrPath::Iter iter(path);
+ return requiresStencilPass(&iter);
+ }
+
+ /**
+ * Draws a path to the stencil buffer. Assume the writable bits are zero
+ * prior and write a nonzero value in interior samples. The default
+ * implementation assumes the path filling algorithm doesn't require a
+ * separate stencil pass and so just calls drawPath.
+ *
+ * Fill will never be an inverse fill rule.
+ *
+ * @param target the target to draw into.
+ * @param path the path to draw.
+ * @param fill the fill rule to apply.
+ * @param translate optional additional translation to apply to
+ * the path. NULL means (0,0).
+ */
+ virtual void drawPathToStencil(GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate) {
+ GrAssert(kInverseEvenOdd_PathFill != fill);
+ GrAssert(kInverseWinding_PathFill != fill);
+
+ this->drawPath(target, 0, path, fill, translate);
+ }
+
+ void drawPathToStencil(GrDrawTarget* target,
+ const GrPath& path,
+ GrPathFill fill,
+ const GrPoint* translate) {
+ GrPath::Iter iter(path);
+ this->drawPathToStencil(target, &iter, fill, translate);
+ }
};
class GrDefaultPathRenderer : public GrPathRenderer {
public:
- GrDefaultPathRenderer(bool singlePassWindingStencil);
+ GrDefaultPathRenderer(bool separateStencilSupport,
+ bool stencilWrapOpsSupport);
virtual void drawPath(GrDrawTarget* target,
GrDrawTarget::StageBitfield stages,
GrPathIter* path,
GrPathFill fill,
const GrPoint* translate);
+ virtual bool requiresStencilPass(GrPath&) const { return true; }
+ virtual void drawPathToStencil(GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate);
private:
- bool fSinglePassWindingStencil;
+
+ void drawPathHelper(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate,
+ bool stencilOnly);
+
+ bool fSeparateStencil;
+ bool fStencilWrapOps;
};
#endif
\ No newline at end of file