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 PathRenderer_DEFINED 9 #define PathRenderer_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/private/GrTypesPriv.h" 13 #include "include/private/SkTArray.h" 14 15 class GrCaps; 16 class GrClip; 17 class GrHardClip; 18 class GrPaint; 19 class GrRecordingContext; 20 class GrRenderTargetProxy; 21 class GrStyledShape; 22 class GrStyle; 23 struct GrUserStencilSettings; 24 struct SkIRect; 25 class SkMatrix; 26 class SkPath; 27 class SkSurfaceProps; 28 29 namespace skgpu::v1 { 30 31 class SurfaceDrawContext; 32 33 /** 34 * Base class for drawing paths into a OpsTask. 35 */ 36 class PathRenderer : public SkRefCnt { 37 public: 38 PathRenderer() = default; 39 40 virtual const char* name() const = 0; 41 42 /** 43 * A caller may wish to use a path renderer to draw a path into the stencil buffer. However, 44 * the path renderer itself may require use of the stencil buffer. Also a path renderer may 45 * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are 46 * covered by bounding geometry but outside the path. These exterior pixels would still be 47 * rendered into the stencil. 48 * 49 * A PathRenderer can provide three levels of support for stenciling paths: 50 * 1) kNoRestriction: This is the most general. The caller passes a GrPaint and calls drawPath(). 51 * The path is rendered exactly as the draw state indicates including support 52 * for simultaneous color and stenciling with arbitrary stenciling rules. 53 * Pixels partially covered by AA paths are affected by the stencil settings. 54 * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil 55 * simultaneously. The path renderer does support the stencilPath() function 56 * which performs no color writes and writes a non-zero stencil value to pixels 57 * covered by the path. 58 * 3) kNoSupport: This path renderer cannot be used to stencil the path. 59 */ 60 enum StencilSupport { 61 kNoSupport_StencilSupport, 62 kStencilOnly_StencilSupport, 63 kNoRestriction_StencilSupport, 64 }; 65 66 /** 67 * This function is to get the stencil support for a particular path. The path's fill must 68 * not be an inverse type. The path will always be filled and not stroked. 69 * 70 * @param shape the shape that will be drawn. Must be simple fill styled and non-inverse 71 * filled. 72 */ 73 StencilSupport getStencilSupport(const GrStyledShape& shape) const; 74 75 enum class CanDrawPath { 76 kNo, 77 kAsBackup, // i.e. This renderer is better than SW fallback if no others can draw the path. 78 kYes 79 }; 80 81 struct CanDrawPathArgs { 82 SkDEBUGCODE(CanDrawPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation. 83 84 const GrCaps* fCaps; 85 const GrRenderTargetProxy* fProxy; 86 const SkIRect* fClipConservativeBounds; 87 const SkMatrix* fViewMatrix; 88 const GrStyledShape* fShape; 89 const GrPaint* fPaint; 90 const SkSurfaceProps* fSurfaceProps; 91 GrAAType fAAType; 92 93 // This is only used by TessellationPathRenderer 94 bool fHasUserStencilSettings; 95 96 #ifdef SK_DEBUG validateCanDrawPathArgs97 void validate() const { 98 SkASSERT(fCaps); 99 SkASSERT(fProxy); 100 SkASSERT(fClipConservativeBounds); 101 SkASSERT(fViewMatrix); 102 SkASSERT(fShape); 103 SkASSERT(fSurfaceProps); 104 } 105 #endif 106 }; 107 108 /** 109 * Returns how well this path renderer is able to render the given path. Returning kNo or 110 * kAsBackup allows the caller to keep searching for a better path renderer. This function is 111 * called when searching for the best path renderer to draw a path. 112 */ canDrawPath(const CanDrawPathArgs & args)113 CanDrawPath canDrawPath(const CanDrawPathArgs& args) const { 114 SkDEBUGCODE(args.validate();) 115 return this->onCanDrawPath(args); 116 } 117 118 struct DrawPathArgs { 119 GrRecordingContext* fContext; 120 GrPaint&& fPaint; 121 const GrUserStencilSettings* fUserStencilSettings; 122 SurfaceDrawContext* fSurfaceDrawContext; 123 const GrClip* fClip; 124 const SkIRect* fClipConservativeBounds; 125 const SkMatrix* fViewMatrix; 126 const GrStyledShape* fShape; 127 GrAAType fAAType; 128 bool fGammaCorrect; 129 #ifdef SK_DEBUG validateDrawPathArgs130 void validate() const { 131 SkASSERT(fContext); 132 SkASSERT(fUserStencilSettings); 133 SkASSERT(fSurfaceDrawContext); 134 SkASSERT(fClipConservativeBounds); 135 SkASSERT(fViewMatrix); 136 SkASSERT(fShape); 137 } 138 #endif 139 }; 140 141 /** 142 * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then 143 * the subclass must respect the stencil settings. 144 */ 145 bool drawPath(const DrawPathArgs& args); 146 /** 147 * Args to stencilPath(). fAAType cannot be kCoverage. 148 */ 149 struct StencilPathArgs { 150 SkDEBUGCODE(StencilPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation. 151 152 GrRecordingContext* fContext; 153 SurfaceDrawContext* fSurfaceDrawContext; 154 const GrHardClip* fClip; 155 const SkIRect* fClipConservativeBounds; 156 const SkMatrix* fViewMatrix; 157 const GrStyledShape* fShape; 158 GrAA fDoStencilMSAA; 159 160 SkDEBUGCODE(void validate() const); 161 }; 162 163 /** 164 * Draws the path to the stencil buffer. Assume the writable stencil bits are already 165 * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards. 166 */ stencilPath(const StencilPathArgs & args)167 void stencilPath(const StencilPathArgs& args) { 168 SkDEBUGCODE(args.validate();) 169 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape)); 170 this->onStencilPath(args); 171 } 172 173 protected: 174 // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set 175 // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize. 176 static void GetPathDevBounds(const SkPath& path, 177 SkISize devSize, 178 const SkMatrix& matrix, 179 SkRect* bounds); 180 181 private: 182 /** 183 * Subclass overrides if it has any limitations of stenciling support. 184 */ onGetStencilSupport(const GrStyledShape &)185 virtual StencilSupport onGetStencilSupport(const GrStyledShape&) const { 186 return kNoRestriction_StencilSupport; 187 } 188 189 /** 190 * Subclass implementation of drawPath() 191 */ 192 virtual bool onDrawPath(const DrawPathArgs& args) = 0; 193 194 /** 195 * Subclass implementation of canDrawPath() 196 */ 197 virtual CanDrawPath onCanDrawPath(const CanDrawPathArgs& args) const = 0; 198 199 /** 200 * Subclass implementation of stencilPath(). Subclass must override iff it ever returns 201 * kStencilOnly in onGetStencilSupport(). 202 */ 203 virtual void onStencilPath(const StencilPathArgs&); 204 205 using INHERITED = SkRefCnt; 206 }; 207 208 } // namespace skgpu::v1 209 210 #endif // PathRenderer_DEFINED 211