blob: 95528d1a566893e83a75cd58bedebcd3082fed14 [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"
13#include "src/gpu/tessellate/GrPathShader.h"
14#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
15
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,
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());
Chris Dalton57ab06c2021-04-22 12:57:28 -060041 this->setBounds(devBounds, HasAABloat::kNo, IsHairline::kNo);
Chris Daltonebb37e72021-01-27 17:59:45 -070042 }
43
44 const char* name() const override { return "GrPathInnerTriangulateOp"; }
45 void visitProxies(const VisitProxyFunc& fn) const override;
46 FixedFunctionFlags fixedFunctionFlags() const override;
Chris Dalton57ab06c2021-04-22 12:57:28 -060047 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Chris Daltonebb37e72021-01-27 17:59:45 -070048
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