• 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 tessellate_StrokeFixedCountTessellator_DEFINED
9 #define tessellate_StrokeFixedCountTessellator_DEFINED
10 
11 #include "src/gpu/tessellate/StrokeTessellator.h"
12 
13 #if SK_GPU_V1
14 #include "src/gpu/GrGpuBuffer.h"
15 #endif
16 
17 namespace skgpu {
18 
19 // Renders strokes as fixed-count triangle strip instances. Any extra triangles not needed by the
20 // instance are emitted as degenerate triangles.
21 class StrokeFixedCountTessellator final : public StrokeTessellator {
22 public:
23     constexpr static int kMaxParametricSegments = 32;
24     constexpr static int8_t kMaxParametricSegments_log2 = 5;  // log2(32)
25 
StrokeFixedCountTessellator(PatchAttribs attribs)26     StrokeFixedCountTessellator(PatchAttribs attribs) : StrokeTessellator(attribs) {}
27 
28     int patchPreallocCount(int totalCombinedStrokeVerbCnt) const final;
29 
30     int writePatches(PatchWriter&,
31                      const SkMatrix& shaderMatrix,
32                      std::array<float,2> matrixMinMaxScales,
33                      PathStrokeList*) final;
34 
35 #if SK_GPU_V1
36     int prepare(GrMeshDrawTarget*,
37                 const SkMatrix& shaderMatrix,
38                 std::array<float,2> matrixMinMaxScales,
39                 PathStrokeList*,
40                 int totalCombinedStrokeVerbCnt) final;
41 
42     void draw(GrOpFlushState*) const final;
43 #endif
44 
45     // Initializes the fallback vertex buffer that should be bound when sk_VertexID is not
46     // supported. Each vertex is a single float and each edge is composed of two vertices, so the
47     // desired edge count in the buffer is presumed to be "bufferSize / (sizeof(float) * 2)". The
48     // caller cannot draw more vertices than edgeCount * 2.
49     static void InitializeVertexIDFallbackBuffer(VertexWriter vertexWriter, size_t bufferSize);
50 
51     // Returns the fixed number of edges that are always emitted with the given join type. If the
52     // join is round, the caller needs to account for the additional radial edges on their own.
53     // Specifically, each join always emits:
54     //
55     //   * Two colocated edges at the beginning (a full-width edge to seam with the preceding stroke
56     //     and a half-width edge to begin the join).
57     //
58     //   * An extra edge in the middle for miter joins, or else a variable number of radial edges
59     //     for round joins (the caller is responsible for counting radial edges from round joins).
60     //
61     //   * A half-width edge at the end of the join that will be colocated with the first
62     //     (full-width) edge of the stroke.
63     //
NumFixedEdgesInJoin(SkPaint::Join joinType)64     constexpr static int NumFixedEdgesInJoin(SkPaint::Join joinType) {
65         switch (joinType) {
66             case SkPaint::kMiter_Join:
67                 return 4;
68             case SkPaint::kRound_Join:
69                 // The caller is responsible for counting the variable number of middle, radial
70                 // segments on round joins.
71                 [[fallthrough]];
72             case SkPaint::kBevel_Join:
73                 return 3;
74         }
75         SkUNREACHABLE;
76     }
77 
78 private:
79 #if SK_GPU_V1
80     int fFixedEdgeCount = 0;
81 
82     // Only used if sk_VertexID is not supported.
83     sk_sp<const GrGpuBuffer> fVertexBufferIfNoIDSupport;
84 #endif
85 };
86 
87 }  // namespace skgpu
88 
89 #endif  // tessellate_StrokeFixedCountTessellator_DEFINED
90