/*
* 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 "GLSharedGroup.h"

#include "KeyedVectorUtils.h"

/**** BufferData ****/

BufferData::BufferData() : m_size(0), m_usage(0), m_mapped(false) {};

BufferData::BufferData(GLsizeiptr size, const void* data) :
    m_size(size), m_usage(0), m_mapped(false) {

    void * buffer = NULL;

    if (size>0) buffer = m_fixedBuffer.alloc(size);

    if (data) memcpy(buffer, data, size);
}

/**** ProgramData ****/
ProgramData::ProgramData() : m_numIndexes(0),
                             m_initialized(false) {
    m_Indexes = NULL;
}

void ProgramData::initProgramData(GLuint numIndexes) {
    m_initialized = true;
    m_numIndexes = numIndexes;

    delete [] m_Indexes;

    m_Indexes = new IndexInfo[numIndexes];
}

bool ProgramData::isInitialized() {
    return m_initialized;
}

ProgramData::~ProgramData() {

    delete [] m_Indexes;

    m_Indexes = NULL;
}

void ProgramData::setIndexInfo(
    GLuint index, GLint base, GLint size, GLenum type) {

    if (index >= m_numIndexes) return;

    m_Indexes[index].base = base;
    m_Indexes[index].size = size;
    m_Indexes[index].type = type;
    m_Indexes[index].hostLocsPerElement = 1;
    m_Indexes[index].flags = 0;
    m_Indexes[index].samplerValue = 0;
}

void ProgramData::setIndexFlags(GLuint index, GLuint flags) {

    if (index >= m_numIndexes) return;

    m_Indexes[index].flags |= flags;
}

GLuint ProgramData::getIndexForLocation(GLint location) {
    GLuint index = m_numIndexes;

    GLint minDist = -1;

    for (GLuint i = 0; i < m_numIndexes; ++i) {
        GLint dist = location - m_Indexes[i].base;
        if (dist >= 0 && (minDist < 0 || dist < minDist)) {
            index = i;
            minDist = dist;
        }
    }

    return index;
}

GLenum ProgramData::getTypeForLocation(GLint location) {
    GLuint index = getIndexForLocation(location);
    if (index < m_numIndexes) {
        return m_Indexes[index].type;
    }
    return 0;
}

GLint ProgramData::getNextSamplerUniform(
    GLint index, GLint* val, GLenum* target) {

    for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {

        if (m_Indexes[i].type == GL_SAMPLER_2D) {

            if (val) *val = m_Indexes[i].samplerValue;

            if (target) {
                if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
                    *target = GL_TEXTURE_EXTERNAL_OES;
                } else {
                    *target = GL_TEXTURE_2D;
                }
            }

            return i;
        }

    }

    return -1;
}

bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target) {

    for (GLuint i = 0; i < m_numIndexes; i++) {

        GLint elemIndex = appLoc - m_Indexes[i].base;

        if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
            if (m_Indexes[i].type == GL_SAMPLER_2D) {
                m_Indexes[i].samplerValue = val;
                if (target) {
                    if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
                        *target = GL_TEXTURE_EXTERNAL_OES;
                    } else {
                        *target = GL_TEXTURE_2D;

                    }
                }
                return true;
            }
        }
    }

    return false;
}

bool ProgramData::attachShader(GLuint shader) {
    size_t n = m_shaders.size();

    for (size_t i = 0; i < n; i++) {
        if (m_shaders[i] == shader) {
            return false;
        }
    }
    m_shaders.push_back(shader);
    return true;
}

bool ProgramData::detachShader(GLuint shader) {
    size_t n = m_shaders.size();

    for (size_t i = 0; i < n; i++) {
        if (m_shaders[i] == shader) {
            m_shaders.erase(m_shaders.begin() + i);
            return true;
        }
    }

    return false;
}

/***** GLSharedGroup ****/

GLSharedGroup::GLSharedGroup() { }

