/*
 ** 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())
        ALOGD("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())
        ALOGD("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
