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 GrTessellatePathOp_DEFINED |
9 | #define GrTessellatePathOp_DEFINED |
10 | |
11 | #include "src/gpu/ops/GrDrawOp.h" |
12 | |
13 | class GrAppliedHardClip; |
14 | class GrFillPathShader; |
15 | class GrStencilPathShader; |
16 | |
17 | // Renders paths using a hybrid Red Book "stencil, then cover" method. Curves get linearized by |
18 | // GPU tessellation shaders. This Op doesn't apply analytic AA, so it requires a render target that |
19 | // supports either MSAA or mixed samples if AA is desired. |
20 | class GrTessellatePathOp : public GrDrawOp { |
21 | public: |
22 | enum class Flags { |
23 | kNone = 0, |
24 | kStencilOnly = (1 << 0), |
25 | kWireframe = (1 << 1) |
26 | }; |
27 | |
28 | private: |
29 | DEFINE_OP_CLASS_ID |
30 | |
31 | GrTessellatePathOp(const SkMatrix& viewMatrix, const SkPath& path, GrPaint&& paint, |
32 | GrAAType aaType, Flags flags = Flags::kNone) |
33 | : GrDrawOp(ClassID()) |
34 | , fFlags(flags) |
35 | , fViewMatrix(viewMatrix) |
36 | , fPath(path) |
37 | , fAAType(aaType) |
38 | , fColor(paint.getColor4f()) |
39 | , fProcessors(std::move(paint)) { |
40 | SkRect devBounds; |
41 | fViewMatrix.mapRect(&devBounds, path.getBounds()); |
42 | this->setBounds(devBounds, HasAABloat(GrAAType::kCoverage == fAAType), IsHairline::kNo); |
43 | } |
44 | |
45 | const char* name() const override { return "GrTessellatePathOp" ; } |
46 | void visitProxies(const VisitProxyFunc& fn) const override { fProcessors.visitProxies(fn); } |
47 | GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip, |
48 | bool hasMixedSampledCoverage, |
49 | GrClampType clampType) override { |
50 | return fProcessors.finalize( |
51 | fColor, GrProcessorAnalysisCoverage::kNone, clip, &GrUserStencilSettings::kUnused, |
52 | hasMixedSampledCoverage, caps, clampType, &fColor); |
53 | } |
54 | |
55 | FixedFunctionFlags fixedFunctionFlags() const override; |
56 | void onPrePrepare(GrRecordingContext*, |
57 | const GrSurfaceProxyView* writeView, |
58 | GrAppliedClip*, |
59 | const GrXferProcessor::DstProxyView&) override; |
60 | void onPrepare(GrOpFlushState* state) override; |
61 | void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; |
62 | |
63 | void drawStencilPass(GrOpFlushState*); |
64 | void drawCoverPass(GrOpFlushState*); |
65 | |
66 | const Flags fFlags; |
67 | const SkMatrix fViewMatrix; |
68 | const SkPath fPath; |
69 | const GrAAType fAAType; |
70 | SkPMColor4f fColor; |
71 | GrProcessorSet fProcessors; |
72 | |
73 | // These path shaders get created during onPrepare for drawing the below path vertex data. |
74 | // |
75 | // If fFillPathShader is null, then we just stencil the full path using fStencilPathShader and |
76 | // fCubicInstanceBuffer, and then fill it using a simple bounding box. |
77 | // |
78 | // If fFillPathShader is not null, then we fill the path using it plus cubic hulls from |
79 | // fCubicInstanceBuffer instead of a bounding box. |
80 | // |
81 | // If fFillPathShader is not null and fStencilPathShader *is* null, then the vertex data |
82 | // contains non-overlapping path geometry that can be drawn directly to the final render target. |
83 | // We only need to stencil curves from fCubicInstanceBuffer, and then draw the rest of the path |
84 | // directly. |
85 | GrStencilPathShader* fStencilPathShader = nullptr; |
86 | GrFillPathShader* fFillPathShader = nullptr; |
87 | |
88 | // The "path vertex data" is made up of cubic wedges or inner polygon triangles (either red book |
89 | // style or fully tessellated). The geometry is generated by |
90 | // GrPathParser::EmitCenterWedgePatches, GrPathParser::EmitInnerPolygonTriangles, |
91 | // or GrTriangulator::PathToTriangles. |
92 | sk_sp<const GrBuffer> fPathVertexBuffer; |
93 | int fBasePathVertex; |
94 | int fPathVertexCount; |
95 | |
96 | // The cubic instance buffer defines standalone cubics to tessellate into the stencil buffer, in |
97 | // addition to the above path geometry. |
98 | sk_sp<const GrBuffer> fCubicInstanceBuffer; |
99 | int fBaseCubicInstance; |
100 | int fCubicInstanceCount; |
101 | |
102 | friend class GrOpMemoryPool; // For ctor. |
103 | }; |
104 | |
105 | GR_MAKE_BITFIELD_CLASS_OPS(GrTessellatePathOp::Flags); |
106 | |
107 | #endif |
108 | |