| OLD | NEW | 
|    1  |    1  | 
|    2 /* |    2 /* | 
|    3  * Copyright 2011 Google Inc. |    3  * Copyright 2011 Google Inc. | 
|    4  * |    4  * | 
|    5  * Use of this source code is governed by a BSD-style license that can be |    5  * Use of this source code is governed by a BSD-style license that can be | 
|    6  * found in the LICENSE file. |    6  * found in the LICENSE file. | 
|    7  */ |    7  */ | 
|    8  |    8  | 
|    9 #ifndef GrPathRenderer_DEFINED |    9 #ifndef GrPathRenderer_DEFINED | 
|   10 #define GrPathRenderer_DEFINED |   10 #define GrPathRenderer_DEFINED | 
|   11  |   11  | 
|   12 #include "GrDrawTarget.h" |   12 #include "GrDrawTarget.h" | 
|   13 #include "GrPathRendererChain.h" |   13 #include "GrPathRendererChain.h" | 
|   14 #include "GrStencil.h" |   14 #include "GrStencil.h" | 
|   15  |   15  | 
|   16 #include "SkDrawProcs.h" |   16 #include "SkDrawProcs.h" | 
|   17 #include "SkStrokeRec.h" |   17 #include "SkStrokeRec.h" | 
|   18 #include "SkTArray.h" |   18 #include "SkTArray.h" | 
|   19  |   19  | 
|   20 class SkPath; |   20 class SkPath; | 
|   21  |   21  | 
|   22 struct GrPoint; |   22 struct GrPoint; | 
|   23  |   23  | 
|   24 /** |   24 /** | 
|   25  *  Base class for drawing paths into a GrDrawTarget. |   25  *  Base class for drawing paths into a GrDrawTarget. | 
|   26  * |   26  * | 
|   27  *  Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kN
     umStages-1. The |   27  *  Derived classes can use stages GrPaint::kTotalStages through GrPipelineBuild
     er::kNumStages-1. | 
|   28  *  stages before GrPaint::kTotalStages are reserved for setting up the draw (i.
     e., textures and |   28  *  The stages before GrPaint::kTotalStages are reserved for setting up the draw
      (i.e., textures and | 
|   29  *  filter masks). |   29  *  filter masks). | 
|   30  */ |   30  */ | 
|   31 class SK_API GrPathRenderer : public SkRefCnt { |   31 class SK_API GrPathRenderer : public SkRefCnt { | 
|   32 public: |   32 public: | 
|   33     SK_DECLARE_INST_COUNT(GrPathRenderer) |   33     SK_DECLARE_INST_COUNT(GrPathRenderer) | 
|   34  |   34  | 
|   35     /** |   35     /** | 
|   36      * This is called to install custom path renderers in every GrContext at cre
     ate time. The |   36      * This is called to install custom path renderers in every GrContext at cre
     ate time. The | 
|   37      * default implementation in GrCreatePathRenderer_none.cpp does not add any 
     additional |   37      * default implementation in GrCreatePathRenderer_none.cpp does not add any 
     additional | 
|   38      * renderers. Link against another implementation to install your own. The f
     irst added is the |   38      * renderers. Link against another implementation to install your own. The f
     irst added is the | 
|   39      * most preferred path renderer, second is second most preferred, etc. |   39      * most preferred path renderer, second is second most preferred, etc. | 
|   40      * |   40      * | 
|   41      * @param context   the context that will use the path renderer |   41      * @param context   the context that will use the path renderer | 
|   42      * @param prChain   the chain to add path renderers to. |   42      * @param prChain   the chain to add path renderers to. | 
|   43      */ |   43      */ | 
|   44     static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChai
     n); |   44     static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChai
     n); | 
