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 GrStrokeInfo;
     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     /**
     81      * Creates a new gpu path, based on the specified path and stroke and returns it.
     82      * The caller owns a ref on the returned path which must be balanced by a call to unref.
     83      *
     84      * @param skPath the path geometry.
     85      * @param stroke the path stroke.
     86      * @return a new path.
     87      */
     88     virtual GrPath* createPath(const SkPath&, const GrStrokeInfo&) = 0;
     89 
     90     /**
     91      * Creates a range of gpu paths with a common stroke. The caller owns a ref on the
     92      * returned path range which must be balanced by a call to unref.
     93      *
     94      * @param PathGenerator class that generates SkPath objects for each path in the range.
     95      * @param GrStrokeInfo   the common stroke applied to each path in the range.
     96      * @return a new path range.
     97      */
     98     virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStrokeInfo&) = 0;
     99 
    100     /**
    101      * Creates a range of glyph paths, indexed by glyph id. The glyphs will have an
    102      * inverted y-direction in order to match the raw font path data. The caller owns
    103      * a ref on the returned path range which must be balanced by a call to unref.
    104      *
    105      * @param SkTypeface   Typeface that defines the glyphs.
    106      *                     If null, the default typeface will be used.
    107      *
    108      * @param SkDescriptor Additional font configuration that specifies the font's size,
    109      *                     stroke, and other flags. This will generally come from an
    110      *                     SkGlyphCache.
    111      *
    112      *                     It is recommended to leave this value null when possible, in
    113      *                     which case the glyphs will be loaded directly from the font's
    114      *                     raw path data and sized at SkPaint::kCanonicalTextSizeForPaths.
    115      *                     This will result in less memory usage and more efficient paths.
    116      *
    117      *                     If non-null, the glyph paths will match the font descriptor,
    118      *                     including with the stroke information baked directly into
    119      *                     the outlines.
    120      *
    121      * @param GrStrokeInfo Common stroke that the GPU will apply to every path. Note that
    122      *                     if the glyph outlines contain baked-in strokes from the font
    123      *                     descriptor, the GPU stroke will be applied on top of those
    124      *                     outlines.
    125      *
    126      * @return a new path range populated with glyphs.
    127      */
    128     GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const GrStrokeInfo&);
    129 
    130     /** None of these params are optional, pointers used just to avoid making copies. */
    131     struct StencilPathArgs {
    132         StencilPathArgs(bool useHWAA,
    133                         GrRenderTarget* renderTarget,
    134                         const SkMatrix* viewMatrix,
    135                         const GrScissorState* scissor,
    136                         const GrStencilSettings* stencil)
    137             : fUseHWAA(useHWAA)
    138             , fRenderTarget(renderTarget)
    139             , fViewMatrix(viewMatrix)
    140             , fScissor(scissor)
    141             , fStencil(stencil) {
    142         }
    143         bool fUseHWAA;
    144         GrRenderTarget* fRenderTarget;
    145         const SkMatrix* fViewMatrix;
    146         const GrScissorState* fScissor;
    147         const GrStencilSettings* fStencil;
    148     };
    149 
    150     void stencilPath(const StencilPathArgs& args, const GrPath* path) {
    151         fGpu->handleDirtyContext();
    152         this->onStencilPath(args, path);
    153     }
    154 
    155     struct DrawPathArgs : public GrGpu::DrawArgs {
    156         DrawPathArgs(const GrPrimitiveProcessor* primProc,
    157                      const GrPipeline* pipeline,
    158                      const GrProgramDesc* desc,
    159                      const GrStencilSettings* stencil)
    160             : DrawArgs(primProc, pipeline, desc)
    161             , fStencil(stencil) {
    162         }
    163 
    164         const GrStencilSettings* fStencil;
    165     };
    166 
    167     void drawPath(const DrawPathArgs& args, const GrPath* path) {
    168         fGpu->handleDirtyContext();
    169         if (GrXferBarrierType barrierType = args.fPipeline->xferBarrierType(*fGpu->caps())) {
    170             fGpu->xferBarrier(args.fPipeline->getRenderTarget(), barrierType);
    171         }
    172         this->onDrawPath(args, path);
    173     }
    174 
    175     void drawPaths(const DrawPathArgs& args, const GrPathRange* pathRange, const void* indices,
    176                    PathIndexType indexType, const float transformValues[],
    177                    PathTransformType transformType, int count) {
    178         fGpu->handleDirtyContext();
    179         if (GrXferBarrierType barrierType = args.fPipeline->xferBarrierType(*fGpu->caps())) {
    180             fGpu->xferBarrier(args.fPipeline->getRenderTarget(), barrierType);
    181         }
    182 #ifdef SK_DEBUG
    183         pathRange->assertPathsLoaded(indices, indexType, count);
    184 #endif
    185         this->onDrawPaths(args, pathRange, indices, indexType, transformValues, transformType,
    186                           count);
    187     }
    188 
    189 protected:
    190     GrPathRendering(GrGpu* gpu)
    191         : fGpu(gpu) {
    192     }
    193     virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
    194     virtual void onDrawPath(const DrawPathArgs&, const GrPath*) = 0;
    195     virtual void onDrawPaths(const DrawPathArgs&, const GrPathRange*, const void*, PathIndexType,
    196                              const float[], PathTransformType, int) = 0;
    197 
    198     GrGpu* fGpu;
    199 private:
    200     GrPathRendering& operator=(const GrPathRendering&);
    201 };
    202 
    203 #endif
    204