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

#include "GrGLVertexArray.h"
#include "GrGLGpu.h"

struct AttribLayout {
    GrGLint     fCount;
    GrGLenum    fType;
    GrGLboolean fNormalized;  // Only used by floating point types.
};

static const AttribLayout gLayouts[kGrVertexAttribTypeCount] = {
    {1, GR_GL_FLOAT, false},         // kFloat_GrVertexAttribType
    {2, GR_GL_FLOAT, false},         // kVec2f_GrVertexAttribType
    {3, GR_GL_FLOAT, false},         // kVec3f_GrVertexAttribType
    {4, GR_GL_FLOAT, false},         // kVec4f_GrVertexAttribType
    {1, GR_GL_UNSIGNED_BYTE, true},  // kUByte_GrVertexAttribType
    {4, GR_GL_UNSIGNED_BYTE, true},  // kVec4ub_GrVertexAttribType
    {2, GR_GL_SHORT, false},         // kVec2s_GrVertexAttribType
    {1, GR_GL_INT, false},           // kInt_GrVertexAttribType
    {1, GR_GL_UNSIGNED_INT, false},  // kUint_GrVertexAttribType
};

GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType);
GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);

void GrGLAttribArrayState::set(GrGLGpu* gpu,
                               int index,
                               GrGLuint vertexBufferID,
                               GrVertexAttribType type,
                               GrGLsizei stride,
                               GrGLvoid* offset) {
    SkASSERT(index >= 0 && index < fAttribArrayStates.count());
    AttribArrayState* array = &fAttribArrayStates[index];
    if (!array->fEnableIsValid || !array->fEnabled) {
        GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
        array->fEnableIsValid = true;
        array->fEnabled = true;
    }
    if (!array->fAttribPointerIsValid ||
        array->fVertexBufferID != vertexBufferID ||
        array->fType != type ||
        array->fStride != stride ||
        array->fOffset != offset) {

        gpu->bindVertexBuffer(vertexBufferID);
        const AttribLayout& layout = gLayouts[type];
        if (!GrVertexAttribTypeIsIntType(type)) {
            GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
                                                               layout.fCount,
                                                               layout.fType,
                                                               layout.fNormalized,
                                                               stride,
                                                               offset));
        } else {
            SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
            SkASSERT(!layout.fNormalized);
            GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
                                                                layout.fCount,
                                                                layout.fType,
                                                                stride,
                                                                offset));
        }
        array->fAttribPointerIsValid = true;
        array->fVertexBufferID = vertexBufferID;
        array->fType = type;
        array->fStride = stride;
        array->fOffset = offset;
    }
}

void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) {
    int count = fAttribArrayStates.count();
    for (int i = 0; i < count; ++i) {
        if (!(usedMask & 0x1)) {
            if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) {
                GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
                fAttribArrayStates[i].fEnableIsValid = true;
                fAttribArrayStates[i].fEnabled = false;
            }
        } else {
            SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled);
        }
        // if the count is greater than 64 then this will become 0 and we will disable arrays 64+.
        usedMask >>= 1;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
    : fID(id)
    , fAttribArrays(attribCount)
    , fIndexBufferIDIsValid(false) {
}

GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
    if (0 == fID) {
        return nullptr;
    }
    gpu->bindVertexArray(fID);
    return &fAttribArrays;
}

GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint ibufferID) {
    GrGLAttribArrayState* state = this->bind(gpu);
    if (state) {
        if (!fIndexBufferIDIsValid || ibufferID != fIndexBufferID) {            
            GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibufferID));
            fIndexBufferIDIsValid = true;
            fIndexBufferID = ibufferID;
        }
    }
    return state;
}

void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
    if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
        fIndexBufferID = 0;
    }
 }

void GrGLVertexArray::invalidateCachedState() {
    fAttribArrays.invalidate();
    fIndexBufferIDIsValid = false;
}
