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: ~GrPathRendering()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 PathTransformSize(PathTransformType type)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 { StencilPathArgsStencilPathArgs132 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 stencilPath(const StencilPathArgs & args,const GrPath * path)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 { DrawPathArgsDrawPathArgs156 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 drawPath(const DrawPathArgs & args,const GrPath * path)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 drawPaths(const DrawPathArgs & args,const GrPathRange * pathRange,const void * indices,PathIndexType indexType,const float transformValues[],PathTransformType transformType,int count)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: GrPathRendering(GrGpu * gpu)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