/*
 * 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 <cutils/log.h>
#include <EGL/egldefs.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "frameworks/native/opengl/libs/GLES_trace/proto/gltrace.pb.h"
#include "gltrace_api.h"
#include "gltrace_context.h"
#include "gltrace_fixup.h"

namespace android {
namespace gltrace {

GLint glGetInteger(GLTraceContext *context, GLenum param) {
    GLint x;
    context->hooks->gl.glGetIntegerv(param, &x);
    return x;
}

GLint glGetVertexAttrib(GLTraceContext *context, GLuint index, GLenum pname) {
    GLint x;
    context->hooks->gl.glGetVertexAttribiv(index, pname, &x);
    return x;
}

bool isUsingPixelBuffers(GLTraceContext *context) {
    if (context->getVersionMajor() < 3) {
        return false; // PBOs not supported prior to GLES 3.0
    }
    return glGetInteger(context, GL_PIXEL_UNPACK_BUFFER_BINDING) != 0;
}

bool isUsingArrayBuffers(GLTraceContext *context) {
    return glGetInteger(context, GL_ARRAY_BUFFER_BINDING) != 0;
}

bool isUsingElementArrayBuffers(GLTraceContext *context) {
    return glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0;
}

unsigned getBytesPerTexel(const GLenum format, const GLenum type) {
    /*
    Description from glTexImage2D spec:

    Data is read from data as a sequence of unsigned bytes or shorts, depending on type.
    When type is GL_UNSIGNED_BYTE, each of the bytes is interpreted as one color component.
    When type is one of GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or
    GL_UNSIGNED_SHORT_5_5_5_1, each unsigned short value is interpreted as containing all
    the components for a single texel, with the color components arranged according to
    format. Color components are treated as groups of one, two, three, or four values,
    again based on format. Groups of components are referred to as texels.

    width × height texels are read from memory, starting at location data. By default,
    these texels are taken from adjacent memory locations, except that after all width
    texels are read, the read pointer is advanced to the next four-byte boundary.
    The four-byte row alignment is specified by glPixelStorei with argument
    GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
    */

    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:
        ALOGE("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:
        ALOGE("GetBytesPerPixel: unknown format %x", format);
    }

    return 1;   // in doubt...
}

void fixup_GenericFloatArray(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
    GLMessage_DataType *arg_floatarray = glmsg->mutable_args(argIndex);
    GLfloat *floatp = (GLfloat *)src;

    if (floatp == NULL) {
        return;
    }

    arg_floatarray->set_type(GLMessage::DataType::FLOAT);
    arg_floatarray->set_isarray(true);
    arg_floatarray->clear_floatvalue();

    for (int i = 0; i < nFloats; i++, floatp++) {
        arg_floatarray->add_floatvalue(*floatp);
    }
}

void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg, void *src) {
    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
    GLint *intp = (GLint *)src;

    if (intp == NULL) {
        return;
    }

    arg_intarray->set_type(GLMessage::DataType::INT);
    arg_intarray->set_isarray(true);
    arg_intarray->clear_intvalue();

    for (int i = 0; i < nInts; i++, intp++) {
        arg_intarray->add_intvalue(*intp);
    }
}

void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg, void *src) {
    // fixup as if they were ints
    fixup_GenericIntArray(argIndex, nEnums, glmsg, src);

    // and then set the data type to be enum
    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
    arg_enumarray->set_type(GLMessage::DataType::ENUM);
}

/** Generic helper function: extract pointer at argIndex and
    replace it with the C style string at *pointer */
void fixup_CStringPtr(int argIndex, GLMessage *glmsg, void *src) {
    GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
    GLchar *ptr = (GLchar *) src;

    arg->set_type(GLMessage::DataType::CHAR);
    arg->set_isarray(true);
    arg->add_charvalue(ptr);
}

void fixup_glGetString(GLMessage *glmsg, void *pointersToFixup[]) {
    /* const GLubyte* GLTrace_glGetString(GLenum name) */
    GLMessage_DataType *ret = glmsg->mutable_returnvalue();
    GLchar *ptr = (GLchar *) pointersToFixup[0];

    if (ptr != NULL) {
        ret->set_type(GLMessage::DataType::CHAR);
        ret->set_isarray(true);
        ret->add_charvalue(ptr);
    }
}

