gfx/skia/trunk/src/gpu/GrPathRenderer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrPathRenderer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,213 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2011 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +#ifndef GrPathRenderer_DEFINED
    1.13 +#define GrPathRenderer_DEFINED
    1.14 +
    1.15 +#include "GrDrawTarget.h"
    1.16 +#include "GrPathRendererChain.h"
    1.17 +#include "GrStencil.h"
    1.18 +
    1.19 +#include "SkDrawProcs.h"
    1.20 +#include "SkStrokeRec.h"
    1.21 +#include "SkTArray.h"
    1.22 +
    1.23 +class SkPath;
    1.24 +
    1.25 +struct GrPoint;
    1.26 +
    1.27 +/**
    1.28 + *  Base class for drawing paths into a GrDrawTarget.
    1.29 + *
    1.30 + *  Derived classes can use stages GrPaint::kTotalStages through GrDrawState::kNumStages-1. The
    1.31 + *  stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and
    1.32 + *  filter masks).
    1.33 + */
    1.34 +class SK_API GrPathRenderer : public SkRefCnt {
    1.35 +public:
    1.36 +    SK_DECLARE_INST_COUNT(GrPathRenderer)
    1.37 +
    1.38 +    /**
    1.39 +     * This is called to install custom path renderers in every GrContext at create time. The
    1.40 +     * default implementation in GrCreatePathRenderer_none.cpp does not add any additional
    1.41 +     * renderers. Link against another implementation to install your own. The first added is the
    1.42 +     * most preferred path renderer, second is second most preferred, etc.
    1.43 +     *
    1.44 +     * @param context   the context that will use the path renderer
    1.45 +     * @param prChain   the chain to add path renderers to.
    1.46 +     */
    1.47 +    static void AddPathRenderers(GrContext* context, GrPathRendererChain* prChain);
    1.48 +
    1.49 +
    1.50 +    GrPathRenderer();
    1.51 +
    1.52 +    /**
    1.53 +     * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
    1.54 +     * the path renderer itself may require use of the stencil buffer. Also a path renderer may
    1.55 +     * use a GrEffect coverage stage that sets coverage to zero to eliminate pixels that are covered
    1.56 +     * by bounding geometry but outside the path. These exterior pixels would still be rendered into
    1.57 +     * the stencil.
    1.58 +     *
    1.59 +     * A GrPathRenderer can provide three levels of support for stenciling paths:
    1.60 +     * 1) kNoRestriction: This is the most general. The caller sets up the GrDrawState on the target
    1.61 +     *                    and calls drawPath(). The path is rendered exactly as the draw state
    1.62 +     *                    indicates including support for simultaneous color and stenciling with
    1.63 +     *                    arbitrary stenciling rules. Pixels partially covered by AA paths are
    1.64 +     *                    affected by the stencil settings.
    1.65 +     * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
    1.66 +     *                  simultaneously. The path renderer does support the stencilPath() function
    1.67 +     *                  which performs no color writes and writes a non-zero stencil value to pixels
    1.68 +     *                  covered by the path.
    1.69 +     * 3) kNoSupport: This path renderer cannot be used to stencil the path.
    1.70 +     */
    1.71 +    typedef GrPathRendererChain::StencilSupport StencilSupport;
    1.72 +    static const StencilSupport kNoSupport_StencilSupport =
    1.73 +        GrPathRendererChain::kNoSupport_StencilSupport;
    1.74 +    static const StencilSupport kStencilOnly_StencilSupport =
    1.75 +        GrPathRendererChain::kStencilOnly_StencilSupport;
    1.76 +    static const StencilSupport kNoRestriction_StencilSupport =
    1.77 +        GrPathRendererChain::kNoRestriction_StencilSupport;
    1.78 +
    1.79 +    /**
    1.80 +     * This function is to get the stencil support for a particular path. The path's fill must
    1.81 +     * not be an inverse type.
    1.82 +     *
    1.83 +     * @param target    target that the path will be rendered to
    1.84 +     * @param path      the path that will be drawn
    1.85 +     * @param stroke    the stroke information (width, join, cap).
    1.86 +     */
    1.87 +    StencilSupport getStencilSupport(const SkPath& path,
    1.88 +                                     const SkStrokeRec& stroke,
    1.89 +                                     const GrDrawTarget* target) const {
    1.90 +        SkASSERT(!path.isInverseFillType());
    1.91 +        return this->onGetStencilSupport(path, stroke, target);
    1.92 +    }
    1.93 +
    1.94 +    /**
    1.95 +     * Returns true if this path renderer is able to render the path. Returning false allows the
    1.96 +     * caller to fallback to another path renderer This function is called when searching for a path
    1.97 +     * renderer capable of rendering a path.
    1.98 +     *
    1.99 +     * @param path       The path to draw
   1.100 +     * @param stroke     The stroke information (width, join, cap)
   1.101 +     * @param target     The target that the path will be rendered to
   1.102 +     * @param antiAlias  True if anti-aliasing is required.
   1.103 +     *
   1.104 +     * @return  true if the path can be drawn by this object, false otherwise.
   1.105 +     */
   1.106 +    virtual bool canDrawPath(const SkPath& path,
   1.107 +                             const SkStrokeRec& rec,
   1.108 +                             const GrDrawTarget* target,
   1.109 +                             bool antiAlias) const = 0;
   1.110 +    /**
   1.111 +     * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
   1.112 +     * the subclass must respect the stencil settings of the target's draw state.
   1.113 +     *
   1.114 +     * @param path                  the path to draw.
   1.115 +     * @param stroke                the stroke information (width, join, cap)
   1.116 +     * @param target                target that the path will be rendered to
   1.117 +     * @param antiAlias             true if anti-aliasing is required.
   1.118 +     */
   1.119 +    bool drawPath(const SkPath& path,
   1.120 +                  const SkStrokeRec& stroke,
   1.121 +                  GrDrawTarget* target,
   1.122 +                  bool antiAlias) {
   1.123 +        SkASSERT(!path.isEmpty());
   1.124 +        SkASSERT(this->canDrawPath(path, stroke, target, antiAlias));
   1.125 +        SkASSERT(target->drawState()->getStencil().isDisabled() ||
   1.126 +                 kNoRestriction_StencilSupport == this->getStencilSupport(path, stroke, target));
   1.127 +        return this->onDrawPath(path, stroke, target, antiAlias);
   1.128 +    }
   1.129 +
   1.130 +    /**
   1.131 +     * Draws the path to the stencil buffer. Assume the writable stencil bits are already
   1.132 +     * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
   1.133 +     *
   1.134 +     * @param path                  the path to draw.
   1.135 +     * @param stroke                the stroke information (width, join, cap)
   1.136 +     * @param target                target that the path will be rendered to
   1.137 +     */
   1.138 +    void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) {
   1.139 +        SkASSERT(!path.isEmpty());
   1.140 +        SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target));
   1.141 +        this->onStencilPath(path, stroke, target);
   1.142 +    }
   1.143 +
   1.144 +    // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
   1.145 +    // If we can, we draw lots faster (raster device does this same test).
   1.146 +    static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const SkMatrix& matrix,
   1.147 +                                             SkScalar* outCoverage) {
   1.148 +        if (stroke.isHairlineStyle()) {
   1.149 +            if (NULL != outCoverage) {
   1.150 +                *outCoverage = SK_Scalar1;
   1.151 +            }
   1.152 +            return true;
   1.153 +        }
   1.154 +        return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
   1.155 +            SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
   1.156 +    }
   1.157 +
   1.158 +protected:
   1.159 +    /**
   1.160 +     * Subclass overrides if it has any limitations of stenciling support.
   1.161 +     */
   1.162 +    virtual StencilSupport onGetStencilSupport(const SkPath&,
   1.163 +                                               const SkStrokeRec&,
   1.164 +                                               const GrDrawTarget*) const {
   1.165 +        return kNoRestriction_StencilSupport;
   1.166 +    }
   1.167 +
   1.168 +    /**
   1.169 +     * Subclass implementation of drawPath()
   1.170 +     */
   1.171 +    virtual bool onDrawPath(const SkPath& path,
   1.172 +                            const SkStrokeRec& stroke,
   1.173 +                            GrDrawTarget* target,
   1.174 +                            bool antiAlias) = 0;
   1.175 +
   1.176 +    /**
   1.177 +     * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
   1.178 +     * kStencilOnly in onGetStencilSupport().
   1.179 +     */
   1.180 +    virtual void onStencilPath(const SkPath& path,  const SkStrokeRec& stroke, GrDrawTarget* target) {
   1.181 +        GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
   1.182 +        GrDrawState* drawState = target->drawState();
   1.183 +        GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
   1.184 +                                     kReplace_StencilOp,
   1.185 +                                     kReplace_StencilOp,
   1.186 +                                     kAlways_StencilFunc,
   1.187 +                                     0xffff,
   1.188 +                                     0xffff,
   1.189 +                                     0xffff);
   1.190 +        drawState->setStencil(kIncrementStencil);
   1.191 +        drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
   1.192 +        this->drawPath(path, stroke, target, false);
   1.193 +    }
   1.194 +
   1.195 +    // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
   1.196 +    // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
   1.197 +    static void GetPathDevBounds(const SkPath& path,
   1.198 +                                 int devW,
   1.199 +                                 int devH,
   1.200 +                                 const SkMatrix& matrix,
   1.201 +                                 SkRect* bounds);
   1.202 +
   1.203 +    // Helper version that gets the dev width and height from a GrSurface.
   1.204 +    static void GetPathDevBounds(const SkPath& path,
   1.205 +                                 const GrSurface* device,
   1.206 +                                 const SkMatrix& matrix,
   1.207 +                                 SkRect* bounds) {
   1.208 +        GetPathDevBounds(path, device->width(), device->height(), matrix, bounds);
   1.209 +    }
   1.210 +
   1.211 +private:
   1.212 +
   1.213 +    typedef SkRefCnt INHERITED;
   1.214 +};
   1.215 +
   1.216 +#endif

mercurial