GLSharedGroup::~GLSharedGroup() {
    m_buffers.clear();
    m_programs.clear();
    clearObjectMap(m_buffers);
    clearObjectMap(m_programs);
    clearObjectMap(m_shaders);
    clearObjectMap(m_shaderPrograms);
}

bool GLSharedGroup::isShaderOrProgramObject(GLuint obj) {

    android::AutoMutex _lock(m_lock);

    return (findObjectOrDefault(m_shaders, obj) ||
            findObjectOrDefault(m_programs, obj) ||
            findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[obj]));
}

BufferData* GLSharedGroup::getBufferData(GLuint bufferId) {

    android::AutoMutex _lock(m_lock);

    return findObjectOrDefault(m_buffers, bufferId);
}

SharedTextureDataMap* GLSharedGroup::getTextureData() {
    return &m_textureRecs;
}

void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, const void* data) {

    android::AutoMutex _lock(m_lock);

    m_buffers[bufferId] = new BufferData(size, data);
}

void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, const void* data) {

    android::AutoMutex _lock(m_lock);

    BufferData* currentBuffer = findObjectOrDefault(m_buffers, bufferId);

    if (currentBuffer) delete currentBuffer;

    m_buffers[bufferId] = new BufferData(size, data);
}

void GLSharedGroup::setBufferUsage(GLuint bufferId, GLenum usage) {

    android::AutoMutex _lock(m_lock);

    BufferData* data = findObjectOrDefault(m_buffers, bufferId);

    if (data) data->m_usage = usage;
}

void GLSharedGroup::setBufferMapped(GLuint bufferId, bool mapped) {
    BufferData* buf = findObjectOrDefault(m_buffers, bufferId);

    if (!buf) return;

    buf->m_mapped = mapped;
}

GLenum GLSharedGroup::getBufferUsage(GLuint bufferId) {
    BufferData* buf = findObjectOrDefault(m_buffers, bufferId);

    if (!buf) return 0;

    return buf->m_usage;
}

bool GLSharedGroup::isBufferMapped(GLuint bufferId) {
    BufferData* buf = findObjectOrDefault(m_buffers, bufferId);

    if (!buf) return false;

    return buf->m_mapped;
}

GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, const void* data) {

    android::AutoMutex _lock(m_lock);

    BufferData* buf = findObjectOrDefault(m_buffers, bufferId);

    if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) {
        return GL_INVALID_VALUE;
    }

    memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);

    buf->m_indexRangeCache.invalidateRange((size_t)offset, (size_t)size);
    return GL_NO_ERROR;
}

void GLSharedGroup::deleteBufferData(GLuint bufferId) {

    android::AutoMutex _lock(m_lock);

    BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
    if (buf) {
        delete buf;
        m_buffers.erase(bufferId);
    }
}

void GLSharedGroup::addProgramData(GLuint program) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);
    if (pData) {
        delete pData;
    }

    m_programs[program] = new ProgramData();
}

void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);
    if (pData) {
        pData->initProgramData(numIndexes);
    }
}

bool GLSharedGroup::isProgramInitialized(GLuint program) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);

    if (pData) {
        return pData->isInitialized();
    }

    if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) {
        return false;
    }

    ShaderProgramData* shaderProgramData =
        findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);

    if (shaderProgramData) {
        return shaderProgramData->programData.isInitialized();
    }

    return false;
}

void GLSharedGroup::deleteProgramData(GLuint program) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);

    if (pData) delete pData;

    m_programs.erase(program);

    if (m_shaderProgramIdMap.find(program) ==
        m_shaderProgramIdMap.end()) return;

    ShaderProgramData* spData =
        findObjectOrDefault(
            m_shaderPrograms, m_shaderProgramIdMap[program]);

    if (spData) delete spData;

    m_shaderPrograms.erase(m_shaderProgramIdMap[program]);
    m_shaderProgramIdMap.erase(program);
}