/* Add the contents of the framebuffer to the protobuf message */
void fixup_addFBContents(GLTraceContext *context, GLMessage *glmsg, FBBinding fbToRead) {
    void *fbcontents;
    unsigned fbsize, fbwidth, fbheight;
    context->getCompressedFB(&fbcontents, &fbsize, &fbwidth, &fbheight, fbToRead);

    GLMessage_FrameBuffer *fb = glmsg->mutable_fb();
    fb->set_width(fbwidth);
    fb->set_height(fbheight);
    fb->add_contents(fbcontents, fbsize);
}

/** Common fixup routing for glTexImage2D & glTexSubImage2D. */
void fixup_glTexImage(GLTraceContext *context, int widthIndex, int heightIndex, GLMessage *glmsg,
                        void *dataSrc) {
    GLMessage_DataType arg_width  = glmsg->args(widthIndex);
    GLMessage_DataType arg_height = glmsg->args(heightIndex);

    GLMessage_DataType arg_format = glmsg->args(6);
    GLMessage_DataType arg_type   = glmsg->args(7);
    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);

    GLsizei width  = arg_width.intvalue(0);
    GLsizei height = arg_height.intvalue(0);
    GLenum format  = arg_format.intvalue(0);
    GLenum type    = arg_type.intvalue(0);
    void *data     = (void *) dataSrc;

    int bytesPerTexel = getBytesPerTexel(format, type);

    arg_data->set_type(GLMessage::DataType::BYTE);
    arg_data->clear_rawbytes();

    if (data != NULL && !isUsingPixelBuffers(context)) {
        arg_data->set_isarray(true);
        arg_data->add_rawbytes(data, bytesPerTexel * width * height);
    } else {
        arg_data->set_isarray(false);
        arg_data->set_type(GLMessage::DataType::VOID);
    }
}


void fixup_glTexImage2D(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glTexImage2D(GLenum target,
                        GLint level,
                        GLint internalformat,
                        GLsizei width,
                        GLsizei height,
                        GLint border,
                        GLenum format,
                        GLenum type,
                        const GLvoid *data);
    */
    int widthIndex = 3;
    int heightIndex = 4;
    fixup_glTexImage(context, widthIndex, heightIndex, glmsg, pointersToFixup[0]);
}

void fixup_glTexSubImage2D(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
    /*
    void glTexSubImage2D(GLenum target,
                        GLint level,
                        GLint xoffset,
                        GLint yoffset,
                        GLsizei width,
                        GLsizei height,
                        GLenum format,
                        GLenum type,
                        const GLvoid * data);
    */
    int widthIndex = 4;
    int heightIndex = 5;
    fixup_glTexImage(context, widthIndex, heightIndex, glmsg, pointersToFixup[0]);
}

void fixup_glCompressedTexImage2D(GLTraceContext *context, GLMessage *glmsg,
                                    void *pointersToFixup[]) {
    /* void glCompressedTexImage2D(GLenum target,
                                   GLint level,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLint border,
                                   GLsizei imageSize,
                                   const GLvoid* data);
    */
    GLsizei size  = glmsg->args(6).intvalue(0);
    void *data = pointersToFixup[0];

    GLMessage_DataType *arg_data  = glmsg->mutable_args(7);
    arg_data->set_type(GLMessage::DataType::BYTE);
    arg_data->clear_rawbytes();

    if (data != NULL && !isUsingPixelBuffers(context)) {
        arg_data->set_isarray(true);
        arg_data->add_rawbytes(data, size);
    } else {
        arg_data->set_isarray(false);
        arg_data->set_type(GLMessage::DataType::VOID);
    }
}

