aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPathRenderer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrPathRenderer.h')
-rw-r--r--src/gpu/GrPathRenderer.h145
1 files changed, 88 insertions, 57 deletions
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index afcd3c9c22..9d525663f1 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -12,72 +12,86 @@
#include "GrDrawTarget.h"
#include "GrPathRendererChain.h"
+#include "GrStencil.h"
+#include "SkStroke.h"
#include "SkTArray.h"
class SkPath;
-class SkStroke;
struct GrPoint;
/**
* Base class for drawing paths into a GrDrawTarget.
*
- * Derived classes can use stages GrPaint::kTotalStages through
- * GrDrawState::kNumStages-1. The stages before GrPaint::kTotalStages
- * are reserved for setting up the draw (i.e., textures and filter masks).
+ * Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kNumStages-1. The
+ * stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and
+ * filter masks).
*/
class GR_API GrPathRenderer : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrPathRenderer)
/**
- * This is called to install custom path renderers in every GrContext at
- * create time. The default implementation in GrCreatePathRenderer_none.cpp
- * does not add any additional renderers. Link against another
- * implementation to install your own. The first added is the most preferred
- * path renderer, second is second most preferred, etc.
+ * This is called to install custom path renderers in every GrContext at create time. The
+ * default implementation in GrCreatePathRenderer_none.cpp does not add any additional
+ * renderers. Link against another implementation to install your own. The first added is the
+ * most preferred path renderer, second is second most preferred, etc.
*
* @param context the context that will use the path renderer
- * @param flags flags indicating how path renderers will be used
* @param prChain the chain to add path renderers to.
*/
- static void AddPathRenderers(GrContext* context,
- GrPathRendererChain::UsageFlags flags,
- GrPathRendererChain* prChain);
+ static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChain);
GrPathRenderer();
/**
- * 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. The
- * target is passed as a param in case the answer depends upon draw state.
+ * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
+ * the path renderer itself may require use of the stencil buffer. Also a path renderer may
+ * use a GrEffect coverage stage that sets coverage to zero to eliminate pixels that are covered
+ * by bounding geometry but outside the path. These exterior pixels would still be rendered into
+ * the stencil.
+ *
+ * A GrPathRenderer can provide three levels of support for stenciling paths:
+ * 1) kNoRestriction: This is the most general. The caller sets up the GrDrawState on the target
+ * and calls drawPath(). The path is rendered exactly as the draw state
+ * indicates including support for simultaneous color and stenciling with
+ * arbitrary stenciling rules. Pixels partially covered by AA paths are
+ * affected by the stencil settings.
+ * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
+ * simultaneously. The path renderer does support the stencilPath() function
+ * which performs no color writes and writes a non-zero stencil value to pixels
+ * covered by the path.
+ * 3) kNoSupport: This path renderer cannot be used to stencil the path.
+ */
+ typedef GrPathRendererChain::StencilSupport StencilSupport;
+ static const StencilSupport kNoSupport_StencilSupport =
+ GrPathRendererChain::kNoSupport_StencilSupport;
+ static const StencilSupport kStencilOnly_StencilSupport =
+ GrPathRendererChain::kStencilOnly_StencilSupport;
+ static const StencilSupport kNoRestriction_StencilSupport =
+ GrPathRendererChain::kNoRestriction_StencilSupport;
+
+ /**
+ * This function is to get the stencil support for a particular path. The path's fill must
+ * not be an inverse type.
*
* @param target target that the path will be rendered to
* @param path the path that will be drawn
* @param stroke the stroke information (width, join, cap).
- *
- * @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 SkPath& path,
+ StencilSupport getStencilSupport(const SkPath& path,
const SkStroke& stroke,
const GrDrawTarget* target) const {
- return false;
+ GrAssert(!path.isInverseFillType());
+ return this->onGetStencilSupport(path, stroke, target);
}
/**
- * Returns true if this path renderer is able to render the path.
- * Returning false allows the caller to fallback to another path renderer
- * This function is called when searching for a path renderer capable of
- * rendering a path.
+ * Returns true if this path renderer is able to render the path. Returning false allows the
+ * caller to fallback to another path renderer This function is called when searching for a path
+ * renderer capable of rendering a path.
*
* @param path The path to draw
* @param stroke The stroke information (width, join, cap)
@@ -91,55 +105,72 @@ public:
const GrDrawTarget* target,
bool antiAlias) const = 0;
/**
- * Draws the path into the draw target. If requiresStencilBuffer returned
- * false then the target may be setup for stencil rendering (since the
- * path renderer didn't claim that it needs to use the stencil internally).
+ * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
+ * the subclass must respect the stencil settings of the target's draw state.
*
* @param path the path to draw.
* @param stroke the stroke information (width, join, cap)
* @param target target that the path will be rendered to
* @param antiAlias true if anti-aliasing is required.
*/
- virtual bool drawPath(const SkPath& path,
- const SkStroke& stroke,
- GrDrawTarget* target,
- bool antiAlias) {
+ bool drawPath(const SkPath& path,
+ const SkStroke& stroke,
+ GrDrawTarget* target,
+ bool antiAlias) {
GrAssert(this->canDrawPath(path, stroke, target, antiAlias));
return this->onDrawPath(path, stroke, target, antiAlias);
}
/**
- * Draws the path to the stencil buffer. Assume the writable stencil bits
- * are already initialized to zero. Fill will always be either
- * kWinding_FillType or kEvenOdd_FillType.
- *
- * 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.
+ * Draws the path to the stencil buffer. Assume the writable stencil bits are already
+ * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
*
+ * @param path the path to draw.
+ * @param stroke the stroke information (width, join, cap)
+ * @param target target that the path will be rendered to
*/
- virtual void drawPathToStencil(const SkPath& path,
- const SkStroke& stroke,
- GrDrawTarget* target) {
- GrCrash("Unexpected call to drawPathToStencil.");
+ void stencilPath(const SkPath& path, const SkStroke& stroke, GrDrawTarget* target) {
+ GrAssert(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target));
+ this->onStencilPath(path, stroke, target);
}
protected:
/**
- * Draws the path into the draw target.
- *
- * @param path the path to draw.
- * @param stroke the stroke information (width, join, cap)
- * @param target target that the path will be rendered to
- * @param antiAlias whether antialiasing is enabled or not.
+ * Subclass overrides if it has any limitations of stenciling support.
+ */
+ virtual StencilSupport onGetStencilSupport(const SkPath&,
+ const SkStroke&,
+ const GrDrawTarget*) const {
+ return kNoRestriction_StencilSupport;
+ }
+
+ /**
+ * Subclass implementation of drawPath()
*/
virtual bool onDrawPath(const SkPath& path,
const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) = 0;
+ /**
+ * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
+ * kStencilOnly in onGetStencilSupport().
+ */
+ virtual void onStencilPath(const SkPath& path, const SkStroke& stroke, GrDrawTarget* target) {
+ GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
+ GrDrawState* drawState = target->drawState();
+ GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
+ drawState->setStencil(kIncrementStencil);
+ drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
+ this->drawPath(path, stroke, target, false);
+ }
+
private:
typedef GrRefCnt INHERITED;