LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrPathRenderer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 78 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2011 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef GrPathRenderer_DEFINED
       9             : #define GrPathRenderer_DEFINED
      10             : 
      11             : #include "GrCaps.h"
      12             : #include "GrRenderTargetContext.h"
      13             : #include "GrPaint.h"
      14             : #include "GrResourceProvider.h"
      15             : #include "GrShape.h"
      16             : 
      17             : #include "SkDrawProcs.h"
      18             : #include "SkTArray.h"
      19             : 
      20             : class SkPath;
      21             : class GrFixedClip;
      22             : struct GrPoint;
      23             : 
      24             : /**
      25             :  *  Base class for drawing paths into a GrOpList.
      26             :  *
      27             :  *  Derived classes can use stages GrPaint::kTotalStages through GrPipelineBuilder::kNumStages-1.
      28             :  *  The stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and
      29             :  *  filter masks).
      30             :  */
      31           0 : class SK_API GrPathRenderer : public SkRefCnt {
      32             : public:
      33             :     GrPathRenderer();
      34             : 
      35             :     /**
      36             :      * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
      37             :      * the path renderer itself may require use of the stencil buffer. Also a path renderer may
      38             :      * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are
      39             :      * covered by bounding geometry but outside the path. These exterior pixels would still be
      40             :      * rendered into the stencil.
      41             :      *
      42             :      * A GrPathRenderer can provide three levels of support for stenciling paths:
      43             :      * 1) kNoRestriction: This is the most general. The caller sets up the GrPipelineBuilder on the
      44             :      *                    target and calls drawPath(). The path is rendered exactly as the draw
      45             :      *                    state indicates including support for simultaneous color and stenciling
      46             :      *                    with arbitrary stenciling rules. Pixels partially covered by AA paths are
      47             :      *                    affected by the stencil settings.
      48             :      * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
      49             :      *                  simultaneously. The path renderer does support the stencilPath() function
      50             :      *                  which performs no color writes and writes a non-zero stencil value to pixels
      51             :      *                  covered by the path.
      52             :      * 3) kNoSupport: This path renderer cannot be used to stencil the path.
      53             :      */
      54             :     enum StencilSupport {
      55             :         kNoSupport_StencilSupport,
      56             :         kStencilOnly_StencilSupport,
      57             :         kNoRestriction_StencilSupport,
      58             :     };
      59             : 
      60             :     /**
      61             :      * This function is to get the stencil support for a particular path. The path's fill must
      62             :      * not be an inverse type. The path will always be filled and not stroked.
      63             :      *
      64             :      * @param shape   the shape that will be drawn. Must be simple fill styled and non-inverse
      65             :      *                filled.
      66             :      */
      67           0 :     StencilSupport getStencilSupport(const GrShape& shape) const {
      68           0 :         SkDEBUGCODE(SkPath path;)
      69           0 :         SkDEBUGCODE(shape.asPath(&path);)
      70           0 :         SkASSERT(shape.style().isSimpleFill());
      71           0 :         SkASSERT(!path.isInverseFillType());
      72           0 :         return this->onGetStencilSupport(shape);
      73             :     }
      74             : 
      75             :     /** Args to canDrawPath()
      76             :      *
      77             :      * fShaderCaps       The shader caps
      78             :      * fPipelineBuilder  The pipelineBuilder
      79             :      * fViewMatrix       The viewMatrix
      80             :      * fShape            The shape to draw
      81             :      * fAntiAlias        The type of anti aliasing required.
      82             :      */
      83             :     struct CanDrawPathArgs {
      84             :         const GrShaderCaps*         fShaderCaps;
      85             :         const SkMatrix*             fViewMatrix;
      86             :         const GrShape*              fShape;
      87             :         GrAAType                    fAAType;
      88             : 
      89             :         // These next two are only used by GrStencilAndCoverPathRenderer
      90             :         bool                        fHasUserStencilSettings;
      91             : 
      92             : #ifdef SK_DEBUG
      93           0 :         void validate() const {
      94           0 :             SkASSERT(fShaderCaps);
      95           0 :             SkASSERT(fViewMatrix);
      96           0 :             SkASSERT(fShape);
      97           0 :         }
      98             : #endif
      99             :     };
     100             : 
     101             :     /**
     102             :      * Returns true if this path renderer is able to render the path. Returning false allows the
     103             :      * caller to fallback to another path renderer This function is called when searching for a path
     104             :      * renderer capable of rendering a path.
     105             :      *
     106             :      * @return  true if the path can be drawn by this object, false otherwise.
     107             :      */
     108           0 :     bool canDrawPath(const CanDrawPathArgs& args) const {
     109           0 :         SkDEBUGCODE(args.validate();)
     110           0 :         return this->onCanDrawPath(args);
     111             :     }
     112             : 
     113             :     /**
     114             :      * Args to drawPath()
     115             :      *
     116             :      * fTarget                The target that the path will be rendered to
     117             :      * fResourceProvider      The resource provider for creating gpu resources to render the path
     118             :      * fPipelineBuilder       The pipelineBuilder
     119             :      * fClip                  The clip
     120             :      * fColor                 Color to render with
     121             :      * fViewMatrix            The viewMatrix
     122             :      * fShape                 The shape to draw
     123             :      * fAAtype                true if anti-aliasing is required.
     124             :      * fGammaCorrect          true if gamma-correct rendering is to be used.
     125             :      */
     126             :     struct DrawPathArgs {
     127             :         GrContext*                   fContext;
     128             :         GrPaint&&                    fPaint;
     129             :         const GrUserStencilSettings* fUserStencilSettings;
     130             :         GrRenderTargetContext*       fRenderTargetContext;
     131             :         const GrClip*                fClip;
     132             :         const SkMatrix*              fViewMatrix;
     133             :         const GrShape*               fShape;
     134             :         GrAAType                     fAAType;
     135             :         bool                         fGammaCorrect;
     136             : #ifdef SK_DEBUG
     137           0 :         void validate() const {
     138           0 :             SkASSERT(fContext);
     139           0 :             SkASSERT(fUserStencilSettings);
     140           0 :             SkASSERT(fRenderTargetContext);
     141           0 :             SkASSERT(fClip);
     142           0 :             SkASSERT(fViewMatrix);
     143           0 :             SkASSERT(fShape);
     144           0 :         }
     145             : #endif
     146             :     };
     147             : 
     148             :     /**
     149             :      * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
     150             :      * the subclass must respect the stencil settings of the GrPipelineBuilder.
     151             :      */
     152           0 :     bool drawPath(const DrawPathArgs& args) {
     153           0 :         SkDEBUGCODE(args.validate();)
     154             : #ifdef SK_DEBUG
     155             :         CanDrawPathArgs canArgs;
     156           0 :         canArgs.fShaderCaps = args.fContext->caps()->shaderCaps();
     157           0 :         canArgs.fViewMatrix = args.fViewMatrix;
     158           0 :         canArgs.fShape = args.fShape;
     159           0 :         canArgs.fAAType = args.fAAType;
     160             : 
     161           0 :         canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
     162           0 :         SkASSERT(!(canArgs.fAAType == GrAAType::kMSAA &&
     163             :                    !args.fRenderTargetContext->isUnifiedMultisampled()));
     164           0 :         SkASSERT(!(canArgs.fAAType == GrAAType::kMixedSamples &&
     165             :                    !args.fRenderTargetContext->isStencilBufferMultisampled()));
     166           0 :         SkASSERT(this->canDrawPath(canArgs));
     167           0 :         if (!args.fUserStencilSettings->isUnused()) {
     168           0 :             SkPath path;
     169           0 :             args.fShape->asPath(&path);
     170           0 :             SkASSERT(args.fShape->style().isSimpleFill());
     171           0 :             SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
     172             :         }
     173             : #endif
     174           0 :         return this->onDrawPath(args);
     175             :     }
     176             : 
     177             :     /* Args to stencilPath().
     178             :      *
     179             :      * fResourceProvider      The resource provider for creating gpu resources to render the path
     180             :      * fRenderTargetContext   The target of the draws
     181             :      * fViewMatrix            Matrix applied to the path.
     182             :      * fPath                  The path to draw.
     183             :      * fAAType                The type of AA, cannot be kCoverage.
     184             :      */
     185             :     struct StencilPathArgs {
     186             :         GrContext*             fContext;
     187             :         GrRenderTargetContext* fRenderTargetContext;
     188             :         const GrClip*          fClip;
     189             :         const SkMatrix*        fViewMatrix;
     190             :         GrAAType               fAAType;
     191             :         const GrShape*         fShape;
     192             : 
     193             : #ifdef SK_DEBUG
     194           0 :         void validate() const {
     195           0 :             SkASSERT(fContext);
     196           0 :             SkASSERT(fRenderTargetContext);
     197           0 :             SkASSERT(fViewMatrix);
     198           0 :             SkASSERT(fShape);
     199           0 :             SkASSERT(fShape->style().isSimpleFill());
     200           0 :             SkASSERT(GrAAType::kCoverage != fAAType);
     201           0 :             SkPath path;
     202           0 :             fShape->asPath(&path);
     203           0 :             SkASSERT(!path.isInverseFillType());
     204           0 :         }
     205             : #endif
     206             :     };
     207             : 
     208             :     /**
     209             :      * Draws the path to the stencil buffer. Assume the writable stencil bits are already
     210             :      * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
     211             :      */
     212           0 :     void stencilPath(const StencilPathArgs& args) {
     213           0 :         SkDEBUGCODE(args.validate();)
     214           0 :         SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
     215           0 :         this->onStencilPath(args);
     216           0 :     }
     217             : 
     218             :     // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
     219             :     // If we can, we draw lots faster (raster device does this same test).
     220           0 :     static bool IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix,
     221             :                                              SkScalar* outCoverage) {
     222           0 :         if (style.pathEffect()) {
     223           0 :             return false;
     224             :         }
     225           0 :         const SkStrokeRec& stroke = style.strokeRec();
     226           0 :         if (stroke.isHairlineStyle()) {
     227           0 :             if (outCoverage) {
     228           0 :                 *outCoverage = SK_Scalar1;
     229             :             }
     230           0 :             return true;
     231             :         }
     232           0 :         return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
     233           0 :             SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
     234             :     }
     235             : 
     236             : protected:
     237             :     // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
     238             :     // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
     239             :     static void GetPathDevBounds(const SkPath& path,
     240             :                                  int devW,
     241             :                                  int devH,
     242             :                                  const SkMatrix& matrix,
     243             :                                  SkRect* bounds);
     244             : 
     245             : private:
     246             :     /**
     247             :      * Subclass overrides if it has any limitations of stenciling support.
     248             :      */
     249           0 :     virtual StencilSupport onGetStencilSupport(const GrShape&) const {
     250           0 :         return kNoRestriction_StencilSupport;
     251             :     }
     252             : 
     253             :     /**
     254             :      * Subclass implementation of drawPath()
     255             :      */
     256             :     virtual bool onDrawPath(const DrawPathArgs& args) = 0;
     257             : 
     258             :     /**
     259             :      * Subclass implementation of canDrawPath()
     260             :      */
     261             :     virtual bool onCanDrawPath(const CanDrawPathArgs& args) const = 0;
     262             : 
     263             :     /**
     264             :      * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
     265             :      * kStencilOnly in onGetStencilSupport().
     266             :      */
     267           0 :     virtual void onStencilPath(const StencilPathArgs& args) {
     268             :         static constexpr GrUserStencilSettings kIncrementStencil(
     269             :             GrUserStencilSettings::StaticInit<
     270             :                  0xffff,
     271             :                  GrUserStencilTest::kAlways,
     272             :                  0xffff,
     273             :                  GrUserStencilOp::kReplace,
     274             :                  GrUserStencilOp::kReplace,
     275             :                  0xffff>()
     276             :         );
     277             : 
     278           0 :         GrPaint paint;
     279             : 
     280           0 :         DrawPathArgs drawArgs{args.fContext,
     281           0 :                               std::move(paint),
     282             :                               &kIncrementStencil,
     283           0 :                               args.fRenderTargetContext,
     284             :                               nullptr,  // clip
     285           0 :                               args.fViewMatrix,
     286           0 :                               args.fShape,
     287           0 :                               args.fAAType,
     288           0 :                               false};
     289           0 :         this->drawPath(drawArgs);
     290           0 :     }
     291             : 
     292             :     typedef SkRefCnt INHERITED;
     293             : };
     294             : 
     295             : #endif

Generated by: LCOV version 1.13