void fixup_glCompressedTexSubImage2D(GLTraceContext *context, GLMessage *glmsg,
                                        void *pointersToFixup[]) {
    /* void glCompressedTexSubImage2D(GLenum target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLsizei width,
                                      GLsizei height,
                                      GLenum format,
                                      GLsizei imageSize,
                                      const GLvoid* data);
    */
    GLsizei size  = glmsg->args(7).intvalue(0);
    void *data = pointersToFixup[0];

    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);
    arg_data->set_type(GLMessage::DataType::BYTE);
    arg_data->clear_rawbytes();

    if (data != NULL && !isUsingPixelBuffers(context)) {
        arg_data->set_isarray(true);
        arg_data->add_rawbytes(data, size);
    } else {
        arg_data->set_isarray(false);
        arg_data->set_type(GLMessage::DataType::VOID);
    }
}

void fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
                                    const GLint* length) */
    GLMessage_DataType arg_count  = glmsg->args(1);
    GLMessage_DataType arg_lenp   = glmsg->args(3);
    GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);

    GLsizei count = arg_count.intvalue(0);
    GLchar **stringpp = (GLchar **) pointersToFixup[0];
    GLint *lengthp = (GLint *) pointersToFixup[1];

    arg_strpp->set_type(GLMessage::DataType::CHAR);
    arg_strpp->set_isarray(true);
    arg_strpp->clear_charvalue();

    ::std::string src = "";
    for (int i = 0; i < count; i++) {
        if (lengthp != NULL)
            src.append(*stringpp++, *lengthp++);
        else
            src.append(*stringpp++);  // assume null terminated
    }

    arg_strpp->add_charvalue(src);
}

void fixup_glUniformGenericInteger(int argIndex, int nElemsPerVector, GLMessage *glmsg,
                                                                    void *pointersToFixup[]) {
    /* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
    GLMessage_DataType arg_count  = glmsg->args(1);
    int n_vectors = arg_count.intvalue(0);
    fixup_GenericIntArray(argIndex, nElemsPerVector * n_vectors, glmsg, pointersToFixup[0]);
}

void fixup_glUniformGeneric(int argIndex, int nElemsPerVector, GLMessage *glmsg, void *src) {
    GLMessage_DataType arg_count  = glmsg->args(1);
    int n_vectors = arg_count.intvalue(0);
    fixup_GenericFloatArray(argIndex, nElemsPerVector * n_vectors, glmsg, src);
}

void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
                                                                const GLfloat* value) */
    GLMessage_DataType arg_count  = glmsg->args(1);
    int n_matrices = arg_count.intvalue(0);
    fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
}

void fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glGen*(GLsizei n, GLuint * buffers); */
    GLMessage_DataType arg_n  = glmsg->args(0);
    GLsizei n = arg_n.intvalue(0);

    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
}

void fixup_glDeleteGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glDelete*(GLsizei n, GLuint *buffers); */
    GLMessage_DataType arg_n  = glmsg->args(0);
    GLsizei n = arg_n.intvalue(0);

    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
}

void fixup_glGetBooleanv(GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glGetBooleanv(GLenum pname, GLboolean *params); */
    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
    GLboolean *src = (GLboolean*) pointersToFixup[0];

    arg_params->set_type(GLMessage::DataType::BOOL);
    arg_params->set_isarray(true);
    arg_params->clear_boolvalue();
    arg_params->add_boolvalue(*src);
}

void fixup_glGetFloatv(GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glGetFloatv(GLenum pname, GLfloat *params); */
    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
    GLfloat *src = (GLfloat*) pointersToFixup[0];

    arg_params->set_type(GLMessage::DataType::FLOAT);
    arg_params->set_isarray(true);
    arg_params->clear_floatvalue();
    arg_params->add_floatvalue(*src);
}

void fixup_glLinkProgram(GLMessage *glmsg) {
    /* void glLinkProgram(GLuint program); */
    GLuint program = glmsg->args(0).intvalue(0);

    /* We don't have to fixup this call, but as soon as a program is linked,
       we obtain information about all active attributes and uniforms to
       pass on to the debugger. Note that in order to pass this info to
       the debugger, all we need to do is call the trace versions of the
       necessary calls. */

    GLint n, maxNameLength;
    GLchar *name;
    GLint size;
    GLenum type;

    // obtain info regarding active attributes
    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);

    name = (GLchar *) malloc(maxNameLength);
    for (int i = 0; i < n; i++) {
        GLTrace_glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name);
    }
    free(name);

    // obtain info regarding active uniforms
    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);

    name = (GLchar *) malloc(maxNameLength);
    for (int i = 0; i < n; i++) {
        GLTrace_glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name);
    }
    free(name);
}