// No such thing for separable shader programs.
void GLSharedGroup::attachShader(GLuint program, GLuint shader) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);
    ShaderData* sData = findObjectOrDefault(m_shaders, shader);

    if (pData && sData) {
        if (pData->attachShader(shader)) {
            refShaderDataLocked(shader);
        }
    }
}

void GLSharedGroup::detachShader(GLuint program, GLuint shader) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);
    ShaderData* sData = findObjectOrDefault(m_shaders, shader);
    if (pData && sData) {
        if (pData->detachShader(shader)) {
            unrefShaderDataLocked(shader);
        }
    }
}

// Not needed/used for separate shader programs.
void GLSharedGroup::setProgramIndexInfo(
    GLuint program, GLuint index, GLint base,
    GLint size, GLenum type, const char* name) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);

    if (pData) {
        pData->setIndexInfo(index,base,size,type);
        if (type == GL_SAMPLER_2D) {
            size_t n = pData->getNumShaders();
            for (size_t i = 0; i < n; i++) {
                GLuint shaderId = pData->getShader(i);
                ShaderData* shader = findObjectOrDefault(m_shaders, shaderId);
                if (!shader) continue;
                ShaderData::StringList::iterator nameIter =
                    shader->samplerExternalNames.begin();
                ShaderData::StringList::iterator nameEnd =
                    shader->samplerExternalNames.end();
                while (nameIter != nameEnd) {
                    if (*nameIter == name) {
                        pData->setIndexFlags(
                            index,
                            ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
                        break;
                    }
                    ++nameIter;
                }
            }
        }
    }
}

GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);
    GLenum type = 0;

    if (pData) {
        type = pData->getTypeForLocation(location);
    }

    if (m_shaderProgramIdMap.find(program) ==
        m_shaderProgramIdMap.end()) return type;

    ShaderProgramData* spData =
        findObjectOrDefault(
            m_shaderPrograms, m_shaderProgramIdMap[program]);

    if (spData) {
        type = spData->programData.getTypeForLocation(location);
    }

    return type;
}

bool GLSharedGroup::isProgram(GLuint program) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);

    if (pData) return true;

    if (m_shaderProgramIdMap.find(program) ==
        m_shaderProgramIdMap.end()) return false;

    ShaderProgramData* spData =
        findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);

    if (spData) return true;

    return false;
}

GLint GLSharedGroup::getNextSamplerUniform(
    GLuint program, GLint index, GLint* val, GLenum* target) const {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData = findObjectOrDefault(m_programs, program);

    if (pData) return pData->getNextSamplerUniform(index, val, target);

    if (m_shaderProgramIdMap.find(program) ==
        m_shaderProgramIdMap.end()) return -1;

    ShaderProgramData* spData =
        findObjectOrDefault(
            m_shaderPrograms,
            findObjectOrDefault(m_shaderProgramIdMap, program));

    if (spData) return spData->programData.getNextSamplerUniform(index, val, target);

    return -1;
}

bool GLSharedGroup::setSamplerUniform(
    GLuint program, GLint appLoc, GLint val, GLenum* target) {

    android::AutoMutex _lock(m_lock);

    ProgramData* pData =
        findObjectOrDefault(m_programs, program);

    if (pData) return pData->setSamplerUniform(appLoc, val, target);

    if (m_shaderProgramIdMap.find(program) ==
        m_shaderProgramIdMap.end()) return false;

    ShaderProgramData* spData =
        findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);

    if (spData) return spData->programData.setSamplerUniform(appLoc, val, target);

    return false;
}

bool GLSharedGroup::isShader(GLuint shader) {

    android::AutoMutex _lock(m_lock);

    ShaderData* pData = findObjectOrDefault(m_shaders, shader);

    return pData != NULL;
}

bool GLSharedGroup::addShaderData(GLuint shader) {

    android::AutoMutex _lock(m_lock);

    ShaderData* data = new ShaderData;

    if (data) {
        m_shaders[shader] = data;
        data->refcount = 1;
    }

    return data != NULL;
}

