• 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 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 the classic 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)
GrDrawOp(ClassID ())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 
name()45     const char* name() const override { return "GrTessellatePathOp"; }
visitProxies(const VisitProxyFunc & fn)46     void visitProxies(const VisitProxyFunc& fn) const override { fProcessors.visitProxies(fn); }
finalize(const GrCaps & caps,const GrAppliedClip * clip,bool hasMixedSampledCoverage,GrClampType clampType)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 onPrepare(GrOpFlushState* state) override;
57     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
58 
59     void drawStencilPass(GrOpFlushState*, const GrAppliedHardClip&,
60                          const GrPipeline::FixedDynamicState*);
61     void drawCoverPass(GrOpFlushState*, GrAppliedClip&&, const GrPipeline::FixedDynamicState*);
62 
63     const Flags fFlags;
64     const SkMatrix fViewMatrix;
65     const SkPath fPath;
66     const GrAAType fAAType;
67     SkPMColor4f fColor;
68     GrProcessorSet fProcessors;
69 
70     // These path shaders get created during onPrepare for drawing the below path vertex data.
71     //
72     // If fFillPathShader is null, then we just stencil the full path using fStencilPathShader and
73     // fCubicInstanceBuffer, and then fill it using a simple bounding box.
74     //
75     // If fFillPathShader is not null, then we fill the path using it plus cubic hulls from
76     // fCubicInstanceBuffer instead of a bounding box.
77     //
78     // If fFillPathShader is not null and fStencilPathShader *is* null, then the vertex data
79     // contains non-overlapping path geometry that can be drawn directly to the final render target.
80     // We only need to stencil curves from fCubicInstanceBuffer, and then draw the rest of the path
81     // directly.
82     GrStencilPathShader* fStencilPathShader = nullptr;
83     GrFillPathShader* fFillPathShader = nullptr;
84 
85     // The "path vertex data" is made up of cubic wedges or inner polygon triangles (either red book
86     // style or fully tessellated). The geometry is generated by
87     // GrPathParser::EmitCenterWedgePatches, GrPathParser::EmitInnerPolygonTriangles,
88     // or GrTessellator::PathToTriangles.
89     sk_sp<const GrBuffer> fPathVertexBuffer;
90     int fBasePathVertex;
91     int fPathVertexCount;
92 
93     // The cubic instance buffer defines standalone cubics to tessellate into the stencil buffer, in
94     // addition to the above path geometry.
95     sk_sp<const GrBuffer> fCubicInstanceBuffer;
96     int fBaseCubicInstance;
97     int fCubicInstanceCount;
98 
99     friend class GrOpMemoryPool;  // For ctor.
100 };
101 
102 GR_MAKE_BITFIELD_CLASS_OPS(GrTessellatePathOp::Flags);
103 
104 #endif
105