/*
 * 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
