Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef GrPathRenderer_DEFINED
     11 #define GrPathRenderer_DEFINED
     12 
     13 #include "GrDrawTarget.h"
     14 #include "GrPathRendererChain.h"
     15 #include "GrStencil.h"
     16 
     17 #include "SkStrokeRec.h"
     18 #include "SkTArray.h"
     19 
     20 class SkPath;
     21 
     22 struct GrPoint;
     23 
     24 /**
     25  *  Base class for drawing paths into a GrDrawTarget.
     26  *
     27  *  Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kNumStages-1. The
     28  *  stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and
     29  *  filter masks).
     30  */
     31 class GR_API GrPathRenderer : public GrRefCnt {
     32 public:
     33     SK_DECLARE_INST_COUNT(GrPathRenderer)
     34 
     35     /**
     36      * This is called to install custom path renderers in every GrContext at create time. The
     37      * default implementation in GrCreatePathRenderer_none.cpp does not add any additional
     38      * renderers. Link against another implementation to install your own. The first added is the
     39      * most preferred path renderer, second is second most preferred, etc.
     40      *
     41      * @param context   the context that will use the path renderer
     42      * @param prChain   the chain to add path renderers to.
     43      */
     44     static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChain);
     45 
     46 
     47     GrPathRenderer();
     48 
     49     /**
     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 path renderer may
     52      * use a GrEffect coverage stage that sets coverage to zero to eliminate pixels that are covered
     53      * by bounding geometry but outside the path. These exterior pixels would still be rendered into
     54      * the stencil.
     55      *
     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 GrDrawState on the target
     58      *                    and calls drawPath(). The path is rendered exactly as the draw state
     59      *                    indicates including support for simultaneous color and stenciling with
     60      *                    arbitrary stenciling rules. Pixels partially covered by AA paths are
     61      *                    affected by the stencil settings.
     62      * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
     63      *                  simultaneously. The path renderer does support the stencilPath() function
     64      *                  which performs no color writes and writes a non-zero stencil value to pixels
     65      *                  covered by the path.
     66      * 3) kNoSupport: This path renderer cannot be used to stencil the path.
     67      */
     68     typedef GrPathRendererChain::StencilSupport StencilSupport;
     69     static const StencilSupport kNoSupport_StencilSupport =
     70         GrPathRendererChain::kNoSupport_StencilSupport;
     71     static const StencilSupport kStencilOnly_StencilSupport =
     72         GrPathRendererChain::kStencilOnly_StencilSupport;
     73     static const StencilSupport kNoRestriction_StencilSupport =
     74         GrPathRendererChain::kNoRestriction_StencilSupport;
     75 
     76     /**
     77      * This function is to get the stencil support for a particular path. The path's fill must
     78      * not be an inverse type.
     79      *
     80      * @param target    target that the path will be rendered to
     81      * @param path      the path that will be drawn
     82      * @param stroke    the stroke information (width, join, cap).
     83      */
     84     StencilSupport getStencilSupport(const SkPath& path,
     85                                      const SkStrokeRec& stroke,
     86                                      const GrDrawTarget* target) const {
     87         GrAssert(!path.isInverseFillType());
     88         return this->onGetStencilSupport(path, stroke, target);
     89     }
     90 
     91     /**
     92      * Returns true if this path renderer is able to render the path. Returning false allows the
     93      * caller to fallback to another path renderer This function is called when searching for a path
     94      * renderer capable of rendering a path.
     95      *
     96      * @param path       The path to draw
     97      * @param stroke     The stroke information (width, join, cap)
     98      * @param target     The target that the path will be rendered to
     99      * @param antiAlias  True if anti-aliasing is required.
    100      *
    101      * @return  true if the path can be drawn by this object, false otherwise.
    102      */
    103     virtual bool canDrawPath(const SkPath& path,
    104                              const SkStrokeRec& rec,
    105                              const GrDrawTarget* target,
    106                              bool antiAlias) const = 0;
    107     /**
    108      * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
    109      * the subclass must respect the stencil settings of the target's draw state.
    110      *
    111      * @param path                  the path to draw.
    112      * @param stroke                the stroke information (width, join, cap)
    113      * @param target                target that the path will be rendered to
    114      * @param antiAlias             true if anti-aliasing is required.
    115      */
    116     bool drawPath(const SkPath& path,
    117                   const SkStrokeRec& stroke,
    118                   GrDrawTarget* target,
    119                   bool antiAlias) {
    120         GrAssert(this->canDrawPath(path, stroke, target, antiAlias));
    121         GrAssert(target->drawState()->getStencil().isDisabled() ||
    122                  kNoRestriction_StencilSupport == this->getStencilSupport(path, stroke, target));
    123         return this->onDrawPath(path, stroke, target, antiAlias);
    124     }
    125 
    126     /**
    127      * Draws the path to the stencil buffer. Assume the writable stencil bits are already
    128      * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
    129      *
    130      * @param path                  the path to draw.
    131      * @param stroke                the stroke information (width, join, cap)
    132      * @param target                target that the path will be rendered to
    133      */
    134     void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) {
    135         GrAssert(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target));
    136         this->onStencilPath(path, stroke, target);
    137     }
    138 
    139 protected:
    140     /**
    141      * Subclass overrides if it has any limitations of stenciling support.
    142      */
    143     virtual StencilSupport onGetStencilSupport(const SkPath&,
    144                                                const SkStrokeRec&,
    145                                                const GrDrawTarget*) const {
    146         return kNoRestriction_StencilSupport;
    147     }
    148 
    149     /**
    150      * Subclass implementation of drawPath()
    151      */
    152     virtual bool onDrawPath(const SkPath& path,
    153                             const SkStrokeRec& stroke,
    154                             GrDrawTarget* target,
    155                             bool antiAlias) = 0;
    156 
    157     /**
    158      * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
    159      * kStencilOnly in onGetStencilSupport().
    160      */
    161     virtual void onStencilPath(const SkPath& path,  const SkStrokeRec& stroke, GrDrawTarget* target) {
    162         GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
    163         GrDrawState* drawState = target->drawState();
    164         GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
    165                                      kReplace_StencilOp,
    166                                      kReplace_StencilOp,
    167                                      kAlways_StencilFunc,
    168                                      0xffff,
    169                                      0xffff,
    170                                      0xffff);
    171         drawState->setStencil(kIncrementStencil);
    172         drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
    173         this->drawPath(path, stroke, target, false);
    174     }
    175 
    176 private:
    177 
    178     typedef GrRefCnt INHERITED;
    179 };
    180 
    181 #endif
    182