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