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

extern "C" {
#include "liblzf/lzf.h"
}

namespace android {

static pthread_key_t dbgEGLThreadLocalStorageKey = -1;
static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;

DbgContext * getDbgContextThreadSpecific() {
    return (DbgContext*)pthread_getspecific(dbgEGLThreadLocalStorageKey);
}

DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
                       const unsigned MAX_VERTEX_ATTRIBS)
        : lzf_buf(NULL), lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
        , version(version), hooks(hooks)
        , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
        , readBytesPerPixel(4)
        , captureSwap(0), captureDraw(0)
        , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
        , hasNonVBOAttribs(false), indexBuffers(NULL), indexBuffer(NULL)
        , program(0), maxAttrib(0)
{
    lzf_ref[0] = lzf_ref[1] = NULL;
    for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
        vertexAttribs[i] = VertexAttrib();
    memset(&expectResponse, 0, sizeof(expectResponse));
}

DbgContext::~DbgContext()
{
    delete vertexAttribs;
    free(lzf_buf);
    free(lzf_ref[0]);
    free(lzf_ref[1]);
}

DbgContext* CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks)
{
    pthread_mutex_lock(&gThreadLocalStorageKeyMutex);
    if (dbgEGLThreadLocalStorageKey == -1)
        pthread_key_create(&dbgEGLThreadLocalStorageKey, NULL);
    pthread_mutex_unlock(&gThreadLocalStorageKeyMutex);

    assert(version < 2);
    assert(GL_NO_ERROR == hooks->gl.glGetError());
    GLint MAX_VERTEX_ATTRIBS = 0;
    hooks->gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MAX_VERTEX_ATTRIBS);
    DbgContext* dbg = new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS);
    glesv2debugger::Message msg, cmd;
    msg.set_context_id(reinterpret_cast<int>(dbg));
    msg.set_expect_response(false);
    msg.set_type(msg.Response);
    msg.set_function(msg.SETPROP);
    msg.set_prop(msg.GLConstant);
    msg.set_arg0(GL_MAX_VERTEX_ATTRIBS);
    msg.set_arg1(MAX_VERTEX_ATTRIBS);
    Send(msg, cmd);

    GLint MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0;
    hooks->gl.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &MAX_COMBINED_TEXTURE_IMAGE_UNITS);
    msg.set_arg0(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
    msg.set_arg1(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
    Send(msg, cmd);

    pthread_setspecific(dbgEGLThreadLocalStorageKey, dbg);
    return dbg;
}

void dbgReleaseThread() {
    delete getDbgContextThreadSpecific();
}

unsigned GetBytesPerPixel(const GLenum format, const GLenum type)
{
    switch (type) {
    case GL_UNSIGNED_SHORT_5_6_5:
    case GL_UNSIGNED_SHORT_4_4_4_4:
    case GL_UNSIGNED_SHORT_5_5_5_1:
        return 2;
    case GL_UNSIGNED_BYTE:
        break;
    default:
        LOGE("GetBytesPerPixel: unknown type %x", type);
    }

    switch (format) {
    case GL_ALPHA:
    case GL_LUMINANCE:
        return 1;
    case GL_LUMINANCE_ALPHA:
        return 2;
    case GL_RGB:
        return 3;
    case GL_RGBA:
    case 0x80E1:   // GL_BGRA_EXT
        return 4;
    default:
        LOGE("GetBytesPerPixel: unknown format %x", format);
    }

    return 1; // in doubt...
}

void DbgContext::Fetch(const unsigned index, std::string * const data) const
{
    // VBO data is already on client, just send user pointer data
    for (unsigned i = 0; i < maxAttrib; i++) {
        if (!vertexAttribs[i].enabled)
            continue;
        if (vertexAttribs[i].buffer > 0)
            continue;
        const char * ptr = (const char *)vertexAttribs[i].ptr;
        ptr += index * vertexAttribs[i].stride;
        data->append(ptr, vertexAttribs[i].elemSize);
    }
}

void DbgContext::Compress(const void * in_data, unsigned int in_len,
                          std::string * const outStr)
{
    if (!lzf_buf)
        lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
    assert(lzf_buf);
    const uint32_t totalDecompSize = in_len;
    outStr->append((const char *)&totalDecompSize, sizeof(totalDecompSize));
    for (unsigned int i = 0; i < in_len; i += LZF_CHUNK_SIZE) {
        uint32_t chunkSize = LZF_CHUNK_SIZE;
        if (i + LZF_CHUNK_SIZE > in_len)
            chunkSize = in_len - i;
        const uint32_t compSize = lzf_compress((const char *)in_data + i, chunkSize,
                                               lzf_buf, LZF_CHUNK_SIZE);
        outStr->append((const char *)&chunkSize, sizeof(chunkSize));
        outStr->append((const char *)&compSize, sizeof(compSize));
        if (compSize > 0)
            outStr->append(lzf_buf, compSize);
        else // compressed chunk bigger than LZF_CHUNK_SIZE (and uncompressed)
            outStr->append((const char *)in_data + i, chunkSize);
    }
}

unsigned char * DbgContext::Decompress(const void * in, const unsigned int inLen,
                                       unsigned int * const outLen)
{
    assert(inLen > 4 * 3);
    if (inLen < 4 * 3)
        return NULL;
    *outLen = *(uint32_t *)in;
    unsigned char * const out = (unsigned char *)malloc(*outLen);
    unsigned int outPos = 0;
    const unsigned char * const end = (const unsigned char *)in + inLen;
    for (const unsigned char * inData = (const unsigned char *)in + 4; inData < end; ) {
        const uint32_t chunkOut = *(uint32_t *)inData;
        inData += 4;
        const uint32_t chunkIn = *(uint32_t *)inData;
        inData += 4;
        if (chunkIn > 0) {
            assert(inData + chunkIn <= end);
            assert(outPos + chunkOut <= *outLen);
            outPos += lzf_decompress(inData, chunkIn, out + outPos, chunkOut);
            inData += chunkIn;
        } else {
            assert(inData + chunkOut <= end);
            assert(outPos + chunkOut <= *outLen);
            memcpy(out + outPos, inData, chunkOut);
            inData += chunkOut;
            outPos += chunkOut;
        }
    }
    return out;
}

void * DbgContext::GetReadPixelsBuffer(const unsigned size)
{
    if (lzf_refBufSize < size + 8) {
        lzf_refBufSize = size + 8;
        lzf_ref[0] = (unsigned *)realloc(lzf_ref[0], lzf_refBufSize);
        assert(lzf_ref[0]);
        memset(lzf_ref[0], 0, lzf_refBufSize);
        lzf_ref[1] = (unsigned *)realloc(lzf_ref[1], lzf_refBufSize);
        assert(lzf_ref[1]);
        memset(lzf_ref[1], 0, lzf_refBufSize);
    }
    if (lzf_refSize != size) // need to clear unused ref to maintain consistency
    { // since ref and src are swapped each time
        memset((char *)lzf_ref[0] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
        memset((char *)lzf_ref[1] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
    }
    lzf_refSize = size;
    lzf_readIndex ^= 1;
    return lzf_ref[lzf_readIndex];
}

void DbgContext::CompressReadPixelBuffer(std::string * const outStr)
{
    assert(lzf_ref[0] && lzf_ref[1]);
    unsigned * const ref = lzf_ref[lzf_readIndex ^ 1];
    unsigned * const src = lzf_ref[lzf_readIndex];
    for (unsigned i = 0; i < lzf_refSize / sizeof(*ref) + 1; i++)
        ref[i] ^= src[i];
    Compress(ref, lzf_refSize, outStr);
}

char * DbgContext::GetBuffer()
{
    if (!lzf_buf)
        lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
    assert(lzf_buf);
    return lzf_buf;
}

unsigned int DbgContext::GetBufferSize()
{
    if (!lzf_buf)
        lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
    assert(lzf_buf);
    if (lzf_buf)
        return LZF_CHUNK_SIZE;
    else
        return 0;
}

void DbgContext::glUseProgram(GLuint program)
{
    while (GLenum error = hooks->gl.glGetError())
        LOGD("DbgContext::glUseProgram(%u): before glGetError() = 0x%.4X",
             program, error);
    this->program = program;
    maxAttrib = 0;
    if (program == 0)
        return;
    GLint activeAttributes = 0;
    hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
    maxAttrib = 0;
    GLint maxNameLen = -1;
    hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLen);
    char * name = new char [maxNameLen + 1];
    name[maxNameLen] = 0;
    // find total number of attribute slots used
    for (unsigned i = 0; i < activeAttributes; i++) {
        GLint size = -1;
        GLenum type = -1;
        hooks->gl.glGetActiveAttrib(program, i, maxNameLen + 1, NULL, &size, &type, name);
        GLint slot = hooks->gl.glGetAttribLocation(program, name);
        assert(slot >= 0);
        switch (type) {
        case GL_FLOAT:
        case GL_FLOAT_VEC2:
        case GL_FLOAT_VEC3:
        case GL_FLOAT_VEC4:
            slot += size;
            break;
        case GL_FLOAT_MAT2:
            slot += size * 2;
            break;
        case GL_FLOAT_MAT3:
            slot += size * 3;
            break;
        case GL_FLOAT_MAT4:
            slot += size * 4;
            break;
        default:
            assert(0);
        }
        if (slot > maxAttrib)
            maxAttrib = slot;
    }
    delete name;
    while (GLenum error = hooks->gl.glGetError())
        LOGD("DbgContext::glUseProgram(%u): after glGetError() = 0x%.4X",
             program, error);
}

static bool HasNonVBOAttribs(const DbgContext * const ctx)
{
    bool need = false;
    for (unsigned i = 0; !need && i < ctx->maxAttrib; i++)
        if (ctx->vertexAttribs[i].enabled && ctx->vertexAttribs[i].buffer == 0)
            need = true;
    return need;
}

void DbgContext::glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
                                       GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
    assert(GL_NO_ERROR == hooks->gl.glGetError());
    assert(indx < MAX_VERTEX_ATTRIBS);
    vertexAttribs[indx].size = size;
    vertexAttribs[indx].type = type;
    vertexAttribs[indx].normalized = normalized;
    switch (type) {
    case GL_FLOAT:
        vertexAttribs[indx].elemSize = sizeof(GLfloat) * size;
        break;
    case GL_INT:
    case GL_UNSIGNED_INT:
        vertexAttribs[indx].elemSize = sizeof(GLint) * size;
        break;
    case GL_SHORT:
    case GL_UNSIGNED_SHORT:
        vertexAttribs[indx].elemSize = sizeof(GLshort) * size;
        break;
    case GL_BYTE:
    case GL_UNSIGNED_BYTE:
        vertexAttribs[indx].elemSize = sizeof(GLbyte) * size;
        break;
    default:
        assert(0);
    }
    if (0 == stride)
        stride = vertexAttribs[indx].elemSize;
    vertexAttribs[indx].stride = stride;
    vertexAttribs[indx].ptr = ptr;
    hooks->gl.glGetVertexAttribiv(indx, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
                                  (GLint *)&vertexAttribs[indx].buffer);
    hasNonVBOAttribs = HasNonVBOAttribs(this);
}

void DbgContext::glEnableVertexAttribArray(GLuint index)
{
    if (index >= MAX_VERTEX_ATTRIBS)
        return;
    vertexAttribs[index].enabled = true;
    hasNonVBOAttribs = HasNonVBOAttribs(this);
}

void DbgContext::glDisableVertexAttribArray(GLuint index)
{
    if (index >= MAX_VERTEX_ATTRIBS)
        return;
    vertexAttribs[index].enabled = false;
    hasNonVBOAttribs = HasNonVBOAttribs(this);
}

void DbgContext::glBindBuffer(GLenum target, GLuint buffer)
{
    if (GL_ELEMENT_ARRAY_BUFFER != target)
        return;
    if (0 == buffer) {
        indexBuffer = NULL;
        return;
    }
    VBO * b = indexBuffers;
    indexBuffer = NULL;
    while (b) {
        if (b->name == buffer) {
            assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
            indexBuffer = b;
            break;
        }
        b = b->next;
    }
    if (!indexBuffer)
        indexBuffer = indexBuffers = new VBO(buffer, target, indexBuffers);
}

void DbgContext::glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
    if (GL_ELEMENT_ARRAY_BUFFER != target)
        return;
    assert(indexBuffer);
    assert(size >= 0);
    indexBuffer->size = size;
    indexBuffer->data = realloc(indexBuffer->data, size);
    memcpy(indexBuffer->data, data, size);
}

void DbgContext::glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
    if (GL_ELEMENT_ARRAY_BUFFER != target)
        return;
    assert(indexBuffer);
    assert(size >= 0);
    assert(offset >= 0);
    assert(offset + size <= indexBuffer->size);
    memcpy((char *)indexBuffer->data + offset, data, size);
}

void DbgContext::glDeleteBuffers(GLsizei n, const GLuint *buffers)
{
    for (unsigned i = 0; i < n; i++) {
        for (unsigned j = 0; j < MAX_VERTEX_ATTRIBS; j++)
            if (buffers[i] == vertexAttribs[j].buffer) {
                vertexAttribs[j].buffer = 0;
                vertexAttribs[j].enabled = false;
            }
        VBO * b = indexBuffers, * previous = NULL;
        while (b) {
            if (b->name == buffers[i]) {
                assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
                if (indexBuffer == b)
                    indexBuffer = NULL;
                if (previous)
                    previous->next = b->next;
                else
                    indexBuffers = b->next;
                free(b->data);
                delete b;
                break;
            }
            previous = b;
            b = b->next;
        }
    }
    hasNonVBOAttribs = HasNonVBOAttribs(this);
}

}; // namespace android