|   45  |   45  | 
|   46  |   46  | 
|   47     GrPathRenderer(); |   47     GrPathRenderer(); | 
|   48  |   48  | 
|   49     /** |   49     /** | 
|   50      * A caller may wish to use a path renderer to draw a path into the stencil 
     buffer. However, |   50      * A caller may wish to use a path renderer to draw a path into the stencil 
     buffer. However, | 
|   51      * the path renderer itself may require use of the stencil buffer. Also a pa
     th renderer may |   51      * the path renderer itself may require use of the stencil buffer. Also a pa
     th renderer may | 
|   52      * use a GrProcessor coverage stage that sets coverage to zero to eliminate 
     pixels that are |   52      * use a GrProcessor coverage stage that sets coverage to zero to eliminate 
     pixels that are | 
|   53      * covered by bounding geometry but outside the path. These exterior pixels 
     would still be |   53      * covered by bounding geometry but outside the path. These exterior pixels 
     would still be | 
|   54      * rendered into the stencil. |   54      * rendered into the stencil. | 
|   55      * |   55      * | 
|   56      * A GrPathRenderer can provide three levels of support for stenciling paths
     : |   56      * A GrPathRenderer can provide three levels of support for stenciling paths
     : | 
|   57      * 1) kNoRestriction: This is the most general. The caller sets up the GrDra
     wState on the target |   57      * 1) kNoRestriction: This is the most general. The caller sets up the GrPip
     elineBuilder on the target | 
|   58      *                    and calls drawPath(). The path is rendered exactly as 
     the draw state |   58      *                    and calls drawPath(). The path is rendered exactly as 
     the draw state | 
|   59      *                    indicates including support for simultaneous color and
      stenciling with |   59      *                    indicates including support for simultaneous color and
      stenciling with | 
|   60      *                    arbitrary stenciling rules. Pixels partially covered b
     y AA paths are |   60      *                    arbitrary stenciling rules. Pixels partially covered b
     y AA paths are | 
|   61      *                    affected by the stencil settings. |   61      *                    affected by the stencil settings. | 
|   62      * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules n
     or shade and stencil |   62      * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules n
     or shade and stencil | 
|   63      *                  simultaneously. The path renderer does support the stenc
     ilPath() function |   63      *                  simultaneously. The path renderer does support the stenc
     ilPath() function | 
|   64      *                  which performs no color writes and writes a non-zero ste
     ncil value to pixels |   64      *                  which performs no color writes and writes a non-zero ste
     ncil value to pixels | 
|   65      *                  covered by the path. |   65      *                  covered by the path. | 
|   66      * 3) kNoSupport: This path renderer cannot be used to stencil the path. |   66      * 3) kNoSupport: This path renderer cannot be used to stencil the path. | 
|   67      */ |   67      */ | 
|   68     typedef GrPathRendererChain::StencilSupport StencilSupport; |   68     typedef GrPathRendererChain::StencilSupport StencilSupport; | 
|   69     static const StencilSupport kNoSupport_StencilSupport = |   69     static const StencilSupport kNoSupport_StencilSupport = | 
|   70         GrPathRendererChain::kNoSupport_StencilSupport; |   70         GrPathRendererChain::kNoSupport_StencilSupport; | 
|   71     static const StencilSupport kStencilOnly_StencilSupport = |   71     static const StencilSupport kStencilOnly_StencilSupport = | 
|   72         GrPathRendererChain::kStencilOnly_StencilSupport; |   72         GrPathRendererChain::kStencilOnly_StencilSupport; | 
|   73     static const StencilSupport kNoRestriction_StencilSupport = |   73     static const StencilSupport kNoRestriction_StencilSupport = | 
|   74         GrPathRendererChain::kNoRestriction_StencilSupport; |   74         GrPathRendererChain::kNoRestriction_StencilSupport; | 
|   75  |   75  | 
|   76     /** |   76     /** | 
|   77      * This function is to get the stencil support for a particular path. The pa
     th's fill must |   77      * This function is to get the stencil support for a particular path. The pa
     th's fill must | 
|   78      * not be an inverse type. |   78      * not be an inverse type. | 
|   79      * |   79      * | 
|   80      * @param target    target that the path will be rendered to |   80      * @param target    target that the path will be rendered to | 
|   81      * @param path      the path that will be drawn |   81      * @param path      the path that will be drawn | 
|   82      * @param stroke    the stroke information (width, join, cap). |   82      * @param stroke    the stroke information (width, join, cap). | 
|   83      */ |   83      */ | 
|   84     StencilSupport getStencilSupport(const GrDrawTarget* target, |   84     StencilSupport getStencilSupport(const GrDrawTarget* target, | 
|   85                                      const GrDrawState* drawState, |   85                                      const GrPipelineBuilder* pipelineBuilder, | 
|   86                                      const SkPath& path, |   86                                      const SkPath& path, | 
|   87                                      const SkStrokeRec& stroke) const { |   87                                      const SkStrokeRec& stroke) const { | 
|   88         SkASSERT(!path.isInverseFillType()); |   88         SkASSERT(!path.isInverseFillType()); | 
|   89         return this->onGetStencilSupport(target, drawState, path, stroke); |   89         return this->onGetStencilSupport(target, pipelineBuilder, path, stroke); | 
|   90     } |   90     } | 
|   91  |   91  | 
|   92     /** |   92     /** | 
|   93      * Returns true if this path renderer is able to render the path. Returning 
     false allows the |   93      * Returns true if this path renderer is able to render the path. Returning 
     false allows the | 
|   94      * caller to fallback to another path renderer This function is called when 
     searching for a path |   94      * caller to fallback to another path renderer This function is called when 
     searching for a path | 
|   95      * renderer capable of rendering a path. |   95      * renderer capable of rendering a path. | 
|   96      * |   96      * | 
|   97      * @param target     The target that the path will be rendered to |   97      * @param target           The target that the path will be rendered to | 
|   98      * @param drawState  The drawState |   98      * @param pipelineBuilder  The pipelineBuilder | 
|   99      * @param viewMatrix The viewMatrix |   99      * @param viewMatrix       The viewMatrix | 
|  100      * @param path       The path to draw |  100      * @param path             The path to draw | 
|  101      * @param stroke     The stroke information (width, join, cap) |  101      * @param stroke           The stroke information (width, join, cap) | 
|  102      * @param antiAlias  True if anti-aliasing is required. |  102      * @param antiAlias        True if anti-aliasing is required. | 
|  103      * |  103      * | 
|  104      * @return  true if the path can be drawn by this object, false otherwise. |  104      * @return  true if the path can be drawn by this object, false otherwise. | 
|  105      */ |  105      */ | 
|  106     virtual bool canDrawPath(const GrDrawTarget* target, |  106     virtual bool canDrawPath(const GrDrawTarget* target, | 
|  107                              const GrDrawState* drawState, |  107                              const GrPipelineBuilder* pipelineBuilder, | 
|  108                              const SkMatrix& viewMatrix, |  108                              const SkMatrix& viewMatrix, | 
|  109                              const SkPath& path, |  109                              const SkPath& path, | 
|  110                              const SkStrokeRec& rec, |  110                              const SkStrokeRec& rec, | 
|  111                              bool antiAlias) const = 0; |  111                              bool antiAlias) const = 0; | 
|  112     /** |  112     /** | 
|  113      * Draws the path into the draw target. If getStencilSupport() would return 
     kNoRestriction then |  113      * Draws the path into the draw target. If getStencilSupport() would return 
     kNoRestriction then | 
|  114      * the subclass must respect the stencil settings of the target's draw state
     . |  114      * the subclass must respect the stencil settings of the target's draw state
     . | 
|  115      * |  115      * | 
|  116      * @param target                The target that the path will be rendered to |  116      * @param target                The target that the path will be rendered to | 
|  117      * @param drawState             The drawState |  117      * @param pipelineBuilder       The pipelineBuilder | 
|  118      * @param viewMatrix            The viewMatrix |  118      * @param viewMatrix            The viewMatrix | 
|  119      * @param path                  the path to draw. |  119      * @param path                  the path to draw. | 
|  120      * @param stroke                the stroke information (width, join, cap) |  120      * @param stroke                the stroke information (width, join, cap) | 
|  121      * @param antiAlias             true if anti-aliasing is required. |  121      * @param antiAlias             true if anti-aliasing is required. | 
|  122      */ |  122      */ | 
|  123     bool drawPath(GrDrawTarget* target, |  123     bool drawPath(GrDrawTarget* target, | 
|  124                   GrDrawState* ds, |  124                   GrPipelineBuilder* ds, | 
|  125                   GrColor color, |  125                   GrColor color, | 
|  126                   const SkMatrix& viewMatrix, |  126                   const SkMatrix& viewMatrix, | 
|  127                   const SkPath& path, |  127                   const SkPath& path, | 
|  128                   const SkStrokeRec& stroke, |  128                   const SkStrokeRec& stroke, | 
|  129                   bool antiAlias) { |  129                   bool antiAlias) { | 
|  130         SkASSERT(!path.isEmpty()); |  130         SkASSERT(!path.isEmpty()); | 
|  131         SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAli
     as)); |  131         SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAli
     as)); | 
