Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2014 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 GrPathRendering_DEFINED
      9 #define GrPathRendering_DEFINED
     10 
     11 #include "SkPath.h"
     12 #include "GrGpu.h"
     13 #include "GrPathRange.h"
     14 #include "GrPipeline.h"
     15 
     16 class SkDescriptor;
     17 class SkTypeface;
     18 class GrPath;
     19 class GrStencilSettings;
     20 class GrStyle;
     21 
     22 /**
     23  * Abstract class wrapping HW path rendering API.
     24  *
     25  * The subclasses of this class use the possible HW API to render paths (as opposed to path
     26  * rendering implemented in Skia on top of a "3d" HW API).
     27  * The subclasses hold the global state needed to render paths, including shadow of the global HW
     28  * API state. Similar to GrGpu.
     29  *
     30  * It is expected that the lifetimes of GrGpuXX and GrXXPathRendering are the same. The call context
     31  * interface (eg.  * the concrete instance of GrGpu subclass) should be provided to the instance
     32  * during construction.
     33  */
     34 class GrPathRendering {
     35 public:
     36     virtual ~GrPathRendering() { }
     37 
     38     typedef GrPathRange::PathIndexType PathIndexType;
     39 
     40     enum PathTransformType {
     41         kNone_PathTransformType,        //!< []
     42         kTranslateX_PathTransformType,  //!< [kMTransX]
     43         kTranslateY_PathTransformType,  //!< [kMTransY]
     44         kTranslate_PathTransformType,   //!< [kMTransX, kMTransY]
     45         kAffine_PathTransformType,      //!< [kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY]
     46 
     47         kLast_PathTransformType = kAffine_PathTransformType
     48     };
     49 
     50     static inline int PathTransformSize(PathTransformType type) {
     51         switch (type) {
     52             case kNone_PathTransformType:
     53                 return 0;
     54             case kTranslateX_PathTransformType:
     55             case kTranslateY_PathTransformType:
     56                 return 1;
     57             case kTranslate_PathTransformType:
     58                 return 2;
     59             case kAffine_PathTransformType:
     60                 return 6;
     61 
     62             default:
     63                 SkFAIL("Unknown path transform type");
     64                 return 0;
     65         }
     66     }
     67 
     68     // No native support for inverse at this time
     69     enum FillType {
     70         /** Specifies that "inside" is computed by a non-zero sum of signed
     71             edge crossings
     72         */
     73         kWinding_FillType,
     74         /** Specifies that "inside" is computed by an odd number of edge
     75             crossings
     76         */
     77         kEvenOdd_FillType,
     78     };
     79 
     80     static const GrUserStencilSettings& GetStencilPassSettings(FillType);
     81 
     82     /**
     83      * Creates a new gpu path, based on the specified path and stroke and returns it.
     84      * The caller owns a ref on the returned path which must be balanced by a call to unref.
     85      *
     86      * @param SkPath    the geometry.
     87      * @param GrStyle   the style applied to the path. Styles with non-dash path effects are not
     88      *                  allowed.
     89      * @return a new GPU path object.
     90      */
     91     virtual GrPath* createPath(const SkPath&, const GrStyle&) = 0;
     92 
     93     /**
     94      * Creates a range of gpu paths with a common style. The caller owns a ref on the
     95      * returned path range which must be balanced by a call to unref.
     96      *
     97      * @param PathGenerator class that generates SkPath objects for each path in the range.
     98      * @param GrStyle   the common style applied to each path in the range. Styles with non-dash
     99      *                  path effects are not allowed.
    100      * @return a new path range.
    101      */
    102     virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStyle&) = 0;
    103 
    104     /**
    105      * Creates a range of glyph paths, indexed by glyph id. The glyphs will have an
    106      * inverted y-direction in order to match the raw font path data. The caller owns
    107      * a ref on the returned path range which must be balanced by a call to unref.
    108      *
    109      * @param SkTypeface   Typeface that defines the glyphs.
    110      *                     If null, the default typeface will be used.
    111      *
    112      * @param SkDescriptor Additional font configuration that specifies the font's size,
    113      *                     stroke, and other flags. This will generally come from an
    114      *                     SkGlyphCache.
    115      *
    116      *                     It is recommended to leave this value null when possible, in
    117      *                     which case the glyphs will be loaded directly from the font's
    118      *                     raw path data and sized at SkPaint::kCanonicalTextSizeForPaths.
    119      *                     This will result in less memory usage and more efficient paths.
    120      *
    121      *                     If non-null, the glyph paths will match the font descriptor,
    122      *                     including with the stroke information baked directly into
    123      *                     the outlines.
    124      *
    125      * @param GrStyle      Common style that the GPU will apply to every path. Note that
    126      *                     if the glyph outlines contain baked-in styles from the font
    127      *                     descriptor, the GPU style will be applied on top of those
    128      *                     outlines.
    129      *
    130      * @return a new path range populated with glyphs.
    131      */
    132     GrPathRange* createGlyphs(const SkTypeface*, const SkScalerContextEffects&,
    133                               const SkDescriptor*, const GrStyle&);
    134 
    135     /** None of these params are optional, pointers used just to avoid making copies. */
    136     struct StencilPathArgs {
    137         StencilPathArgs(bool useHWAA,
    138                         GrRenderTarget* renderTarget,
    139                         const SkMatrix* viewMatrix,
    140                         const GrScissorState* scissor,
    141                         const GrStencilSettings* stencil)
    142             : fUseHWAA(useHWAA)
    143             , fRenderTarget(renderTarget)
    144             , fViewMatrix(viewMatrix)
    145             , fScissor(scissor)
    146             , fStencil(stencil) {
    147         }
    148         bool fUseHWAA;
    149         GrRenderTarget* fRenderTarget;
    150         const SkMatrix* fViewMatrix;
    151         const GrScissorState* fScissor;
    152         const GrStencilSettings* fStencil;
    153     };
    154 
    155     void stencilPath(const StencilPathArgs& args, const GrPath* path) {
    156         fGpu->handleDirtyContext();
    157         this->onStencilPath(args, path);
    158     }
    159 
    160     void drawPath(const GrPipeline& pipeline,
    161                   const GrPrimitiveProcessor& primProc,
    162                   const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
    163                   const GrPath* path) {
    164         fGpu->handleDirtyContext();
    165         if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
    166             fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
    167         }
    168         this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
    169     }
    170 
    171     void drawPaths(const GrPipeline& pipeline,
    172                    const GrPrimitiveProcessor& primProc,
    173                    const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
    174                    const GrPathRange* pathRange,
    175                    const void* indices,
    176                    PathIndexType indexType,
    177                    const float transformValues[],
    178                    PathTransformType transformType,
    179                    int count) {
    180         fGpu->handleDirtyContext();
    181         if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
    182             fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
    183         }
    184 #ifdef SK_DEBUG
    185         pathRange->assertPathsLoaded(indices, indexType, count);
    186 #endif
    187         this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
    188                           transformValues, transformType, count);
    189     }
    190 
    191 protected:
    192     GrPathRendering(GrGpu* gpu)
    193         : fGpu(gpu) {
    194     }
    195     virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
    196     virtual void onDrawPath(const GrPipeline&,
    197                             const GrPrimitiveProcessor&,
    198                             const GrStencilSettings&,
    199                             const GrPath*) = 0;
    200     virtual void onDrawPaths(const GrPipeline&,
    201                              const GrPrimitiveProcessor&,
    202                              const GrStencilSettings&,
    203                              const GrPathRange*,
    204                              const void* indices,
    205                              PathIndexType,
    206                              const float transformValues[],
    207                              PathTransformType,
    208                              int count) = 0;
    209 
    210     GrGpu* fGpu;
    211 private:
    212     GrPathRendering& operator=(const GrPathRendering&);
    213 };
    214 
    215 #endif
    216