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