blob: 4b1051c429c991935d1078c5370a3d30e85c8125 [file] [log] [blame]
Chris Daltonebb37e72021-01-27 17:59:45 -07001/*
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"
Chris Daltonebb37e72021-01-27 17:59:45 -070013#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
Chris Dalton3b412782021-06-01 13:40:03 -060014#include "src/gpu/tessellate/shaders/GrTessellationShader.h"
Chris Daltonebb37e72021-01-27 17:59:45 -070015
16class 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.
26class GrPathInnerTriangulateOp : public GrDrawOp {
27private:
28 DEFINE_OP_CLASS_ID
29
30 GrPathInnerTriangulateOp(const SkMatrix& viewMatrix, const SkPath& path, GrPaint&& paint,
Chris Dalton569c01b2021-05-25 10:11:46 -060031 GrAAType aaType, GrTessellationPathRenderer::OpFlags opFlags,
32 const SkRect& devBounds)
Chris Daltonebb37e72021-01-27 17:59:45 -070033 : GrDrawOp(ClassID())
34 , fOpFlags(opFlags)
35 , fViewMatrix(viewMatrix)
36 , fPath(path)
37 , fAAType(aaType)
38 , fColor(paint.getColor4f())
39 , fProcessors(std::move(paint)) {
Chris Dalton57ab06c2021-04-22 12:57:28 -060040 this->setBounds(devBounds, HasAABloat::kNo, IsHairline::kNo);
Chris Daltonebb37e72021-01-27 17:59:45 -070041 }
42
43 const char* name() const override { return "GrPathInnerTriangulateOp"; }
44 void visitProxies(const VisitProxyFunc& fn) const override;
45 FixedFunctionFlags fixedFunctionFlags() const override;
Chris Dalton57ab06c2021-04-22 12:57:28 -060046 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Chris Daltonebb37e72021-01-27 17:59:45 -070047
48 // These calls set up the stencil & fill programs we will use prior to preparing and executing.
Chris Dalton2f733ec2021-06-01 12:11:57 -060049 void pushFanStencilProgram(const GrTessellationShader::ProgramArgs&,
Chris Daltonebb37e72021-01-27 17:59:45 -070050 const GrPipeline* pipelineForStencils, const GrUserStencilSettings*);
Chris Dalton2f733ec2021-06-01 12:11:57 -060051 void pushFanFillProgram(const GrTessellationShader::ProgramArgs&, const GrUserStencilSettings*);
52 void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&&);
Chris Daltonebb37e72021-01-27 17:59:45 -070053
54 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
55 const GrXferProcessor::DstProxyView&, GrXferBarrierFlags,
56 GrLoadOp colorLoadOp) override;
57 void onPrepare(GrOpFlushState*) override;
58 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
59
60 const GrTessellationPathRenderer::OpFlags fOpFlags;
61 const SkMatrix fViewMatrix;
62 const SkPath fPath;
63 const GrAAType fAAType;
64 SkPMColor4f fColor;
65 GrProcessorSet fProcessors;
66
67 // Triangulates the inner fan.
68 GrInnerFanTriangulator* fFanTriangulator = nullptr;
69 GrTriangulator::Poly* fFanPolys = nullptr;
70 GrInnerFanTriangulator::BreadcrumbTriangleList fFanBreadcrumbs;
71
72 // This pipeline is shared by all programs that do filling.
73 const GrPipeline* fPipelineForFills = nullptr;
74
75 // Tessellates the outer curves.
76 GrPathTessellator* fTessellator = nullptr;
77
78 // Pass 1: Tessellate the outer curves into the stencil buffer.
79 const GrProgramInfo* fStencilCurvesProgram = nullptr;
80
81 // Pass 2: Fill the path's inner fan with a stencil test against the curves. (In extenuating
82 // circumstances this might require two separate draws.)
83 SkSTArray<2, const GrProgramInfo*> fFanPrograms;
84
85 // Pass 3: Draw convex hulls around each curve.
86 const GrProgramInfo* fFillHullsProgram = nullptr;
87
88 // This buffer gets created by fFanTriangulator during onPrepare.
89 sk_sp<const GrBuffer> fFanBuffer;
90 int fBaseFanVertex = 0;
91 int fFanVertexCount = 0;
92
93 friend class GrOp; // For ctor.
94};
95
96#endif