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