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