Add way to determine at link time what path renderer will be used.
Added mechanism for a custom path renderer to punt and fallback to default path renderer
git-svn-id: http://skia.googlecode.com/svn/trunk@1005 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrPathRenderer.h b/gpu/include/GrPathRenderer.h
new file mode 100644
index 0000000..2d846c8
--- /dev/null
+++ b/gpu/include/GrPathRenderer.h
@@ -0,0 +1,319 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrPathRenderer_DEFINED
+#define GrPathRenderer_DEFINED
+
+#include "GrDrawTarget.h"
+
+class GrPathIter;
+struct GrPoint;
+
+/**
+ * Base class for drawing paths into a GrDrawTarget.
+ */
+class GrPathRenderer : public GrRefCnt {
+public:
+ /**
+ * Returns true if this path renderer is able to render the path.
+ * Returning false allows the caller to fallback to another path renderer.
+ *
+ * @param target The target to draw into
+ * @param path The path to draw
+ * @param fill The fill rule to use
+ *
+ * @return true if the path can be drawn by this object, false otherwise.
+ */
+ virtual bool canDrawPath(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const = 0;
+
+ /**
+ * Draws a path into the draw target. The target will already have its draw
+ * state configured for the draw.
+ * @param target the target to draw into.
+ * @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
+ * 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).
+ */
+ virtual void drawPath(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate) = 0;
+
+ /**
+ * 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 needs its own stencil
+ * pass. If this returns false then drawPath() should not modify the
+ * the target's stencil settings but use those already set on target.
+ *
+ * @param target target that the path will be rendered to
+ * @param path the path that will be drawn
+ * @param fill the fill rule that will be used, will never be an inverse
+ * rule.
+ *
+ * @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(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const { return false; }
+
+ /**
+ * Draws a path to the stencil buffer. Assume the writable stencil bits
+ * are already initialized to zero. Fill will always be either
+ * kWinding_PathFill or kEvenOdd_PathFill.
+ *
+ * Only called if requiresStencilPass returns true for the same combo of
+ * target, path, and fill. Never called with an inverse fill.
+ *
+ * The default implementation assumes the path filling algorithm doesn't
+ * require a separate stencil pass and so crashes.
+ *
+ *
+ * @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) {
+ GrCrash("Unexpected call to drawPathToStencil.");
+ }
+
+ /**
+ * This is called to install a custom path renderer in every GrContext at
+ * create time. The default implementation in GrCreatePathRenderer_none.cpp
+ * returns NULL. Link against another implementation to install your own.
+ */
+ static GrPathRenderer* CreatePathRenderer();
+
+private:
+
+ typedef GrRefCnt INHERITED;
+};
+
+/**
+ * Subclass that renders the path using the stencil buffer to resolve fill
+ * rules (e.g. winding, even-odd)
+ */
+class GrDefaultPathRenderer : public GrPathRenderer {
+public:
+ GrDefaultPathRenderer(bool separateStencilSupport,
+ bool stencilWrapOpsSupport);
+
+ virtual bool canDrawPath(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const { return true; }
+
+ virtual void drawPath(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate);
+ virtual bool requiresStencilPass(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const;
+ virtual void drawPathToStencil(GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate);
+private:
+
+ void drawPathHelper(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate,
+ bool stencilOnly);
+
+ bool fSeparateStencil;
+ bool fStencilWrapOps;
+
+ typedef GrPathRenderer INHERITED;
+};
+
+#endif
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrPathRenderer_DEFINED
+#define GrPathRenderer_DEFINED
+
+#include "GrDrawTarget.h"
+
+class GrPathIter;
+struct GrPoint;
+
+/**
+ * Base class for drawing paths into a GrDrawTarget.
+ */
+class GrPathRenderer : public GrRefCnt {
+public:
+ /**
+ * Returns true if this path renderer is able to render the path.
+ * Returning false allows the caller to fallback to another path renderer.
+ *
+ * @param target The target to draw into
+ * @param path The path to draw
+ * @param fill The fill rule to use
+ *
+ * @return true if the path can be drawn by this object, false otherwise.
+ */
+ virtual bool canDrawPath(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const = 0;
+
+ /**
+ * Draws a path into the draw target. The target will already have its draw
+ * state configured for the draw.
+ * @param target the target to draw into.
+ * @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
+ * 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).
+ */
+ virtual void drawPath(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate) = 0;
+
+ /**
+ * 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 needs its own stencil
+ * pass. If this returns false then drawPath() should not modify the
+ * the target's stencil settings but use those already set on target.
+ *
+ * @param target target that the path will be rendered to
+ * @param path the path that will be drawn
+ * @param fill the fill rule that will be used, will never be an inverse
+ * rule.
+ *
+ * @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(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const { return false; }
+
+ /**
+ * Draws a path to the stencil buffer. Assume the writable stencil bits
+ * are already initialized to zero. Fill will always be either
+ * kWinding_PathFill or kEvenOdd_PathFill.
+ *
+ * Only called if requiresStencilPass returns true for the same combo of
+ * target, path, and fill. Never called with an inverse fill.
+ *
+ * The default implementation assumes the path filling algorithm doesn't
+ * require a separate stencil pass and so crashes.
+ *
+ *
+ * @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) {
+ GrCrash("Unexpected call to drawPathToStencil.");
+ }
+
+private:
+
+ typedef GrRefCnt INHERITED;
+};
+
+/**
+ * Subclass that renders the path using the stencil buffer to resolve fill
+ * rules (e.g. winding, even-odd)
+ */
+class GrDefaultPathRenderer : public GrPathRenderer {
+public:
+ GrDefaultPathRenderer(bool separateStencilSupport,
+ bool stencilWrapOpsSupport);
+
+ virtual bool canDrawPath(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const { return true; }
+
+ virtual void drawPath(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate);
+ virtual bool requiresStencilPass(const GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill) const;
+ virtual void drawPathToStencil(GrDrawTarget* target,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate);
+private:
+
+ void drawPathHelper(GrDrawTarget* target,
+ GrDrawTarget::StageBitfield stages,
+ GrPathIter* path,
+ GrPathFill fill,
+ const GrPoint* translate,
+ bool stencilOnly);
+
+ bool fSeparateStencil;
+ bool fStencilWrapOps;
+
+ typedef GrPathRenderer INHERITED;
+};
+
+#endif