/*
 * Copyright (C) 2009 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 "rsContext.h"

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

using namespace android;
using namespace android::renderscript;


ShaderCache::ShaderCache()
{
    mEntryCount = 0;
    mEntryAllocationCount = 16;
    mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t));
}

ShaderCache::~ShaderCache()
{
    for (uint32_t ct=0; ct < mEntryCount; ct++) {
        glDeleteProgram(mEntries[ct].program);
    }

    mEntryCount = 0;
    mEntryAllocationCount = 0;
    free(mEntries);
}

bool ShaderCache::lookup(ProgramVertex *vtx, ProgramFragment *frag)
{
    if (!vtx->getShaderID()) {
        vtx->loadShader();
    }
    if (!frag->getShaderID()) {
        frag->loadShader();
    }

    for (uint32_t ct=0; ct < mEntryCount; ct++) {
        if ((mEntries[ct].vtx == vtx->getShaderID()) &&
            (mEntries[ct].frag == frag->getShaderID())) {

            //LOGV("SC using program %i", mEntries[ct].program);
            glUseProgram(mEntries[ct].program);
            mCurrent = &mEntries[ct];
            return true;
        }
    }
    // Not in cache, add it.

    if (mEntryAllocationCount == mEntryCount) {
        // Out of space, make some.
        mEntryAllocationCount *= 2;
        entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t));
        if (!e) {
            LOGE("Out of memory for ShaderCache::lookup");
            return false;
        }
        memcpy(e, mEntries, sizeof(entry_t) * mEntryCount);
        free(mEntries);
        mEntries = e;
    }

    LOGV("vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
    LOGE("e0 %x", glGetError());

    entry_t *e = &mEntries[mEntryCount];
    mCurrent = e;
    e->vtx = vtx->getShaderID();
    e->frag = frag->getShaderID();
    e->program = glCreateProgram();
    if (mEntries[mEntryCount].program) {
        GLuint pgm = e->program;
        glAttachShader(pgm, vtx->getShaderID());
        //LOGE("e1 %x", glGetError());
        glAttachShader(pgm, frag->getShaderID());

        glBindAttribLocation(pgm, VertexArray::POSITION, "attrib_Position");
        glBindAttribLocation(pgm, VertexArray::COLOR, "attrib_Color");


        //LOGE("e2 %x", glGetError());
        glLinkProgram(pgm);
        //LOGE("e3 %x", glGetError());
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char* buf = (char*) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(pgm, bufLength, NULL, buf);
                    LOGE("Could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            glDeleteProgram(pgm);
        }
        for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) {
            e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct));
            LOGV("vtx A, %s = %d\n", vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]);
        }
        for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
            e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct));
            LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]);
        }
        for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
            e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct));
            LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]);
        }
    }

    LOGV("SC made program %i", e->program);
    glUseProgram(e->program);
    mEntryCount++;
    return true;
}

void ShaderCache::cleanupVertex(uint32_t id)
{
}

void ShaderCache::cleanupFragment(uint32_t id)
{
}

void ShaderCache::cleanupAll()
{
}

