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