/** Given a glGetActive[Uniform|Attrib] call, obtain the location
 *  of the variable of given name in the call.
 */
GLint getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar *name) {
    GLMessage_Function func = glmsg->function();
    if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
        return -1;
    }

    int program = glmsg->args(0).intvalue(0);

    if (func == GLMessage::glGetActiveAttrib) {
        return context->hooks->gl.glGetAttribLocation(program, name);
    } else {
        return context->hooks->gl.glGetUniformLocation(program, name);
    }
}

void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
                                                                void *pointersToFixup[]) {
    /* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
                GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
    /* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
                GLsizei* length, GLint* size, GLenum* type, GLchar* name) */

    fixup_GenericIntArray(3, 1, glmsg, pointersToFixup[0]);     // length
    fixup_GenericIntArray(4, 1, glmsg, pointersToFixup[1]);     // size
    fixup_GenericEnumArray(5, 1, glmsg, pointersToFixup[2]);    // type
    fixup_CStringPtr(6, glmsg, pointersToFixup[3]);             // name

    // The index argument in the glGetActive[Attrib|Uniform] functions
    // does not correspond to the actual location index as used in
    // glUniform*() or glVertexAttrib*() to actually upload the data.
    // In order to make things simpler for the debugger, we also pass
    // a hidden location argument that stores the actual location.
    // append the location value to the end of the argument list
    GLint location = getShaderVariableLocation(context, glmsg, (GLchar*)pointersToFixup[3]);
    GLMessage_DataType *arg_location = glmsg->add_args();
    arg_location->set_isarray(false);
    arg_location->set_type(GLMessage::DataType::INT);
    arg_location->add_intvalue(location);
}

/** Copy @len bytes of data from @src into the @dataIndex'th argument of the message. */
void addGlBufferData(GLMessage *glmsg, int dataIndex, GLvoid *src, GLsizeiptr len) {
    GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
    arg_datap->set_type(GLMessage::DataType::VOID);
    arg_datap->set_isarray(true);
    arg_datap->clear_intvalue();
    arg_datap->add_rawbytes(src, len);
}

void fixup_glBufferData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
    GLsizeiptr size = glmsg->args(1).intvalue(0);
    GLvoid *datap = (GLvoid *) pointersToFixup[0];

    // Save element array buffers for future use to fixup glVertexAttribPointers
    // when a glDrawElements() call is performed.
    GLenum target = glmsg->args(0).intvalue(0);
    if (target == GL_ELEMENT_ARRAY_BUFFER) {
        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
        context->bindBuffer(bufferId, datap, size);
    }

    // add buffer data to the protobuf message
    if (datap != NULL) {
        addGlBufferData(glmsg, 2, datap, size);
    }
}

void fixup_glBufferSubData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
    GLenum target = glmsg->args(0).intvalue(0);
    GLintptr offset = glmsg->args(1).intvalue(0);
    GLsizeiptr size = glmsg->args(2).intvalue(0);
    GLvoid *datap = (GLvoid *) pointersToFixup[0];
    if (target == GL_ELEMENT_ARRAY_BUFFER) {
        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
        context->updateBufferSubData(bufferId, offset, datap, size);
    }

    // add buffer data to the protobuf message
    addGlBufferData(glmsg, 3, datap, size);
}

/** Obtain the size of each vertex attribute. */
int vertexAttribSize(GLenum type, GLsizei numComponents) {
    int sizePerComponent;

    switch(type) {
    case GL_BYTE:
    case GL_UNSIGNED_BYTE:
        sizePerComponent = 1;
        break;
    case GL_SHORT:
    case GL_UNSIGNED_SHORT:
        sizePerComponent = 2;
        break;
    case GL_FIXED:
    case GL_FLOAT:
    default:
        sizePerComponent = 4;
        break;
    }

    return sizePerComponent * numComponents;
}

