• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 GrPathTessellator_DEFINED
9 #define GrPathTessellator_DEFINED
10 
11 #include "src/gpu/GrInnerFanTriangulator.h"
12 #include "src/gpu/ops/GrMeshDrawOp.h"
13 #include "src/gpu/tessellate/GrTessellationPathRenderer.h"
14 
15 class SkPath;
16 
17 // Prepares GPU data for, and then draws a path's tessellated geometry. Depending on the subclass,
18 // the caller may or may not be required to draw the path's inner fan separately.
19 class GrPathTessellator {
20 public:
21     using BreadcrumbTriangleList = GrInnerFanTriangulator::BreadcrumbTriangleList;
22 
23     // Called before draw(). Prepares GPU buffers containing the geometry to tessellate. If the
24     // given BreadcrumbTriangleList is non-null, then this class will also include the breadcrumb
25     // triangles in its draw.
26     virtual void prepare(GrMeshDrawOp::Target*, const SkMatrix&, const SkPath&,
27                          const BreadcrumbTriangleList* = nullptr) = 0;
28 
29     // Issues draw calls for the tessellated geometry. The caller is responsible for binding its
30     // desired pipeline ahead of time.
31     virtual void draw(GrOpFlushState*) const = 0;
32 
33     // Draws a 4-point instance for each curve. This method is used for drawing convex hulls over
34     // each cubic with GrFillCubicHullShader. The caller is responsible for binding its desired
35     // pipeline ahead of time. This method is not supported by every subclass.
drawHullInstances(GrOpFlushState *)36     virtual void drawHullInstances(GrOpFlushState*) const { SK_ABORT("Not supported."); }
37 
~GrPathTessellator()38     virtual ~GrPathTessellator() {}
39 };
40 
41 // Draws tessellations of the path's outer curves using indirect draw commands. Quadratics are
42 // converted to cubics. An outer curve is an independent, 4-point closed contour that represents
43 // either a cubic or a conic.
44 //
45 // For performance reasons we can often express triangles as one of these indirect draws and sneak
46 // them in alongside the other curves. If DrawInnerFan is kYes, then this class also draws the
47 // path's inner fan along with the outer curves.
48 class GrPathIndirectTessellator final : public GrPathTessellator {
49 public:
50     enum class DrawInnerFan : bool { kNo = false, kYes };
51     GrPathIndirectTessellator(const SkMatrix&, const SkPath&, DrawInnerFan);
52 
53     void prepare(GrMeshDrawOp::Target*, const SkMatrix&, const SkPath&,
54                  const BreadcrumbTriangleList*) override;
55     void draw(GrOpFlushState*) const override;
56     void drawHullInstances(GrOpFlushState*) const override;
57 
58 private:
59     constexpr static float kLinearizationPrecision =
60             GrTessellationPathRenderer::kLinearizationPrecision;
61     constexpr static int kMaxResolveLevel = GrTessellationPathRenderer::kMaxResolveLevel;
62 
63     const bool fDrawInnerFan;
64     int fResolveLevelCounts[kMaxResolveLevel + 1] = {0};
65     int fOuterCurveInstanceCount = 0;
66 
67     sk_sp<const GrBuffer> fInstanceBuffer;
68     int fBaseInstance = 0;
69     int fTotalInstanceCount = 0;
70 
71     sk_sp<const GrBuffer> fIndirectDrawBuffer;
72     size_t fIndirectDrawOffset = 0;
73     int fIndirectDrawCount = 0;
74     sk_sp<const GrBuffer> fIndirectIndexBuffer;
75 };
76 
77 // Base class for GrPathTessellators that draw actual hardware tessellation patches.
78 class GrPathHardwareTessellator : public GrPathTessellator {
79 public:
80     GrPathHardwareTessellator() = default;
81 
82     void draw(GrOpFlushState*) const final;
83 
84 protected:
85     sk_sp<const GrBuffer> fPatchBuffer;
86     int fBasePatchVertex = 0;
87     int fPatchVertexCount = 0;
88 };
89 
90 // Draws an array of "outer curve" patches for GrCubicTessellateShader. Each patch is an independent
91 // 4-point curve, representing either a cubic or conic. Qudaratics are converted to cubics. The
92 // caller is responsible to stencil the path's inner fan along with these outer cubics.
93 class GrPathOuterCurveTessellator final : public GrPathHardwareTessellator {
94 public:
95     GrPathOuterCurveTessellator() = default;
96 
97     void prepare(GrMeshDrawOp::Target*, const SkMatrix&, const SkPath&,
98                  const BreadcrumbTriangleList*) override;
99 };
100 
101 // Draws an array of "wedge" patches for GrWedgeTessellateShader. A wedge is an independent, 5-point
102 // closed contour consisting of 4 control points plus an anchor point fanning from the center of the
103 // curve's resident contour. A wedge can be either a cubic or a conic. Qudaratics and lines are
104 // converted to cubics. Once stencilled, these wedges alone define the complete path.
105 class GrPathWedgeTessellator final : public GrPathHardwareTessellator {
106 public:
107     GrPathWedgeTessellator() = default;
108 
109     void prepare(GrMeshDrawOp::Target*, const SkMatrix&, const SkPath&,
110                  const BreadcrumbTriangleList*) override;
111 };
112 
113 #endif
114