|  132         SkASSERT(ds->getStencil().isDisabled() || |  132         SkASSERT(ds->getStencil().isDisabled() || | 
|  133                  kNoRestriction_StencilSupport == this->getStencilSupport(target
     , ds, path, |  133                  kNoRestriction_StencilSupport == this->getStencilSupport(target
     , ds, path, | 
|  134                                                                           stroke
     )); |  134                                                                           stroke
     )); | 
|  135         return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, ant
     iAlias); |  135         return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, ant
     iAlias); | 
|  136     } |  136     } | 
|  137  |  137  | 
|  138     /** |  138     /** | 
|  139      * Draws the path to the stencil buffer. Assume the writable stencil bits ar
     e already |  139      * Draws the path to the stencil buffer. Assume the writable stencil bits ar
     e already | 
|  140      * initialized to zero. The pixels inside the path will have non-zero stenci
     l values afterwards. |  140      * initialized to zero. The pixels inside the path will have non-zero stenci
     l values afterwards. | 
|  141      * |  141      * | 
|  142      * @param path                  the path to draw. |  142      * @param path                  the path to draw. | 
|  143      * @param stroke                the stroke information (width, join, cap) |  143      * @param stroke                the stroke information (width, join, cap) | 
|  144      * @param target                target that the path will be rendered to |  144      * @param target                target that the path will be rendered to | 
|  145      */ |  145      */ | 
|  146     void stencilPath(GrDrawTarget* target, |  146     void stencilPath(GrDrawTarget* target, | 
|  147                      GrDrawState* ds, |  147                      GrPipelineBuilder* ds, | 
|  148                      const SkMatrix& viewMatrix, |  148                      const SkMatrix& viewMatrix, | 
|  149                      const SkPath& path, |  149                      const SkPath& path, | 
|  150                      const SkStrokeRec& stroke) { |  150                      const SkStrokeRec& stroke) { | 
|  151         SkASSERT(!path.isEmpty()); |  151         SkASSERT(!path.isEmpty()); | 
|  152         SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds
     , path, stroke)); |  152         SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds
     , path, stroke)); | 