/** Create and send a glVertexAttribPointerData trace message to the host. */
void trace_glVertexAttribPointerData(GLTraceContext *context,
                    GLuint indx, GLint size, GLenum type,
                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
                    GLuint minIndex, GLuint maxIndex, nsecs_t startTime) {
    /* void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type,
                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
                    int minIndex, int maxIndex) */
    GLMessage glmsg;
    GLTraceContext *glContext = context;

    glmsg.set_function(GLMessage::glVertexAttribPointerData);

    // copy argument indx
    GLMessage_DataType *arg_indx = glmsg.add_args();
    arg_indx->set_isarray(false);
    arg_indx->set_type(GLMessage::DataType::INT);
    arg_indx->add_intvalue(indx);

    // copy argument size
    GLMessage_DataType *arg_size = glmsg.add_args();
    arg_size->set_isarray(false);
    arg_size->set_type(GLMessage::DataType::INT);
    arg_size->add_intvalue(size);

    // copy argument type
    GLMessage_DataType *arg_type = glmsg.add_args();
    arg_type->set_isarray(false);
    arg_type->set_type(GLMessage::DataType::ENUM);
    arg_type->add_intvalue((int)type);

    // copy argument normalized
    GLMessage_DataType *arg_normalized = glmsg.add_args();
    arg_normalized->set_isarray(false);
    arg_normalized->set_type(GLMessage::DataType::BOOL);
    arg_normalized->add_boolvalue(normalized);

    // copy argument stride
    GLMessage_DataType *arg_stride = glmsg.add_args();
    arg_stride->set_isarray(false);
    arg_stride->set_type(GLMessage::DataType::INT);
    arg_stride->add_intvalue(stride);

    // copy argument ptr
    GLMessage_DataType *arg_ptr = glmsg.add_args();
    arg_ptr->set_isarray(true);
    arg_ptr->set_type(GLMessage::DataType::BYTE);
    int perVertexSize = vertexAttribSize(type, size);
    GLchar *p = (GLchar*) ptr;
    std::string data;
    for (GLuint i = minIndex; i < maxIndex; i++) {
        data.append(p, perVertexSize);
        p += stride == 0 ? perVertexSize : stride;
    }
    arg_ptr->add_rawbytes(data);

    // copy argument min index
    GLMessage_DataType *arg_min = glmsg.add_args();
    arg_min->set_isarray(false);
    arg_min->set_type(GLMessage::DataType::INT);
    arg_min->add_intvalue(minIndex);

    // copy argument max index
    GLMessage_DataType *arg_max = glmsg.add_args();
    arg_max->set_isarray(false);
    arg_max->set_type(GLMessage::DataType::INT);
    arg_max->add_intvalue(maxIndex);

    glmsg.set_context_id(context->getId());
    glmsg.set_start_time(startTime);
    glmsg.set_threadtime(0);
    glmsg.set_duration(0);

    context->traceGLMessage(&glmsg);
}

void findMinAndMaxIndices(GLvoid *indices, GLsizei count, GLenum type,
                            GLuint *minIndex, GLuint *maxIndex) {
    GLuint index;
    *minIndex = UINT_MAX;
    *maxIndex = 0;

    if (indices == NULL) {
        return;
    }

    for (GLsizei i = 0; i < count; i++) {
        if (type == GL_UNSIGNED_BYTE) {
            index = *((GLubyte*) indices + i);
        } else {
            index = *((GLushort*) indices + i);
        }

        if (index < *minIndex) *minIndex = index;
        if (index > *maxIndex) *maxIndex = index;
    }
}

void trace_VertexAttribPointerData(GLTraceContext *context,
                            GLuint minIndex, GLuint maxIndex, nsecs_t time) {
    GLuint maxAttribs = glGetInteger(context, GL_MAX_VERTEX_ATTRIBS);
    for (GLuint index = 0; index < maxAttribs; index++) {
        if (!glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_ENABLED)) {
            // vertex array disabled
            continue;
        }

        if (glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)) {
            // vbo
            continue;
        }

        GLint size = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_SIZE);
        GLenum type = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_TYPE);
        GLboolean norm = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
        GLsizei stride = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_STRIDE);
        GLvoid* ptr;
        context->hooks->gl.glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);

        trace_glVertexAttribPointerData(context,
                    index, size, type, norm, stride, ptr,
                    minIndex, maxIndex, time);
    }
}

void trace_VertexAttribPointerDataForGlDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
    if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
        // only supported for GLES2 and above
        return;
    }

    /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
    GLsizei count = glmsg->args(2).intvalue(0);

    // Vertex attrib pointer data patchup calls should appear as if
    // they occurred right before the draw call.
    nsecs_t time = glmsg->start_time() - 1;

    trace_VertexAttribPointerData(context, 0, count, time);
}

void trace_VertexAttribPointerDataForGlDrawElements(GLTraceContext *context, GLMessage *glmsg,
                            GLvoid *indices) {
    if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
        // only supported for GLES2 and above
        return;
    }

    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
    GLsizei count = glmsg->args(1).intvalue(0);
    GLenum type = glmsg->args(2).intvalue(0);
    GLuint index;

    GLuint minIndex, maxIndex;

    // The index buffer is either passed in as an argument to the glDrawElements() call,
    // or it is stored in the current GL_ELEMENT_ARRAY_BUFFER.
    GLvoid *indexBuffer;
    if (isUsingElementArrayBuffers(context)) {
        GLsizeiptr eaBufferSize;
        GLuint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
        context->getBuffer(bufferId, &indexBuffer, &eaBufferSize);
    } else {
        indexBuffer = indices;
    }

    // Rather than sending vertex attribute data that corresponds to the indices
    // being drawn, we send the vertex attribute data for the entire range of
    // indices being drawn, including the ones not drawn. The min & max indices
    // provide the range of indices being drawn.
    findMinAndMaxIndices(indexBuffer, count, type, &minIndex, &maxIndex);

    // Vertex attrib pointer data patchup calls should appear as if
    // they occurred right before the draw call.
    nsecs_t time = glmsg->start_time() - 1;

    trace_VertexAttribPointerData(context, minIndex, maxIndex + 1, time);
}

void fixup_glDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
    // Trace all vertex attribute data stored in client space.
    trace_VertexAttribPointerDataForGlDrawArrays(context, glmsg);

    // Attach the FB if requested
    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
    }
}

void fixup_glDrawElements(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
    GLvoid *indices = pointersToFixup[0];
    GLenum type = glmsg->args(2).intvalue(0);
    GLsizei count = glmsg->args(1).intvalue(0);
    GLuint index;

    // Trace all vertex attribute data stored in client space.
    trace_VertexAttribPointerDataForGlDrawElements(context, glmsg, indices);

    // Fixup indices argument
    if (!isUsingElementArrayBuffers(context)) {
        GLMessage_DataType *arg_indices = glmsg->mutable_args(3);
        arg_indices->set_isarray(true);
        arg_indices->clear_intvalue();
        arg_indices->set_type(GLMessage::DataType::INT);
        for (GLsizei i = 0; i < count; i++) {
            if (type == GL_UNSIGNED_BYTE) {
                index = *((GLubyte*) indices + i);
            } else {
                index = *((GLushort*) indices + i);
            }
            arg_indices->add_intvalue(index);
        }
    }

    // Attach the FB if requested
    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
    }
}

