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

#ifndef GrMesh_DEFINED
#define GrMesh_DEFINED

#include "GrBuffer.h"
#include "GrPendingIOResource.h"
#include "GrGpuBuffer.h"

class GrPrimitiveProcessor;

/**
 * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrOp to
 * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
 * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
 * already (stride, attribute mappings).
 */
class GrMesh {
public:
    GrMesh(GrPrimitiveType primitiveType = GrPrimitiveType::kTriangles)
            : fPrimitiveType(primitiveType), fBaseVertex(0) {
        SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
    }

    void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
    GrPrimitiveType primitiveType() const { return fPrimitiveType; }

    bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }
    GrPrimitiveRestart primitiveRestart() const {
        return GrPrimitiveRestart(fFlags & Flags::kUsePrimitiveRestart);
    }
    bool isInstanced() const { return fFlags & Flags::kIsInstanced; }
    bool hasInstanceData() const { return SkToBool(fInstanceBuffer.get()); }
    bool hasVertexData() const { return SkToBool(fVertexBuffer.get()); }

    void setNonIndexedNonInstanced(int vertexCount);

    void setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
                    uint16_t minIndexValue, uint16_t maxIndexValue, GrPrimitiveRestart);
    void setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount, int vertexCount,
                             int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer);

    void setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount, int baseInstance,
                      int vertexCount);
    void setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
                             sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
                             int baseInstance, GrPrimitiveRestart);

    void setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex = 0);

    class SendToGpuImpl {
    public:
        virtual void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
                                   int baseVertex) = 0;

        virtual void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
                                          int indexCount, int baseIndex, uint16_t minIndexValue,
                                          uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
                                          int baseVertex, GrPrimitiveRestart) = 0;

        virtual void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer,
                                            int vertexCount, int baseVertex,
                                            const GrBuffer* instanceBuffer, int instanceCount,
                                            int baseInstance) = 0;

        virtual void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
                                                   int indexCount, int baseIndex,
                                                   const GrBuffer* vertexBuffer, int baseVertex,
                                                   const GrBuffer* instanceBuffer,
                                                   int instanceCount, int baseInstance,
                                                   GrPrimitiveRestart) = 0;

        virtual ~SendToGpuImpl() {}
    };

    void sendToGpu(SendToGpuImpl*) const;

private:
    enum class Flags {
        kNone = 0,
        kUsePrimitiveRestart = 1 << 0,
        kIsInstanced = 1 << 1,
    };

    GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
    GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kNo) == Flags::kNone);
    GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kYes) == Flags::kUsePrimitiveRestart);

    GrPrimitiveType fPrimitiveType;
    sk_sp<const GrBuffer> fIndexBuffer;
    sk_sp<const GrBuffer> fInstanceBuffer;
    sk_sp<const GrBuffer> fVertexBuffer;
    int fBaseVertex;
    Flags fFlags;

    union {
        struct { // When fIndexBuffer == nullptr and isInstanced() == false.
            int   fVertexCount;
        } fNonIndexNonInstanceData;

        struct { // When fIndexBuffer != nullptr and isInstanced() == false.
            struct {
                int   fIndexCount;
                int   fPatternRepeatCount;
            } fIndexData;

            union {
                struct { // When fPatternRepeatCount == 0.
                    int        fBaseIndex;
                    uint16_t   fMinIndexValue;
                    uint16_t   fMaxIndexValue;
                } fNonPatternIndexData;

                struct { // When fPatternRepeatCount != 0.
                    int   fVertexCount;
                    int   fMaxPatternRepetitionsInIndexBuffer;
                } fPatternData;
            };
        };

        struct { // When isInstanced() != false.
            struct {
                int   fInstanceCount;
                int   fBaseInstance;
            } fInstanceData;

            union { // When fIndexBuffer == nullptr.
                struct {
                    int   fVertexCount;
                } fInstanceNonIndexData;

                struct { // When fIndexBuffer != nullptr.
                    int   fIndexCount;
                } fInstanceIndexData;
            };
        };
    };
};

GR_MAKE_BITFIELD_CLASS_OPS(GrMesh::Flags);

inline void GrMesh::setNonIndexedNonInstanced(int vertexCount) {
    fIndexBuffer.reset();
    fInstanceBuffer.reset();
    fNonIndexNonInstanceData.fVertexCount = vertexCount;
    fFlags = Flags::kNone;
}

