/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <rs_hal.h>
#include <rsContext.h>

#include <GLES/gl.h>
#include <GLES2/gl2.h>

#include "rsdGL.h"
#include "rsdCore.h"
#include "rsdVertexArray.h"
#include "rsdShaderCache.h"

using android::renderscript::Context;

RsdVertexArray::RsdVertexArray(const Attrib *attribs, uint32_t numAttribs) {
    mAttribs = attribs;
    mCount = numAttribs;
}

RsdVertexArray::~RsdVertexArray() {
}

RsdVertexArray::Attrib::Attrib() {
    clear();
}

void RsdVertexArray::Attrib::clear() {
    buffer = 0;
    offset = 0;
    type = 0;
    size = 0;
    stride = 0;
    ptr = nullptr;
    normalized = false;
    name.assign("");
}

void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
                              bool normalized, size_t offset,
                              const char *name) {
    clear();
    this->type = type;
    this->size = size;
    this->offset = offset;
    this->normalized = normalized;
    this->stride = stride;
    this->name.assign(name);
}

void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
    if (idx == 0) {
        ALOGV("Starting vertex attribute binding");
    }
    ALOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%p",
          idx, slot,
          mAttribs[idx].name.c_str(),
          mAttribs[idx].buffer,
          mAttribs[idx].ptr,
          mAttribs[idx].size,
          mAttribs[idx].type,
          mAttribs[idx].stride,
          mAttribs[idx].normalized,
          (void*)mAttribs[idx].offset);
}

void RsdVertexArray::setup(const Context *rsc) const {

    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
    RsdVertexArrayState *state = dc->gl.vertexArrayState;
    RsdShaderCache *sc = dc->gl.shaderCache;

    rsdGLCheckError(rsc, "RsdVertexArray::setup start");
    uint32_t maxAttrs = state->mAttrsEnabledSize;

    for (uint32_t ct=1; ct < maxAttrs; ct++) {
        if(state->mAttrsEnabled[ct]) {
            glDisableVertexAttribArray(ct);
            state->mAttrsEnabled[ct] = false;
        }
    }

    rsdGLCheckError(rsc, "RsdVertexArray::setup disabled");
    for (uint32_t ct=0; ct < mCount; ct++) {
        int32_t slot = sc->vtxAttribSlot(mAttribs[ct].name);
        if (rsc->props.mLogShadersAttr) {
            logAttrib(ct, slot);
        }
        if (slot < 0 || slot >= (int32_t)maxAttrs) {
            continue;
        }
        glEnableVertexAttribArray(slot);
        state->mAttrsEnabled[slot] = true;
        glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
        glVertexAttribPointer(slot,
                              mAttribs[ct].size,
                              mAttribs[ct].type,
                              mAttribs[ct].normalized,
                              mAttribs[ct].stride,
                              mAttribs[ct].ptr + mAttribs[ct].offset);
    }
    rsdGLCheckError(rsc, "RsdVertexArray::setup done");
}
////////////////////////////////////////////
RsdVertexArrayState::RsdVertexArrayState() {
    mAttrsEnabled = nullptr;
    mAttrsEnabledSize = 0;
}

RsdVertexArrayState::~RsdVertexArrayState() {
    if (mAttrsEnabled) {
        delete[] mAttrsEnabled;
        mAttrsEnabled = nullptr;
    }
}
void RsdVertexArrayState::init(uint32_t maxAttrs) {
    mAttrsEnabledSize = maxAttrs;
    mAttrsEnabled = new bool[mAttrsEnabledSize];
    for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
        mAttrsEnabled[ct] = false;
    }
}
