• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 PathInnerTriangulateOp_DEFINED
9 #define PathInnerTriangulateOp_DEFINED
10 
11 #include "src/gpu/geometry/GrInnerFanTriangulator.h"
12 #include "src/gpu/ops/FillPathFlags.h"
13 #include "src/gpu/ops/GrDrawOp.h"
14 #include "src/gpu/tessellate/shaders/GrTessellationShader.h"
15 
16 namespace skgpu {
17 
18 class PathCurveTessellator;
19 
20 };
21 
22 namespace skgpu::v1 {
23 
24 // This op is a 3-pass twist on the standard Redbook "stencil then cover" algorithm:
25 //
26 // 1) Tessellate the path's outer curves into the stencil buffer.
27 // 2) Triangulate the path's inner fan and fill it with a stencil test against the curves.
28 // 3) Draw convex hulls around each curve that fill in remaining samples.
29 //
30 // In practice, a path's inner fan takes up a large majority of its pixels. So from a GPU load
31 // perspective, this op is effectively as fast as a single-pass algorithm.
32 class PathInnerTriangulateOp final : public GrDrawOp {
33 private:
34     DEFINE_OP_CLASS_ID
35 
PathInnerTriangulateOp(const SkMatrix & viewMatrix,const SkPath & path,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)36     PathInnerTriangulateOp(const SkMatrix& viewMatrix,
37                            const SkPath& path,
38                            GrPaint&& paint,
39                            GrAAType aaType,
40                            FillPathFlags pathFlags,
41                            const SkRect& drawBounds)
42             : GrDrawOp(ClassID())
43             , fPathFlags(pathFlags)
44             , fViewMatrix(viewMatrix)
45             , fPath(path)
46             , fAAType(aaType)
47             , fColor(paint.getColor4f())
48             , fProcessors(std::move(paint)) {
49         SkASSERT(!fPath.isInverseFillType());
50         this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
51     }
52 
name()53     const char* name() const override { return "PathInnerTriangulateOp"; }
54     void visitProxies(const GrVisitProxyFunc&) const override;
55     FixedFunctionFlags fixedFunctionFlags() const override;
56     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
57 
58     // These calls set up the stencil & fill programs we will use prior to preparing and executing.
59     void pushFanStencilProgram(const GrTessellationShader::ProgramArgs&,
60                                const GrPipeline* pipelineForStencils, const GrUserStencilSettings*);
61     void pushFanFillProgram(const GrTessellationShader::ProgramArgs&, const GrUserStencilSettings*);
62     void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&&);
63 
64     void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
65                       const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
66     void onPrepare(GrOpFlushState*) override;
67     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
68 
69     const FillPathFlags fPathFlags;
70     const SkMatrix fViewMatrix;
71     const SkPath fPath;
72     const GrAAType fAAType;
73     SkPMColor4f fColor;
74     GrProcessorSet fProcessors;
75 
76     // Triangulates the inner fan.
77     GrInnerFanTriangulator* fFanTriangulator = nullptr;
78     GrTriangulator::Poly* fFanPolys = nullptr;
79     GrInnerFanTriangulator::BreadcrumbTriangleList fFanBreadcrumbs;
80 
81     // This pipeline is shared by all programs that do filling.
82     const GrPipeline* fPipelineForFills = nullptr;
83 
84     // Tessellates the outer curves.
85     PathCurveTessellator* fTessellator = nullptr;
86 
87     // Pass 1: Tessellate the outer curves into the stencil buffer.
88     const GrProgramInfo* fStencilCurvesProgram = nullptr;
89 
90     // Pass 2: Fill the path's inner fan with a stencil test against the curves. (In extenuating
91     // circumstances this might require two separate draws.)
92     SkSTArray<2, const GrProgramInfo*> fFanPrograms;
93 
94     // Pass 3: Draw convex hulls around each curve.
95     const GrProgramInfo* fCoverHullsProgram = nullptr;
96 
97     // This buffer gets created by fFanTriangulator during onPrepare.
98     sk_sp<const GrBuffer> fFanBuffer;
99     int fBaseFanVertex = 0;
100     int fFanVertexCount = 0;
101 
102     // Only used if sk_VertexID is not supported.
103     sk_sp<const GrGpuBuffer> fHullVertexBufferIfNoIDSupport;
104 
105     friend class GrOp;  // For ctor.
106 };
107 
108 } // namespace skgpu::v1
109 
110 #endif // PathInnerTriangulateOp_DEFINED
111