inline void GrMesh::setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
                               uint16_t minIndexValue, uint16_t maxIndexValue,
                               GrPrimitiveRestart primitiveRestart) {
    SkASSERT(indexBuffer);
    SkASSERT(indexCount >= 1);
    SkASSERT(baseIndex >= 0);
    SkASSERT(maxIndexValue >= minIndexValue);
    fIndexBuffer = std::move(indexBuffer);
    fInstanceBuffer.reset();
    fIndexData.fIndexCount = indexCount;
    fIndexData.fPatternRepeatCount = 0;
    fNonPatternIndexData.fBaseIndex = baseIndex;
    fNonPatternIndexData.fMinIndexValue = minIndexValue;
    fNonPatternIndexData.fMaxIndexValue = maxIndexValue;
    fFlags = Flags(primitiveRestart);
}

inline void GrMesh::setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount,
                                        int vertexCount, int patternRepeatCount,
                                        int maxPatternRepetitionsInIndexBuffer) {
    SkASSERT(indexBuffer);
    SkASSERT(indexCount >= 1);
    SkASSERT(vertexCount >= 1);
    SkASSERT(patternRepeatCount >= 1);
    SkASSERT(maxPatternRepetitionsInIndexBuffer >= 1);
    fIndexBuffer = std::move(indexBuffer);
    fInstanceBuffer.reset();
    fIndexData.fIndexCount = indexCount;
    fIndexData.fPatternRepeatCount = patternRepeatCount;
    fPatternData.fVertexCount = vertexCount;
    fPatternData.fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer;
    fFlags = Flags::kNone;
}

inline void GrMesh::setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
                                 int baseInstance, int vertexCount) {
    SkASSERT(instanceCount >= 1);
    SkASSERT(baseInstance >= 0);
    fIndexBuffer.reset();
    fInstanceBuffer = std::move(instanceBuffer);
    fInstanceData.fInstanceCount = instanceCount;
    fInstanceData.fBaseInstance = baseInstance;
    fInstanceNonIndexData.fVertexCount = vertexCount;
    fFlags = Flags::kIsInstanced;
}

inline void GrMesh::setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
                                        sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
                                        int baseInstance, GrPrimitiveRestart primitiveRestart) {
    SkASSERT(indexBuffer);
    SkASSERT(indexCount >= 1);
    SkASSERT(instanceCount >= 1);
    SkASSERT(baseInstance >= 0);
    fIndexBuffer = std::move(indexBuffer);
    fInstanceBuffer = std::move(instanceBuffer);
    fInstanceData.fInstanceCount = instanceCount;
    fInstanceData.fBaseInstance = baseInstance;
    fInstanceIndexData.fIndexCount = indexCount;
    fFlags = Flags::kIsInstanced | Flags(primitiveRestart);
}

inline void GrMesh::setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex) {
    SkASSERT(baseVertex >= 0);
    fVertexBuffer = std::move(vertexBuffer);
    fBaseVertex = baseVertex;
}

inline void GrMesh::sendToGpu(SendToGpuImpl* impl) const {
    if (this->isInstanced()) {
        if (!this->isIndexed()) {
            impl->sendInstancedMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
                                         fInstanceNonIndexData.fVertexCount, fBaseVertex,
                                         fInstanceBuffer.get(), fInstanceData.fInstanceCount,
                                         fInstanceData.fBaseInstance);
        } else {
            impl->sendIndexedInstancedMeshToGpu(
                    fPrimitiveType, fIndexBuffer.get(), fInstanceIndexData.fIndexCount, 0,
                    fVertexBuffer.get(), fBaseVertex, fInstanceBuffer.get(),
                    fInstanceData.fInstanceCount, fInstanceData.fBaseInstance,
                    this->primitiveRestart());
        }
        return;
    }

    if (!this->isIndexed()) {
        SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0);
        impl->sendMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
                            fNonIndexNonInstanceData.fVertexCount, fBaseVertex);
        return;
    }

    if (0 == fIndexData.fPatternRepeatCount) {
        impl->sendIndexedMeshToGpu(
                fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount,
                fNonPatternIndexData.fBaseIndex, fNonPatternIndexData.fMinIndexValue,
                fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(), fBaseVertex,
                this->primitiveRestart());
        return;
    }

    SkASSERT(fIndexData.fPatternRepeatCount > 0);
    int baseRepetition = 0;
    do {
        int repeatCount = SkTMin(fPatternData.fMaxPatternRepetitionsInIndexBuffer,
                                 fIndexData.fPatternRepeatCount - baseRepetition);
        // A patterned index buffer must contain indices in the range [0..vertexCount].
        int minIndexValue = 0;
        int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1;
        SkASSERT(!(fFlags & Flags::kUsePrimitiveRestart));
        impl->sendIndexedMeshToGpu(
                fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount * repeatCount, 0,
                minIndexValue, maxIndexValue, fVertexBuffer.get(),
                fBaseVertex + fPatternData.fVertexCount * baseRepetition, GrPrimitiveRestart::kNo);
        baseRepetition += repeatCount;
    } while (baseRepetition < fIndexData.fPatternRepeatCount);
}

#endif
