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