/*
 * Copyright 2022 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef skgpu_graphite_DrawPassCommands_DEFINED
#define skgpu_graphite_DrawPassCommands_DEFINED

#include "include/core/SkRect.h"
#include "src/base/SkArenaAlloc.h"
#include "src/base/SkTBlockList.h"
#include "src/gpu/graphite/DrawTypes.h"

namespace skgpu::graphite {

namespace DrawPassCommands {

// A list of all the commands types used by a DrawPass.
// Each of these is reified into a struct below.
//
// The design of this systems is based on SkRecords.

// (We're using the macro-of-macro trick here to do several different things with the same list.)
//
// We leave this SKGPU_DRAW_COMMAND_TYPES macro defined for use by code that wants to operate on
// DrawPassCommands types polymorphically.
#define SKGPU_DRAW_PASS_COMMAND_TYPES(M)                            \
    M(BindGraphicsPipeline)                                         \
    M(SetBlendConstants)                                            \
    M(BindUniformBuffer)                                            \
    M(BindDrawBuffers)                                              \
    M(BindTexturesAndSamplers)                                      \
    M(SetScissor)                                                   \
    M(Draw)                                                         \
    M(DrawIndexed)                                                  \
    M(DrawInstanced)                                                \
    M(DrawIndexedInstanced)

// Defines DrawPassCommands::Type, an enum of all draw command types.
#define ENUM(T) k##T,
enum class Type { SKGPU_DRAW_PASS_COMMAND_TYPES(ENUM) };
#undef ENUM

#define ACT_AS_PTR(ptr)                 \
    operator T*() const { return ptr; } \
    T* operator->() const { return ptr; }

// PODArray doesn't own the pointer's memory, and we assume the data is POD.
template <typename T>
class PODArray {
public:
    PODArray() {}
    PODArray(T* ptr) : fPtr(ptr) {}
    // Default copy and assign.

    ACT_AS_PTR(fPtr)
private:
    T* fPtr;
};

#undef ACT_AS_PTR

// A macro to make it a little easier to define a struct that can be stored in DrawPass.
#define COMMAND(T, ...)                    \
struct T {                                 \
static constexpr Type kType = Type::k##T;  \
    __VA_ARGS__;                           \
};

COMMAND(BindGraphicsPipeline,
            uint32_t fPipelineIndex);
COMMAND(SetBlendConstants,
            PODArray<float> fBlendConstants);
COMMAND(BindUniformBuffer,
            BindBufferInfo fInfo;
            UniformSlot fSlot);
COMMAND(BindDrawBuffers,
            BindBufferInfo fVertices;
            BindBufferInfo fInstances;
            BindBufferInfo fIndices);
COMMAND(BindTexturesAndSamplers,
            int fNumTexSamplers;
            PODArray<int> fTextureIndices;
            PODArray<int> fSamplerIndices);
COMMAND(SetScissor,
            SkIRect fScissor);
COMMAND(Draw,
            PrimitiveType fType;
            uint32_t fBaseVertex;
            uint32_t fVertexCount);
COMMAND(DrawIndexed,
            PrimitiveType fType;
            uint32_t fBaseIndex;
            uint32_t fIndexCount;
            uint32_t fBaseVertex);
COMMAND(DrawInstanced,
            PrimitiveType fType;
            uint32_t fBaseVertex;
            uint32_t fVertexCount;
            uint32_t fBaseInstance;
            uint32_t fInstanceCount);
COMMAND(DrawIndexedInstanced,
            PrimitiveType fType;
            uint32_t fBaseIndex;
            uint32_t fIndexCount;
            uint32_t fBaseVertex;
            uint32_t fBaseInstance;
            uint32_t fInstanceCount);

#undef COMMAND

#define ASSERT_TRIV_DES(T) static_assert(std::is_trivially_destructible<T>::value);
SKGPU_DRAW_PASS_COMMAND_TYPES(ASSERT_TRIV_DES)
#undef ASSERT_TRIV_DES
#define ASSERT_TRIV_CPY(T) static_assert(std::is_trivially_copyable<T>::value);
SKGPU_DRAW_PASS_COMMAND_TYPES(ASSERT_TRIV_CPY)
#undef ASSERT_TRIV_CPY

class List {
public:
    List() = default;
    ~List() = default;

    void bindGraphicsPipeline(uint32_t pipelineIndex) {
        this->add<BindGraphicsPipeline>(pipelineIndex);
    }

    void setBlendConstants(std::array<float, 4>  blendConstants) {
        this->add<SetBlendConstants>(this->copy(blendConstants.data(), 4));
    }

    void bindUniformBuffer(BindBufferInfo info, UniformSlot slot) {
        this->add<BindUniformBuffer>(info, slot);
    }

    // Caller must write 'numTexSamplers' texture and sampler indices into the two returned arrays.
    std::pair<int*, int*>
    bindDeferredTexturesAndSamplers(int numTexSamplers) {
        int* textureIndices = fAlloc.makeArrayDefault<int>(numTexSamplers);
        int* samplerIndices = fAlloc.makeArrayDefault<int>(numTexSamplers);
        this->add<BindTexturesAndSamplers>(numTexSamplers, textureIndices, samplerIndices);
        return {textureIndices, samplerIndices};
    }

    void setScissor(SkIRect scissor) {
        this->add<SetScissor>(scissor);
    }

    void bindDrawBuffers(BindBufferInfo vertexAttribs,
                         BindBufferInfo instanceAttribs,
                         BindBufferInfo indices) {
        this->add<BindDrawBuffers>(vertexAttribs, instanceAttribs, indices);
    }

    void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) {
        this->add<Draw>(type, baseVertex, vertexCount);
    }

    void drawIndexed(PrimitiveType type, unsigned int baseIndex,
                     unsigned int indexCount, unsigned int baseVertex) {
        this->add<DrawIndexed>(type, baseIndex, indexCount, baseVertex);
    }

    void drawInstanced(PrimitiveType type,
                       unsigned int baseVertex, unsigned int vertexCount,
                       unsigned int baseInstance, unsigned int instanceCount) {
        this->add<DrawInstanced>(type, baseVertex, vertexCount, baseInstance, instanceCount);
    }

    void drawIndexedInstanced(PrimitiveType type,
                              unsigned int baseIndex, unsigned int indexCount,
                              unsigned int baseVertex, unsigned int baseInstance,
                              unsigned int instanceCount) {
        this->add<DrawIndexedInstanced>(type,
                                        baseIndex,
                                        indexCount,
                                        baseVertex,
                                        baseInstance,
                                        instanceCount);
    }

    using Command = std::pair<Type, void*>;
    using Iter = SkTBlockList<Command>::CIter;
    Iter commands() const { return fCommands.items(); }

private:
    template <typename T, typename... Args>
    void add(Args&&... args) {
        T* cmd = fAlloc.make<T>(T{std::forward<Args>(args)...});
        fCommands.push_back(std::make_pair(T::kType, cmd));
    }

    // This copy() is for arrays.
    // It will work with POD only arrays.
    template <typename T>
    T* copy(const T src[], size_t count) {
        static_assert(std::is_trivially_copyable<T>::value);
        T* dst = fAlloc.makeArrayDefault<T>(count);
        memcpy(dst, src, count*sizeof(T));
        return dst;
    }

    SkTBlockList<Command> fCommands;

    // fAlloc needs to be a data structure which can append variable length data in contiguous
    // chunks, returning a stable handle to that data for later retrieval.
    SkArenaAlloc fAlloc{256};
};

} // namespace DrawPassCommands

} // namespace skgpu::graphite

#endif // skgpu_graphite_DrawPassCommands_DEFINED