void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
                                             nsecs_t threadStart, nsecs_t threadEnd,
                                             GLMessage *glmsg, void *pointersToFixup[]) {
    // for all messages, set the current context id
    glmsg->set_context_id(context->getId());

    // set start time and duration
    glmsg->set_start_time(wallStart);
    glmsg->set_duration((unsigned)(wallEnd - wallStart));
    glmsg->set_threadtime((unsigned)(threadEnd - threadStart));

    // do any custom message dependent processing
    switch (glmsg->function()) {
    case GLMessage::glDeleteBuffers:      /* glDeleteBuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glDeleteTextures:     /* glDeleteTextures(GLsizei n, GLuint *textures); */
        fixup_glDeleteGeneric(glmsg, pointersToFixup);
        break;
    case GLMessage::glGenBuffers:        /* void glGenBuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glGenFramebuffers:   /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glGenRenderbuffers:  /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
    case GLMessage::glGenTextures:       /* void glGenTextures(GLsizei n, GLuint *textures); */
        fixup_glGenGeneric(glmsg, pointersToFixup);
        break;
    case GLMessage::glLinkProgram:       /* void glLinkProgram(GLuint program); */
        fixup_glLinkProgram(glmsg);
        break;
    case GLMessage::glGetActiveAttrib:
        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
        break;
    case GLMessage::glGetActiveUniform:
        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
        break;
    case GLMessage::glBindAttribLocation:
        /* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
        fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glGetAttribLocation:
    case GLMessage::glGetUniformLocation:
        /* int glGetAttribLocation(GLuint program, const GLchar* name) */
        /* int glGetUniformLocation(GLuint program, const GLchar* name) */
        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glGetBooleanv:
        fixup_glGetBooleanv(glmsg, pointersToFixup);
        break;
    case GLMessage::glGetFloatv:
        fixup_glGetFloatv(glmsg, pointersToFixup);
        break;
    case GLMessage::glGetIntegerv:        /* void glGetIntegerv(GLenum pname, GLint *params); */
        fixup_GenericIntArray(1, 1, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glGetProgramiv:
    case GLMessage::glGetRenderbufferParameteriv:
    case GLMessage::glGetShaderiv:
        /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
        /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
        /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
        fixup_GenericIntArray(2, 1, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glGetString:
        fixup_glGetString(glmsg, pointersToFixup);
        break;
    case GLMessage::glTexImage2D:
        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
            fixup_glTexImage2D(context, glmsg, pointersToFixup);
        }
        break;
    case GLMessage::glTexSubImage2D:
        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
            fixup_glTexSubImage2D(context, glmsg, pointersToFixup);
        }
        break;
    case GLMessage::glCompressedTexImage2D:
        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
            fixup_glCompressedTexImage2D(context, glmsg, pointersToFixup);
        }
        break;
    case GLMessage::glCompressedTexSubImage2D:
        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
            fixup_glCompressedTexSubImage2D(context, glmsg, pointersToFixup);
        }
        break;
    case GLMessage::glShaderSource:
        fixup_glShaderSource(glmsg, pointersToFixup);
        break;
    case GLMessage::glUniform1iv:
        /* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
        fixup_glUniformGenericInteger(2, 1, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniform2iv:
        /* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
        fixup_glUniformGenericInteger(2, 2, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniform3iv:
        /* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
        fixup_glUniformGenericInteger(2, 3, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniform4iv:
        /* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
        fixup_glUniformGenericInteger(2, 4, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniform1fv:
        /* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
        fixup_glUniformGeneric(2, 1, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glUniform2fv:
        /* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
        fixup_glUniformGeneric(2, 2, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glUniform3fv:
        /* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
        fixup_glUniformGeneric(2, 3, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glUniform4fv:
        /* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
        fixup_glUniformGeneric(2, 4, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glUniformMatrix2fv:
        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                                                                    const GLfloat* value) */
        fixup_glUniformMatrixGeneric(2, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniformMatrix3fv:
        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                                                                    const GLfloat* value) */
        fixup_glUniformMatrixGeneric(3, glmsg, pointersToFixup);
        break;
    case GLMessage::glUniformMatrix4fv:
        /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
                                                                    const GLfloat* value) */
        fixup_glUniformMatrixGeneric(4, glmsg, pointersToFixup);
        break;
    case GLMessage::glBufferData:
        /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
        fixup_glBufferData(context, glmsg, pointersToFixup);
        break;
    case GLMessage::glBufferSubData:
        /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
        fixup_glBufferSubData(context, glmsg, pointersToFixup);
        break;
    case GLMessage::glDrawArrays:
        /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
        fixup_glDrawArrays(context, glmsg);
        break;
    case GLMessage::glDrawElements:
        /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
        fixup_glDrawElements(context, glmsg, pointersToFixup);
        break;
    case GLMessage::glPushGroupMarkerEXT:
        /* void PushGroupMarkerEXT(sizei length, const char *marker); */
        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
        break;
    case GLMessage::glInsertEventMarkerEXT:
        /* void InsertEventMarkerEXT(sizei length, const char *marker); */
        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
        break;
    default:
        break;
    }
}

};
};
