blob: dd4dd6dce4c2643b82c93716a65d79dc04a50e63 [file] [log] [blame]
Chris Daltonb832ce62020-01-06 19:49:37 -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 GrTessellatePathOp_DEFINED
9#define GrTessellatePathOp_DEFINED
10
11#include "src/gpu/ops/GrDrawOp.h"
12
13class GrAppliedHardClip;
Chris Dalton4328e922020-01-29 13:16:14 -070014class GrFillPathShader;
Chris Daltonf9aea7f2020-01-21 11:19:26 -070015class GrStencilPathShader;
Chris Daltonb832ce62020-01-06 19:49:37 -070016
Chris Dalton0a22b1e2020-03-26 11:52:15 -060017// Renders paths using a hybrid Red Book "stencil, then cover" method. Curves get linearized by
Chris Daltonb832ce62020-01-06 19:49:37 -070018// 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.
20class GrTessellatePathOp : public GrDrawOp {
21public:
22 enum class Flags {
23 kNone = 0,
24 kStencilOnly = (1 << 0),
25 kWireframe = (1 << 1)
26 };
27
28private:
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());
Chris Dalton4e998532020-02-10 11:06:42 -070042 this->setBounds(devBounds, HasAABloat(GrAAType::kCoverage == fAAType), IsHairline::kNo);
Chris Daltonb832ce62020-01-06 19:49:37 -070043 }
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;
Robert Phillipsc655c3a2020-03-18 13:23:45 -040056 void onPrePrepare(GrRecordingContext*,
Brian Salomon8afde5f2020-04-01 16:22:00 -040057 const GrSurfaceProxyView* writeView,
Robert Phillipsc655c3a2020-03-18 13:23:45 -040058 GrAppliedClip*,
59 const GrXferProcessor::DstProxyView&) override;
Chris Daltonb832ce62020-01-06 19:49:37 -070060 void onPrepare(GrOpFlushState* state) override;
61 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
62
Chris Daltonaa0e45c2020-03-16 10:05:11 -060063 void drawStencilPass(GrOpFlushState*);
64 void drawCoverPass(GrOpFlushState*);
Chris Daltonb832ce62020-01-06 19:49:37 -070065
66 const Flags fFlags;
67 const SkMatrix fViewMatrix;
68 const SkPath fPath;
69 const GrAAType fAAType;
70 SkPMColor4f fColor;
71 GrProcessorSet fProcessors;
72
Chris Dalton4328e922020-01-29 13:16:14 -070073 // 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;
Chris Daltond081dce2020-01-23 12:09:04 -070087
Chris Dalton4328e922020-01-29 13:16:14 -070088 // 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,
Chris Dalton17dc4182020-03-25 16:18:16 -060091 // or GrTriangulator::PathToTriangles.
Chris Daltonf9aea7f2020-01-21 11:19:26 -070092 sk_sp<const GrBuffer> fPathVertexBuffer;
93 int fBasePathVertex;
94 int fPathVertexCount;
95
Chris Daltonf9aea7f2020-01-21 11:19:26 -070096 // 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;
Chris Daltonb832ce62020-01-06 19:49:37 -0700101
102 friend class GrOpMemoryPool; // For ctor.
103};
104
105GR_MAKE_BITFIELD_CLASS_OPS(GrTessellatePathOp::Flags);
106
107#endif