/*
 * 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 namespace android;
using namespace android::renderscript;

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.setTo("");
}

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.setTo(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.string(),
          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;
    }
}

