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