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