xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/PathStencilCoverOp.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 Google LLC.
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 #ifndef PathStencilCoverOp_DEFINED
8 #define PathStencilCoverOp_DEFINED
9 
10 #include "include/core/SkPath.h"
11 #include "include/core/SkRect.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/private/SkColorData.h"
14 #include "include/private/base/SkDebug.h"
15 #include "include/private/gpu/ganesh/GrTypesPriv.h"
16 #include "src/base/SkArenaAlloc.h"
17 #include "src/gpu/ganesh/GrBuffer.h"
18 #include "src/gpu/ganesh/GrCaps.h"
19 #include "src/gpu/ganesh/GrGpuBuffer.h"
20 #include "src/gpu/ganesh/GrPaint.h"
21 #include "src/gpu/ganesh/GrProcessorSet.h"
22 #include "src/gpu/ganesh/ops/GrDrawOp.h"
23 #include "src/gpu/ganesh/ops/GrOp.h"
24 #include "src/gpu/ganesh/tessellate/GrTessellationShader.h"
25 #include "src/gpu/ganesh/tessellate/PathTessellator.h"
26 
27 #include <utility>
28 
29 class GrAppliedClip;
30 class GrDstProxyView;
31 class GrOpFlushState;
32 class GrProgramInfo;
33 class GrRecordingContext;
34 class GrSurfaceProxyView;
35 class SkMatrix;
36 enum class GrXferBarrierFlags;
37 enum class SkPathFillType;
38 
39 namespace skgpu::ganesh {
40 
41 enum class FillPathFlags;
42 
43 // Draws paths using a standard Redbook "stencil then cover" method. Curves get linearized by either
44 // GPU tessellation shaders or indirect draws. This Op doesn't apply analytic AA, so it requires
45 // MSAA if AA is desired.
46 class PathStencilCoverOp final : public GrDrawOp {
47 private:
48     DEFINE_OP_CLASS_ID
49 
50     using PathDrawList = PathTessellator::PathDrawList;
51 
52     // If the path is inverse filled, drawBounds must be the entire backing store dimensions of the
53     // render target.
PathStencilCoverOp(SkArenaAlloc * arena,const SkMatrix & viewMatrix,const SkPath & path,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)54     PathStencilCoverOp(SkArenaAlloc* arena,
55                        const SkMatrix& viewMatrix,
56                        const SkPath& path,
57                        GrPaint&& paint,
58                        GrAAType aaType,
59                        FillPathFlags pathFlags,
60                        const SkRect& drawBounds)
61             : GrDrawOp(ClassID())
62             , fPathDrawList(arena->make<PathDrawList>(viewMatrix, path, SK_PMColor4fTRANSPARENT))
63             , fTotalCombinedPathVerbCnt(path.countVerbs())
64             , fPathCount(1)
65             , fPathFlags(pathFlags)
66             , fAAType(aaType)
67             , fColor(paint.getColor4f())
68             , fProcessors(std::move(paint)) {
69         this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
70         SkDEBUGCODE(fOriginalDrawBounds = drawBounds;)
71     }
72 
73     // Constructs a PathStencilCoverOp from an existing draw list.
74     // FIXME: The only user of this method is the atlas. We should move the GrProgramInfos into
75     // PathTessellator so the atlas can use that directly instead of going through this class.
PathStencilCoverOp(const PathDrawList * pathDrawList,int totalCombinedVerbCnt,int pathCount,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)76     PathStencilCoverOp(const PathDrawList* pathDrawList,
77                        int totalCombinedVerbCnt,
78                        int pathCount,
79                        GrPaint&& paint,
80                        GrAAType aaType,
81                        FillPathFlags pathFlags,
82                        const SkRect& drawBounds)
83             : GrDrawOp(ClassID())
84             , fPathDrawList(pathDrawList)
85             , fTotalCombinedPathVerbCnt(totalCombinedVerbCnt)
86             , fPathCount(pathCount)
87             , fPathFlags(pathFlags)
88             , fAAType(aaType)
89             , fColor(paint.getColor4f())
90             , fProcessors(std::move(paint)) {
91         this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
92         SkDEBUGCODE(fOriginalDrawBounds = drawBounds;)
93     }
94 
name()95     const char* name() const override { return "PathStencilCoverOp"; }
96     void visitProxies(const GrVisitProxyFunc&) const override;
97     FixedFunctionFlags fixedFunctionFlags() const override;
98     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
99 
100     // All paths in fPathDrawList are required to have the same fill type.
pathFillType()101     SkPathFillType pathFillType() const {
102         return fPathDrawList->fPath.getFillType();
103     }
104 
105     // Chooses the rendering method we will use and creates the corresponding tessellator and
106     // stencil/cover programs.
107     void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&& clip);
108 
109     void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
110                       const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
111     void onPrepare(GrOpFlushState*) override;
112     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
113 
114     const PathDrawList* fPathDrawList;
115     const int fTotalCombinedPathVerbCnt;
116     const int fPathCount;
117     const FillPathFlags fPathFlags;
118     const GrAAType fAAType;
119     SkPMColor4f fColor;
120     GrProcessorSet fProcessors;
121     SkDEBUGCODE(SkRect fOriginalDrawBounds;)
122 
123     // Decided during prePreparePrograms.
124     PathTessellator* fTessellator = nullptr;
125     const GrProgramInfo* fStencilFanProgram = nullptr;
126     const GrProgramInfo* fStencilPathProgram = nullptr;
127     const GrProgramInfo* fCoverBBoxProgram = nullptr;
128 
129     // Filled during onPrepare.
130     sk_sp<const GrBuffer> fFanBuffer;
131     int fFanBaseVertex = 0;
132     int fFanVertexCount = 0;
133 
134     sk_sp<const GrBuffer> fBBoxBuffer;
135     int fBBoxBaseInstance = 0;
136 
137     // Only used if sk_VertexID is not supported.
138     sk_sp<const GrGpuBuffer> fBBoxVertexBufferIfNoIDSupport;
139 
140     friend class GrOp;  // For ctor.
141 };
142 
143 }  // namespace skgpu::ganesh
144 
145 #endif // PathStencilCoverOp_DEFINED
146