Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/gpu/ganesh/PathRenderer.h
Line
Count
Source (jump to first uncovered line)
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/base/SkTArray.h"
13
#include "include/private/gpu/ganesh/GrTypesPriv.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::ganesh {
30
31
class SurfaceDrawContext;
32
33
/**
34
 *  Base class for drawing paths into a OpsTask.
35
 */
36
class PathRenderer : public SkRefCnt {
37
public:
38
8.65k
    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
97
0
        void validate() const {
98
0
            SkASSERT(fCaps);
99
0
            SkASSERT(fProxy);
100
0
            SkASSERT(fClipConservativeBounds);
101
0
            SkASSERT(fViewMatrix);
102
0
            SkASSERT(fShape);
103
0
            SkASSERT(fSurfaceProps);
104
0
        }
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
     */
113
623k
    CanDrawPath canDrawPath(const CanDrawPathArgs& args) const {
114
623k
        SkDEBUGCODE(args.validate();)
115
623k
        return this->onCanDrawPath(args);
116
623k
    }
skgpu::ganesh::PathRenderer::canDrawPath(skgpu::ganesh::PathRenderer::CanDrawPathArgs const&) const
Line
Count
Source
113
311k
    CanDrawPath canDrawPath(const CanDrawPathArgs& args) const {
114
311k
        SkDEBUGCODE(args.validate();)
115
311k
        return this->onCanDrawPath(args);
116
311k
    }
skgpu::ganesh::PathRenderer::canDrawPath(skgpu::ganesh::PathRenderer::CanDrawPathArgs const&) const
Line
Count
Source
113
311k
    CanDrawPath canDrawPath(const CanDrawPathArgs& args) const {
114
311k
        SkDEBUGCODE(args.validate();)
115
311k
        return this->onCanDrawPath(args);
116
311k
    }
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
130
0
        void validate() const {
131
0
            SkASSERT(fContext);
132
0
            SkASSERT(fUserStencilSettings);
133
0
            SkASSERT(fSurfaceDrawContext);
134
0
            SkASSERT(fClipConservativeBounds);
135
0
            SkASSERT(fViewMatrix);
136
0
            SkASSERT(fShape);
137
0
        }
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
     */
167
216
    void stencilPath(const StencilPathArgs& args) {
168
216
        SkDEBUGCODE(args.validate();)
169
216
        SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
170
216
        this->onStencilPath(args);
171
216
    }
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
     */
185
4.12k
    virtual StencilSupport onGetStencilSupport(const GrStyledShape&) const {
186
4.12k
        return kNoRestriction_StencilSupport;
187
4.12k
    }
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::ganesh
209
210
#endif // PathRenderer_DEFINED