|  153         this->onStencilPath(target, ds, viewMatrix, path, stroke); |  153         this->onStencilPath(target, ds, viewMatrix, path, stroke); | 
|  154     } |  154     } | 
|  155  |  155  | 
|  156     // Helper for determining if we can treat a thin stroke as a hairline w/ cov
     erage. |  156     // Helper for determining if we can treat a thin stroke as a hairline w/ cov
     erage. | 
|  157     // If we can, we draw lots faster (raster device does this same test). |  157     // If we can, we draw lots faster (raster device does this same test). | 
|  158     static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
     Matrix& matrix, |  158     static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
     Matrix& matrix, | 
|  159                                              SkScalar* outCoverage) { |  159                                              SkScalar* outCoverage) { | 
|  160         if (stroke.isHairlineStyle()) { |  160         if (stroke.isHairlineStyle()) { | 
|  161             if (outCoverage) { |  161             if (outCoverage) { | 
|  162                 *outCoverage = SK_Scalar1; |  162                 *outCoverage = SK_Scalar1; | 
|  163             } |  163             } | 
|  164             return true; |  164             return true; | 
|  165         } |  165         } | 
|  166         return stroke.getStyle() == SkStrokeRec::kStroke_Style && |  166         return stroke.getStyle() == SkStrokeRec::kStroke_Style && | 
|  167             SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
     ); |  167             SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
     ); | 
