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

#ifndef GrGLVertexArray_DEFINED
#define GrGLVertexArray_DEFINED

#include "include/gpu/gl/GrGLTypes.h"
#include "include/private/GrTypesPriv.h"
#include "include/private/SkTArray.h"
#include "src/gpu/GrGpuResource.h"
#include "src/gpu/gl/GrGLDefines.h"

class GrBuffer;
class GrGLGpu;

/**
 * This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray
 * (below) but is separate because it is also used to track the state of vertex array object 0.
 */
class GrGLAttribArrayState {
public:
    explicit GrGLAttribArrayState(int arrayCount = 0) {
        this->resize(arrayCount);
    }

    void resize(int newCount) {
        fAttribArrayStates.resize_back(newCount);
        this->invalidate();
    }

    /**
     * This function enables and sets vertex attrib state for the specified attrib index. It is
     * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex
     * array object.
     */
    void set(GrGLGpu*,
             int attribIndex,
             const GrBuffer* vertexBuffer,
             GrVertexAttribType cpuType,
             GrSLType gpuType,
             GrGLsizei stride,
             size_t offsetInBytes,
             int divisor = 0);

    /**
     * This function enables the first 'enabledCount' vertex arrays and disables the rest.
     */
    void enableVertexArrays(const GrGLGpu*, int enabledCount,
                            GrPrimitiveRestart = GrPrimitiveRestart::kNo);

    void invalidate() {
        int count = fAttribArrayStates.count();
        for (int i = 0; i < count; ++i) {
            fAttribArrayStates[i].invalidate();
        }
        fEnableStateIsValid = false;
    }

    /**
     * The number of attrib arrays that this object is configured to track.
     */
    int count() const { return fAttribArrayStates.count(); }

private:
    static constexpr int kInvalidDivisor = -1;

    /**
     * Tracks the state of glVertexAttribArray for an attribute index.
     */
    struct AttribArrayState {
        void invalidate() {
            fVertexBufferUniqueID.makeInvalid();
            fDivisor = kInvalidDivisor;
            fUsingCpuBuffer = false;
        }

        GrGpuResource::UniqueID   fVertexBufferUniqueID;
        bool                      fUsingCpuBuffer;
        GrVertexAttribType        fCPUType;
        GrSLType                  fGPUType;
        GrGLsizei                 fStride;
        const GrGLvoid*           fOffset;
        int                       fDivisor;
    };

    SkSTArray<16, AttribArrayState, true> fAttribArrayStates;
    int fNumEnabledArrays;
    GrPrimitiveRestart fPrimitiveRestartEnabled;
    bool fEnableStateIsValid = false;
};

/**
 * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array
 * and is used to track the state of the vertex array to avoid redundant GL calls.
 */
class GrGLVertexArray {
public:
    GrGLVertexArray(GrGLint id, int attribCount);

    /**
     * Binds this vertex array. If the ID has been deleted or abandoned then nullptr is returned.
     * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is
     * returned.
     */
    GrGLAttribArrayState* bind(GrGLGpu*);

    /**
     * This is a version of the above function that also binds an index buffer to the vertex
     * array object.
     */
    GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* indexBuffer);

    GrGLuint arrayID() const { return fID; }

    void invalidateCachedState();

private:
    GrGLuint                  fID;
    GrGLAttribArrayState      fAttribArrays;
    GrGpuResource::UniqueID   fIndexBufferUniqueID;
};

#endif
