diff options
author | 2011-07-01 14:57:55 +0000 | |
---|---|---|
committer | 2011-07-01 14:57:55 +0000 | |
commit | ee435122d7dcb9cd4be4524004b0de282c42848b (patch) | |
tree | 7e74d0c1edfe7df8a59aee965b36272d950b99c2 /gpu/include | |
parent | db2a09f2408728871ed9e26eb1197cad6585a15d (diff) |
Tesselate path once for tiled offscreen AA
Review URL: http://codereview.appspot.com/4661062/
git-svn-id: http://skia.googlecode.com/svn/trunk@1777 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/include')
-rw-r--r-- | gpu/include/GrContext.h | 2 | ||||
-rw-r--r-- | gpu/include/GrPathRenderer.h | 201 | ||||
-rw-r--r-- | gpu/include/GrScalar.h | 3 | ||||
-rw-r--r-- | gpu/include/GrTesselatedPathRenderer.h | 14 |
4 files changed, 144 insertions, 76 deletions
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h index 05282670a5..a8810f984c 100644 --- a/gpu/include/GrContext.h +++ b/gpu/include/GrContext.h @@ -580,7 +580,7 @@ private: void drawClipIntoStencil(); - GrPathRenderer* getPathRenderer(const GrDrawTarget*, const GrPath&, GrPathFill); + GrPathRenderer* getPathRenderer(const GrPath&, GrPathFill); struct OffscreenRecord; diff --git a/gpu/include/GrPathRenderer.h b/gpu/include/GrPathRenderer.h index d77aad66b2..6bc91b58a3 100644 --- a/gpu/include/GrPathRenderer.h +++ b/gpu/include/GrPathRenderer.h @@ -18,57 +18,46 @@ #define GrPathRenderer_DEFINED #include "GrDrawTarget.h" +#include "SkTemplates.h" class SkPath; struct GrPoint; /** * Base class for drawing paths into a GrDrawTarget. + * Paths may be drawn multiple times as when tiling for supersampling. The + * calls on GrPathRenderer to draw a path will look like this: + * + * pr->setPath(target, path, fill, translate); // sets the path to draw + * pr->drawPath(...); // draw the path + * pr->drawPath(...); + * ... + * pr->clearPath(); // finished with the path */ class GR_API GrPathRenderer : public GrRefCnt { public: GrPathRenderer(void); - /** * 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, const SkPath& 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, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate) = 0; + virtual bool canDrawPath(const SkPath& path, GrPathFill fill) const = 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 + * 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'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. + * The view matrix and render target set on the draw target may change + * before setPath/drawPath is called and so shouldn't be considered. * * @param target target that the path will be rendered to * @param path the path that will be drawn @@ -85,7 +74,59 @@ public: GrPathFill fill) const { return false; } /** - * Draws a path to the stencil buffer. Assume the writable stencil bits + * @return true if the path renderer can perform anti-aliasing (aside from + * having FSAA enabled for a render target). Target is provided to + * communicate the draw state (blend mode, stage settings, etc). + */ + virtual bool supportsAA(GrDrawTarget* target, + const SkPath& path, + GrPathFill fill) { return false; } + + /** + * Sets the path to render and target to render into. All calls to drawPath + * and drawPathToStencil must occur between setPath and clearPath. The + * path cannot be modified externally between setPath and clearPath. The + * path may be drawn several times (e.g. tiled supersampler). The target's + * state may change between setPath and drawPath* calls. However, if the + * path renderer specified vertices/indices during setPath or drawPath* + * they will still be set at subsequent drawPath* calls until the next + * clearPath. The target's draw state may change between drawPath* calls + * so if the subclass does any caching of tesselation, etc. then it must + * validate that target parameters that guided the decisions still hold. + * + * @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). + */ + void setPath(GrDrawTarget* target, + const SkPath* path, + GrPathFill fill, + const GrPoint* translate); + + /** + * Notifies path renderer that path set in setPath is no longer in use. + */ + void clearPath(); + + /** + * 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). + * + * Only called between setPath / clearPath. + * + * @param stages bitfield that indicates which stages are + * in use. All enabled stages expect positions + * as texture coordinates. The path renderer + * use the remaining stages for its path + * filling algorithm. + */ + virtual void drawPath(GrDrawTarget::StageBitfield stages) = 0; + + /** + * Draws the 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. * @@ -95,27 +136,11 @@ public: * 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). + * Only called between setPath / clearPath. */ - virtual void drawPathToStencil(GrDrawTarget* target, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate) { + virtual void drawPathToStencil() { GrCrash("Unexpected call to drawPathToStencil."); } - - /** - * @return true if the path renderer can perform anti-aliasing (aside from - * having FSAA enabled for a render target) - */ - virtual bool supportsAA(GrDrawTarget* target, - const SkPath& path, - GrPathFill fill) { return false; } /** * This is called to install a custom path renderer in every GrContext at @@ -134,8 +159,56 @@ public: fCurveTolerance = SkScalarMul(fCurveTolerance, multiplier); } + /** + * Helper that sets a path and automatically remove it in destructor. + */ + class AutoClearPath { + public: + AutoClearPath() { + fPathRenderer = NULL; + } + AutoClearPath(GrPathRenderer* pr, + GrDrawTarget* target, + const SkPath* path, + GrPathFill fill, + const GrPoint* translate) { + GrAssert(NULL != pr); + pr->setPath(target, path, fill, translate); + fPathRenderer = pr; + } + void set(GrPathRenderer* pr, + GrDrawTarget* target, + const SkPath* path, + GrPathFill fill, + const GrPoint* translate) { + if (NULL != fPathRenderer) { + fPathRenderer->clearPath(); + } + GrAssert(NULL != pr); + pr->setPath(target, path, fill, translate); + fPathRenderer = pr; + } + ~AutoClearPath() { + if (NULL != fPathRenderer) { + fPathRenderer->clearPath(); + } + } + private: + GrPathRenderer* fPathRenderer; + }; + protected: + + // subclass can override these to be notified just after a path is set + // and just before the path is cleared. + virtual void pathWasSet() {} + virtual void pathWillClear() {} + GrScalar fCurveTolerance; + const SkPath* fPath; + GrDrawTarget* fTarget; + GrPathFill fFill; + GrPoint fTranslate; private: @@ -151,35 +224,37 @@ public: GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport); - virtual bool canDrawPath(const GrDrawTarget* target, - const SkPath& path, + virtual bool canDrawPath(const SkPath& path, GrPathFill fill) const { return true; } - virtual void drawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate); virtual bool requiresStencilPass(const GrDrawTarget* target, const SkPath& path, GrPathFill fill) const; - virtual void drawPathToStencil(GrDrawTarget* target, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate); + + virtual void drawPath(GrDrawTarget::StageBitfield stages); + virtual void drawPathToStencil(); + +protected: + virtual void pathWillClear(); + private: - void onDrawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate, - bool stencilOnly); + void onDrawPath(GrDrawTarget::StageBitfield stages, bool stencilOnly); + + void createGeom(GrScalar srcSpaceTolSqd, + GrDrawTarget::StageBitfield stages); bool fSeparateStencil; bool fStencilWrapOps; + int fSubpathCount; + SkAutoSTMalloc<8, uint16_t> fSubpathVertCount; + GrScalar fPreviousSrcTol; + GrDrawTarget::StageBitfield fPreviousStages; + + typedef GrPathRenderer INHERITED; }; #endif + diff --git a/gpu/include/GrScalar.h b/gpu/include/GrScalar.h index 35cd61a22c..409e80b6e6 100644 --- a/gpu/include/GrScalar.h +++ b/gpu/include/GrScalar.h @@ -39,7 +39,8 @@ #define GrIntToScalar(a) SkIntToScalar(a) #define GrScalarHalf(a) SkScalarHalf(a) #define GrScalarAve(a,b) SkScalarAve(a,b) -#define GrMul(a,b) SkScalarMul(a,b) +#define GrMul(a,b) SkScalarMul(a,b) // deprecated, prefer GrScalarMul +#define GrScalarMul(a,b) SkScalarMul(a,b) #define GrScalarDiv(a,b) SkScalarDiv(a, b) #define GrScalarToFloat(a) SkScalarToFloat(a) #define GrFloatToScalar(a) SkScalarToFloat(a) diff --git a/gpu/include/GrTesselatedPathRenderer.h b/gpu/include/GrTesselatedPathRenderer.h index e37e66bdf8..dac9a17c8f 100644 --- a/gpu/include/GrTesselatedPathRenderer.h +++ b/gpu/include/GrTesselatedPathRenderer.h @@ -23,22 +23,14 @@ class GrTesselatedPathRenderer : public GrPathRenderer { public: GrTesselatedPathRenderer(); - virtual void drawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate); - virtual bool canDrawPath(const GrDrawTarget* target, - const GrPath& path, + virtual void drawPath(GrDrawTarget::StageBitfield stages); + virtual bool canDrawPath(const GrPath& path, GrPathFill fill) const; virtual bool requiresStencilPass(const GrDrawTarget* target, const GrPath& path, GrPathFill fill) const { return false; } - virtual void drawPathToStencil(GrDrawTarget* target, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate); + virtual void drawPathToStencil(); virtual bool supportsAA(GrDrawTarget* target, const GrPath& path, GrPathFill fill); |