|  168     } |  168     } | 
|  169  |  169  | 
|  170 protected: |  170 protected: | 
|  171     /** |  171     /** | 
|  172      * Subclass overrides if it has any limitations of stenciling support. |  172      * Subclass overrides if it has any limitations of stenciling support. | 
|  173      */ |  173      */ | 
|  174     virtual StencilSupport onGetStencilSupport(const GrDrawTarget*, |  174     virtual StencilSupport onGetStencilSupport(const GrDrawTarget*, | 
|  175                                                const GrDrawState*, |  175                                                const GrPipelineBuilder*, | 
|  176                                                const SkPath&, |  176                                                const SkPath&, | 
|  177                                                const SkStrokeRec&) const { |  177                                                const SkStrokeRec&) const { | 
|  178         return kNoRestriction_StencilSupport; |  178         return kNoRestriction_StencilSupport; | 
|  179     } |  179     } | 
|  180  |  180  | 
|  181     /** |  181     /** | 
|  182      * Subclass implementation of drawPath() |  182      * Subclass implementation of drawPath() | 
|  183      */ |  183      */ | 
|  184     virtual bool onDrawPath(GrDrawTarget*, |  184     virtual bool onDrawPath(GrDrawTarget*, | 
|  185                             GrDrawState*, |  185                             GrPipelineBuilder*, | 
|  186                             GrColor, |  186                             GrColor, | 
|  187                             const SkMatrix& viewMatrix, |  187                             const SkMatrix& viewMatrix, | 
|  188                             const SkPath&, |  188                             const SkPath&, | 
|  189                             const SkStrokeRec&, |  189                             const SkStrokeRec&, | 
|  190                             bool antiAlias) = 0; |  190                             bool antiAlias) = 0; | 
|  191  |  191  | 
|  192     /** |  192     /** | 
|  193      * Subclass implementation of stencilPath(). Subclass must override iff it e
     ver returns |  193      * Subclass implementation of stencilPath(). Subclass must override iff it e
     ver returns | 
|  194      * kStencilOnly in onGetStencilSupport(). |  194      * kStencilOnly in onGetStencilSupport(). | 
|  195      */ |  195      */ | 
|  196     virtual void onStencilPath(GrDrawTarget* target, |  196     virtual void onStencilPath(GrDrawTarget* target, | 
|  197                                GrDrawState* drawState, |  197                                GrPipelineBuilder* pipelineBuilder, | 
|  198                                const SkMatrix& viewMatrix, |  198                                const SkMatrix& viewMatrix, | 
|  199                                const SkPath& path, |  199                                const SkPath& path, | 
|  200                                const SkStrokeRec& stroke) { |  200                                const SkStrokeRec& stroke) { | 
|  201         GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, |  201         GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, | 
|  202                                      kReplace_StencilOp, |  202                                      kReplace_StencilOp, | 
|  203                                      kReplace_StencilOp, |  203                                      kReplace_StencilOp, | 
|  204                                      kAlways_StencilFunc, |  204                                      kAlways_StencilFunc, | 
|  205                                      0xffff, |  205                                      0xffff, | 
|  206                                      0xffff, |  206                                      0xffff, | 
|  207                                      0xffff); |  207                                      0xffff); | 
|  208         drawState->setStencil(kIncrementStencil); |  208         pipelineBuilder->setStencil(kIncrementStencil); | 
|  209         drawState->setDisableColorXPFactory(); |  209         pipelineBuilder->setDisableColorXPFactory(); | 
|  210         this->drawPath(target, drawState, GrColor_WHITE, viewMatrix, path, strok
     e, false); |  210         this->drawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, path,
      stroke, false); | 
|  211     } |  211     } | 
|  212  |  212  | 
|  213     // Helper for getting the device bounds of a path. Inverse filled paths will
      have bounds set |  213     // Helper for getting the device bounds of a path. Inverse filled paths will
      have bounds set | 
|  214     // by devSize. Non-inverse path bounds will not necessarily be clipped to de
     vSize. |  214     // by devSize. Non-inverse path bounds will not necessarily be clipped to de
     vSize. | 
|  215     static void GetPathDevBounds(const SkPath& path, |  215     static void GetPathDevBounds(const SkPath& path, | 
|  216                                  int devW, |  216                                  int devW, | 
|  217                                  int devH, |  217                                  int devH, | 
|  218                                  const SkMatrix& matrix, |  218                                  const SkMatrix& matrix, | 
|  219                                  SkRect* bounds); |  219                                  SkRect* bounds); | 
|  220  |  220  | 
|  221     // Helper version that gets the dev width and height from a GrSurface. |  221     // Helper version that gets the dev width and height from a GrSurface. | 
|  222     static void GetPathDevBounds(const SkPath& path, |  222     static void GetPathDevBounds(const SkPath& path, | 
|  223                                  const GrSurface* device, |  223                                  const GrSurface* device, | 
|  224                                  const SkMatrix& matrix, |  224                                  const SkMatrix& matrix, | 
|  225                                  SkRect* bounds) { |  225                                  SkRect* bounds) { | 
|  226         GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
     ); |  226         GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
     ); | 
|  227     } |  227     } | 
|  228  |  228  | 
|  229 private: |  229 private: | 
|  230  |  230  | 
|  231     typedef SkRefCnt INHERITED; |  231     typedef SkRefCnt INHERITED; | 
|  232 }; |  232 }; | 
|  233  |  233  | 
|  234 #endif |  234 #endif | 
| OLD | NEW |