| /* |
| * Copyright 2021 Google LLC. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef tessellate_StrokeFixedCountTessellator_DEFINED |
| #define tessellate_StrokeFixedCountTessellator_DEFINED |
| |
| #include "src/gpu/tessellate/StrokeTessellator.h" |
| |
| #if SK_GPU_V1 |
| #include "src/gpu/GrGpuBuffer.h" |
| #endif |
| |
| namespace skgpu { |
| |
| // Renders strokes as fixed-count triangle strip instances. Any extra triangles not needed by the |
| // instance are emitted as degenerate triangles. |
| class StrokeFixedCountTessellator final : public StrokeTessellator { |
| public: |
| constexpr static int kMaxParametricSegments = 32; |
| constexpr static int8_t kMaxParametricSegments_log2 = 5; // log2(32) |
| |
| StrokeFixedCountTessellator(PatchAttribs attribs) : StrokeTessellator(attribs) {} |
| |
| int patchPreallocCount(int totalCombinedStrokeVerbCnt) const final; |
| |
| int writePatches(PatchWriter&, |
| const SkMatrix& shaderMatrix, |
| std::array<float,2> matrixMinMaxScales, |
| PathStrokeList*) final; |
| |
| #if SK_GPU_V1 |
| int prepare(GrMeshDrawTarget*, |
| const SkMatrix& shaderMatrix, |
| std::array<float,2> matrixMinMaxScales, |
| PathStrokeList*, |
| int totalCombinedStrokeVerbCnt) final; |
| |
| void draw(GrOpFlushState*) const final; |
| #endif |
| |
| // Initializes the fallback vertex buffer that should be bound when sk_VertexID is not |
| // supported. Each vertex is a single float and each edge is composed of two vertices, so the |
| // desired edge count in the buffer is presumed to be "bufferSize / (sizeof(float) * 2)". The |
| // caller cannot draw more vertices than edgeCount * 2. |
| static void InitializeVertexIDFallbackBuffer(VertexWriter vertexWriter, size_t bufferSize); |
| |
| // Returns the fixed number of edges that are always emitted with the given join type. If the |
| // join is round, the caller needs to account for the additional radial edges on their own. |
| // Specifically, each join always emits: |
| // |
| // * Two colocated edges at the beginning (a full-width edge to seam with the preceding stroke |
| // and a half-width edge to begin the join). |
| // |
| // * An extra edge in the middle for miter joins, or else a variable number of radial edges |
| // for round joins (the caller is responsible for counting radial edges from round joins). |
| // |
| // * A half-width edge at the end of the join that will be colocated with the first |
| // (full-width) edge of the stroke. |
| // |
| constexpr static int NumFixedEdgesInJoin(SkPaint::Join joinType) { |
| switch (joinType) { |
| case SkPaint::kMiter_Join: |
| return 4; |
| case SkPaint::kRound_Join: |
| // The caller is responsible for counting the variable number of middle, radial |
| // segments on round joins. |
| [[fallthrough]]; |
| case SkPaint::kBevel_Join: |
| return 3; |
| } |
| SkUNREACHABLE; |
| } |
| |
| private: |
| #if SK_GPU_V1 |
| int fFixedEdgeCount = 0; |
| |
| // Only used if sk_VertexID is not supported. |
| sk_sp<const GrGpuBuffer> fVertexBufferIfNoIDSupport; |
| #endif |
| }; |
| |
| } // namespace skgpu |
| |
| #endif // tessellate_StrokeFixedCountTessellator_DEFINED |