ShaderData* GLSharedGroup::getShaderData(GLuint shader) {

    android::AutoMutex _lock(m_lock);

    return findObjectOrDefault(m_shaders, shader);
}

void GLSharedGroup::unrefShaderData(GLuint shader) {

    android::AutoMutex _lock(m_lock);

    unrefShaderDataLocked(shader);
}

void GLSharedGroup::refShaderDataLocked(GLuint shaderId) {
    ShaderData* data = findObjectOrDefault(m_shaders, shaderId);
    data->refcount++;
}

void GLSharedGroup::unrefShaderDataLocked(GLuint shaderId) {
    ShaderData* data = findObjectOrDefault(m_shaders, shaderId);

    if (data && --data->refcount == 0) {

        delete data;

        m_shaders.erase(shaderId);
    }
}

uint32_t GLSharedGroup::addNewShaderProgramData() {

    android::AutoMutex _lock(m_lock);

    ShaderProgramData* data = new ShaderProgramData;
    uint32_t currId = m_shaderProgramId;

    ALOGD("%s: new data %p id %u", __FUNCTION__, data, currId);

    m_shaderPrograms[currId] = data;
    m_shaderProgramId++;
    return currId;
}

void GLSharedGroup::associateGLShaderProgram(
    GLuint shaderProgramName, uint32_t shaderProgramId) {

    android::AutoMutex _lock(m_lock);

    m_shaderProgramIdMap[shaderProgramName] = shaderProgramId;
}

ShaderProgramData* GLSharedGroup::getShaderProgramDataById(uint32_t id) {

    android::AutoMutex _lock(m_lock);

    ShaderProgramData* res = findObjectOrDefault(m_shaderPrograms, id);

    ALOGD("%s: id=%u res=%p", __FUNCTION__, id, res);

    return res;
}

ShaderProgramData* GLSharedGroup::getShaderProgramData(
    GLuint shaderProgramName) {

    android::AutoMutex _lock(m_lock);

    return findObjectOrDefault(m_shaderPrograms,
                               m_shaderProgramIdMap[shaderProgramName]);
}

void GLSharedGroup::deleteShaderProgramDataById(uint32_t id) {

    android::AutoMutex _lock(m_lock);

    ShaderProgramData* data =
        findObjectOrDefault(m_shaderPrograms, id);

    delete data;

    m_shaderPrograms.erase(id);
}


void GLSharedGroup::deleteShaderProgramData(GLuint shaderProgramName) {

    android::AutoMutex _lock(m_lock);

    uint32_t id = m_shaderProgramIdMap[shaderProgramName];
    ShaderProgramData* data = findObjectOrDefault(m_shaderPrograms, id);

    delete data;

    m_shaderPrograms.erase(id);
    m_shaderProgramIdMap.erase(shaderProgramName);
}

void GLSharedGroup::initShaderProgramData(GLuint shaderProgram, GLuint numIndices) {
    ShaderProgramData* spData = getShaderProgramData(shaderProgram);
    spData->programData.initProgramData(numIndices);
}

void GLSharedGroup::setShaderProgramIndexInfo(
    GLuint shaderProgram, GLuint index, GLint base,
    GLint size, GLenum type, const char* name) {

    ShaderProgramData* spData = getShaderProgramData(shaderProgram);
    ProgramData& pData = spData->programData;
    ShaderData& sData = spData->shaderData;

    pData.setIndexInfo(index, base, size, type);

    if (type == GL_SAMPLER_2D) {

        ShaderData::StringList::iterator nameIter =
            sData.samplerExternalNames.begin();
        ShaderData::StringList::iterator nameEnd =
            sData.samplerExternalNames.end();

        while (nameIter != nameEnd) {
            if (*nameIter == name) {
                pData.setIndexFlags(
                    index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
                break;
            }
            ++nameIter;
        }
    }
}
