gltrace_fixup.cpp revision 7b3f48d2efc83094de70c24520bafacda3749a20
10469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/*
20469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Copyright 2011, The Android Open Source Project
30469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
40469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Licensed under the Apache License, Version 2.0 (the "License");
50469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * you may not use this file except in compliance with the License.
60469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * You may obtain a copy of the License at
70469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
80469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *     http://www.apache.org/licenses/LICENSE-2.0
90469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Unless required by applicable law or agreed to in writing, software
110469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * distributed under the License is distributed on an "AS IS" BASIS,
120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * See the License for the specific language governing permissions and
140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * limitations under the License.
150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */
160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <cutils/log.h>
183ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy#include <EGL/egldefs.h>
1988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES/gl.h>
2088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES/glext.h>
210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <GLES2/gl2.h>
2288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES2/gl2ext.h>
230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace.pb.h"
2588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include "gltrace_api.h"
260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_context.h"
270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_fixup.h"
280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android {
300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace {
310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyunsigned getBytesPerTexel(const GLenum format, const GLenum type) {
330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /*
340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    Description from glTexImage2D spec:
350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    Data is read from data as a sequence of unsigned bytes or shorts, depending on type.
370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    When type is GL_UNSIGNED_BYTE, each of the bytes is interpreted as one color component.
380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    When type is one of GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or
390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GL_UNSIGNED_SHORT_5_5_5_1, each unsigned short value is interpreted as containing all
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    the components for a single texel, with the color components arranged according to
410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    format. Color components are treated as groups of one, two, three, or four values,
420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    again based on format. Groups of components are referred to as texels.
430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    width × height texels are read from memory, starting at location data. By default,
450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    these texels are taken from adjacent memory locations, except that after all width
460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    texels are read, the read pointer is advanced to the next four-byte boundary.
470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    The four-byte row alignment is specified by glPixelStorei with argument
480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    */
500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (type) {
520469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_5_6_5:
530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_4_4_4_4:
540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_5_5_5_1:
550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 2;
560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_BYTE:
570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
59e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GetBytesPerPixel: unknown type %x", type);
600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (format) {
630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_ALPHA:
640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_LUMINANCE:
650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 1;
660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_LUMINANCE_ALPHA:
670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 2;
680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_RGB:
690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 3;
700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_RGBA:
710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case 0x80E1: // GL_BGRA_EXT
720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 4;
730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
74e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GetBytesPerPixel: unknown format %x", format);
750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    return 1;   // in doubt...
780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
809801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericFloatArray(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
819801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_floatarray = glmsg->mutable_args(argIndex);
829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLfloat *floatp = (GLfloat *)src;
839801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
849801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    if (floatp == NULL) {
859801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        return;
869801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
879801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
889801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->set_type(GLMessage::DataType::FLOAT);
899801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->set_isarray(true);
909801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->clear_floatvalue();
919801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
929801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    for (int i = 0; i < nFloats; i++, floatp++) {
939801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        arg_floatarray->add_floatvalue(*floatp);
949801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
959801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
969801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg, void *src) {
989801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
999801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLint *intp = (GLint *)src;
1009801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1019801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    if (intp == NULL) {
1029801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        return;
1039801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
1049801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1059801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->set_type(GLMessage::DataType::INT);
1069801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->set_isarray(true);
1079801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->clear_intvalue();
1089801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1099801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    for (int i = 0; i < nInts; i++, intp++) {
1109801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        arg_intarray->add_intvalue(*intp);
1119801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
1129801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
1139801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1149801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg, void *src) {
1159801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    // fixup as if they were ints
1169801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(argIndex, nEnums, glmsg, src);
1179801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1189801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    // and then set the data type to be enum
1199801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
1209801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_enumarray->set_type(GLMessage::DataType::ENUM);
1219801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
1229801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/** Generic helper function: extract pointer at argIndex and
1240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    replace it with the C style string at *pointer */
1259801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_CStringPtr(int argIndex, GLMessage *glmsg, void *src) {
1260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
1279801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar *ptr = (GLchar *) src;
1280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->set_type(GLMessage::DataType::CHAR);
1300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->set_isarray(true);
1310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->add_charvalue(ptr);
1320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1349801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetString(GLMessage *glmsg, void *pointersToFixup[]) {
1350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* const GLubyte* GLTrace_glGetString(GLenum name) */
1360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *ret = glmsg->mutable_returnvalue();
1379801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar *ptr = (GLchar *) pointersToFixup[0];
1380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (ptr != NULL) {
1400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->set_type(GLMessage::DataType::CHAR);
1410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->set_isarray(true);
1420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->add_charvalue(ptr);
1430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
146a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy/* Add the contents of the framebuffer to the protobuf message */
14793a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid fixup_addFBContents(GLTraceContext *context, GLMessage *glmsg, FBBinding fbToRead) {
148a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    void *fbcontents;
1490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    unsigned fbsize, fbwidth, fbheight;
15093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    context->getCompressedFB(&fbcontents, &fbsize, &fbwidth, &fbheight, fbToRead);
1510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
152a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    GLMessage_FrameBuffer *fb = glmsg->mutable_fb();
153a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->set_width(fbwidth);
154a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->set_height(fbheight);
155a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->add_contents(fbcontents, fbsize);
1560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
15834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy/** Common fixup routing for glTexImage2D & glTexSubImage2D. */
1599801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg, void *dataSrc) {
16034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_width  = glmsg->args(widthIndex);
16134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_height = glmsg->args(heightIndex);
16234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
1630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_format = glmsg->args(6);
1640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_type   = glmsg->args(7);
1650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);
1660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei width  = arg_width.intvalue(0);
1680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei height = arg_height.intvalue(0);
1690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLenum format  = arg_format.intvalue(0);
1700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLenum type    = arg_type.intvalue(0);
1719801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    void *data     = (void *) dataSrc;
1720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int bytesPerTexel = getBytesPerTexel(format, type);
1740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_data->set_type(GLMessage::DataType::BYTE);
1760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_data->clear_rawbytes();
1770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (data != NULL) {
17934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        arg_data->set_isarray(true);
1800469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        arg_data->add_rawbytes(data, bytesPerTexel * width * height);
1810469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    } else {
18234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        arg_data->set_isarray(false);
1830469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        arg_data->set_type(GLMessage::DataType::VOID);
1840469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1850469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1860469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
18734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
1889801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
18934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /* void glTexImage2D(GLenum target,
19034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint level,
19134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint internalformat,
19234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei width,
19334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei height,
19434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint border,
19534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum format,
19634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum type,
19750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                        const GLvoid *data);
19834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    */
19934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int widthIndex = 3;
20034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int heightIndex = 4;
2019801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
20234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
20334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2049801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
20534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /*
20634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    void glTexSubImage2D(GLenum target,
20734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint level,
20834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint xoffset,
20934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint yoffset,
21034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei width,
21134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei height,
21234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum format,
21334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum type,
21434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        const GLvoid * data);
21534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    */
21634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int widthIndex = 4;
21734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int heightIndex = 5;
2189801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
21934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
22034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2213d3c125423ab922e705c3f563c689bd7c4a04bacBen Claytonvoid fixup_glCompressedTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
2223d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    /* void glCompressedTexImage2D(GLenum target,
2233d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLint level,
2243d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLenum internalformat,
2253d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLsizei width,
2263d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLsizei height,
2273d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLint border,
2283d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   GLsizei imageSize,
2293d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                   const GLvoid* data);
2303d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    */
2313d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    GLsizei size  = glmsg->args(6).intvalue(0);
2323d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    void *data = pointersToFixup[0];
2333d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2343d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    GLMessage_DataType *arg_data  = glmsg->mutable_args(7);
2353d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    arg_data->set_type(GLMessage::DataType::BYTE);
2363d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    arg_data->clear_rawbytes();
2373d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2383d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    if (data != NULL) {
2393d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_isarray(true);
2403d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->add_rawbytes(data, size);
2413d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    } else {
2423d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_isarray(false);
2433d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_type(GLMessage::DataType::VOID);
2443d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    }
2453d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton}
2463d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2473d3c125423ab922e705c3f563c689bd7c4a04bacBen Claytonvoid fixup_glCompressedTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
2483d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    /* void glCompressedTexSubImage2D(GLenum target,
2493d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLint level,
2503d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLint xoffset,
2513d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLint yoffset,
2523d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLsizei width,
2533d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLsizei height,
2543d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLenum format,
2553d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      GLsizei imageSize,
2563d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton                                      const GLvoid* data);
2573d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    */
2583d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    GLsizei size  = glmsg->args(7).intvalue(0);
2593d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    void *data = pointersToFixup[0];
2603d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2613d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);
2623d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    arg_data->set_type(GLMessage::DataType::BYTE);
2633d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    arg_data->clear_rawbytes();
2643d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2653d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    if (data != NULL) {
2663d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_isarray(true);
2673d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->add_rawbytes(data, size);
2683d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    } else {
2693d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_isarray(false);
2703d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        arg_data->set_type(GLMessage::DataType::VOID);
2713d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    }
2723d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton}
2733d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton
2749801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
27550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
2760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                    const GLint* length) */
2770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_count  = glmsg->args(1);
2780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_lenp   = glmsg->args(3);
2790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);
2800469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2810469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei count = arg_count.intvalue(0);
2829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar **stringpp = (GLchar **) pointersToFixup[0];
2839801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLint *lengthp = (GLint *) pointersToFixup[1];
2840469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2850469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->set_type(GLMessage::DataType::CHAR);
2860469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->set_isarray(true);
2870469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->clear_charvalue();
2880469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    ::std::string src = "";
2900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    for (int i = 0; i < count; i++) {
2910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        if (lengthp != NULL)
292090503a01c457feb6e64facfc7eb50c1f5612c6bSiva Velusamy            src.append(*stringpp++, *lengthp++);
2930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        else
294090503a01c457feb6e64facfc7eb50c1f5612c6bSiva Velusamy            src.append(*stringpp++);  // assume null terminated
2950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
2960469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->add_charvalue(src);
2980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2990469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3007b3f48d2efc83094de70c24520bafacda3749a20Ben Claytonvoid fixup_glUniformGenericInteger(int argIndex, int nElemsPerVector, GLMessage *glmsg,
3019801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                                                    void *pointersToFixup[]) {
30288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
3037b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    GLMessage_DataType arg_count  = glmsg->args(1);
3047b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    int n_vectors = arg_count.intvalue(0);
3057b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    fixup_GenericIntArray(argIndex, nElemsPerVector * n_vectors, glmsg, pointersToFixup[0]);
30688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
30788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
3087b3f48d2efc83094de70c24520bafacda3749a20Ben Claytonvoid fixup_glUniformGeneric(int argIndex, int nElemsPerVector, GLMessage *glmsg, void *src) {
3097b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    GLMessage_DataType arg_count  = glmsg->args(1);
3107b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    int n_vectors = arg_count.intvalue(0);
3117b3f48d2efc83094de70c24520bafacda3749a20Ben Clayton    fixup_GenericFloatArray(argIndex, nElemsPerVector * n_vectors, glmsg, src);
3120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3149801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
31550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
3160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                const GLfloat* value) */
3170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_count  = glmsg->args(1);
3180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int n_matrices = arg_count.intvalue(0);
3199801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
3200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3229801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
3230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGen*(GLsizei n, GLuint * buffers); */
3240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_n  = glmsg->args(0);
3250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei n = arg_n.intvalue(0);
3260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3279801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
3280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3309801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glDeleteGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
33134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /* void glDelete*(GLsizei n, GLuint *buffers); */
33234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_n  = glmsg->args(0);
33334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLsizei n = arg_n.intvalue(0);
33434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
3359801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
33634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
33734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
3389801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetBooleanv(GLMessage *glmsg, void *pointersToFixup[]) {
3390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGetBooleanv(GLenum pname, GLboolean *params); */
3400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
3419801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLboolean *src = (GLboolean*) pointersToFixup[0];
3420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_type(GLMessage::DataType::BOOL);
3440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_isarray(true);
3450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->clear_boolvalue();
3460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->add_boolvalue(*src);
3470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3499801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetFloatv(GLMessage *glmsg, void *pointersToFixup[]) {
3500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGetFloatv(GLenum pname, GLfloat *params); */
3510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
3529801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLfloat *src = (GLfloat*) pointersToFixup[0];
3530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_type(GLMessage::DataType::FLOAT);
3550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_isarray(true);
3560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->clear_floatvalue();
3570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->add_floatvalue(*src);
3580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3590469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
36088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamyvoid fixup_glLinkProgram(GLMessage *glmsg) {
36188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glLinkProgram(GLuint program); */
36288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLuint program = glmsg->args(0).intvalue(0);
36388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
36488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* We don't have to fixup this call, but as soon as a program is linked,
36588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       we obtain information about all active attributes and uniforms to
36688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       pass on to the debugger. Note that in order to pass this info to
36788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       the debugger, all we need to do is call the trace versions of the
36888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       necessary calls. */
36988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
37088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLint n, maxNameLength;
37188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLchar *name;
37288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLint size;
37388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLenum type;
37488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
37588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // obtain info regarding active attributes
37688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
37788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
37888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
37988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    name = (GLchar *) malloc(maxNameLength);
38088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    for (int i = 0; i < n; i++) {
38188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        GLTrace_glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name);
38288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
38388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    free(name);
38488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
38588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // obtain info regarding active uniforms
38688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
38788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
38888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
38988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    name = (GLchar *) malloc(maxNameLength);
39088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    for (int i = 0; i < n; i++) {
39188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        GLTrace_glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name);
39288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
39388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    free(name);
39488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
39588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
39688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy/** Given a glGetActive[Uniform|Attrib] call, obtain the location
3979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy *  of the variable of given name in the call.
39888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy */
399300ad09822db1013d9f28c4bca3680f865533ab6Andrew HsiehGLint getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar *name) {
40088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLMessage_Function func = glmsg->function();
40188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
40288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return -1;
40388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
40488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
40588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    int program = glmsg->args(0).intvalue(0);
40688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
40788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    if (func == GLMessage::glGetActiveAttrib) {
40888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return context->hooks->gl.glGetAttribLocation(program, name);
40988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    } else {
41088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return context->hooks->gl.glGetUniformLocation(program, name);
41188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
41288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
41388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
41450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
4159801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                                                void *pointersToFixup[]) {
41688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
41788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy                GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
41888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
41988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy                GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
42088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
4219801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(3, 1, glmsg, pointersToFixup[0]);     // length
4229801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(4, 1, glmsg, pointersToFixup[1]);     // size
4239801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericEnumArray(5, 1, glmsg, pointersToFixup[2]);    // type
4249801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_CStringPtr(6, glmsg, pointersToFixup[3]);             // name
42588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
42688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // The index argument in the glGetActive[Attrib|Uniform] functions
42788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // does not correspond to the actual location index as used in
42888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // glUniform*() or glVertexAttrib*() to actually upload the data.
42988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // In order to make things simpler for the debugger, we also pass
43088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // a hidden location argument that stores the actual location.
43188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // append the location value to the end of the argument list
432300ad09822db1013d9f28c4bca3680f865533ab6Andrew Hsieh    GLint location = getShaderVariableLocation(context, glmsg, (GLchar*)pointersToFixup[3]);
43388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLMessage_DataType *arg_location = glmsg->add_args();
43488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->set_isarray(false);
43588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->set_type(GLMessage::DataType::INT);
43688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->add_intvalue(location);
43788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
43888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
43950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLint glGetInteger(GLTraceContext *context, GLenum param) {
44050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLint x;
44150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->hooks->gl.glGetIntegerv(param, &x);
44250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return x;
44350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
44450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
44550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLint glGetVertexAttrib(GLTraceContext *context, GLuint index, GLenum pname) {
44650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLint x;
44750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->hooks->gl.glGetVertexAttribiv(index, pname, &x);
44850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return x;
44950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
45050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
45150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamybool isUsingArrayBuffers(GLTraceContext *context) {
45250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return glGetInteger(context, GL_ARRAY_BUFFER_BINDING) != 0;
45350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
45450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
45550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamybool isUsingElementArrayBuffers(GLTraceContext *context) {
45650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0;
45750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
45850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
45950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Copy @len bytes of data from @src into the @dataIndex'th argument of the message. */
46050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid addGlBufferData(GLMessage *glmsg, int dataIndex, GLvoid *src, GLsizeiptr len) {
46150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
46250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->set_type(GLMessage::DataType::VOID);
46350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->set_isarray(true);
46450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->clear_intvalue();
46550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->add_rawbytes(src, len);
46650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
46750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
46850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glBufferData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
46950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
47050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizeiptr size = glmsg->args(1).intvalue(0);
47150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *datap = (GLvoid *) pointersToFixup[0];
47250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
47350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Save element array buffers for future use to fixup glVertexAttribPointers
47450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // when a glDrawElements() call is performed.
47550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum target = glmsg->args(0).intvalue(0);
47650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (target == GL_ELEMENT_ARRAY_BUFFER) {
47750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
47850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->bindBuffer(bufferId, datap, size);
47950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
48050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
48150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // add buffer data to the protobuf message
48250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (datap != NULL) {
48350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        addGlBufferData(glmsg, 2, datap, size);
48450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
48550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
48650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
48750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glBufferSubData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
48850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
48950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum target = glmsg->args(0).intvalue(0);
49050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLintptr offset = glmsg->args(1).intvalue(0);
49150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizeiptr size = glmsg->args(2).intvalue(0);
49250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *datap = (GLvoid *) pointersToFixup[0];
49350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (target == GL_ELEMENT_ARRAY_BUFFER) {
49450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
49550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->updateBufferSubData(bufferId, offset, datap, size);
49650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
49750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
49850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // add buffer data to the protobuf message
49950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    addGlBufferData(glmsg, 3, datap, size);
50050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
50150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
50250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Obtain the size of each vertex attribute. */
50350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyint vertexAttribSize(GLenum type, GLsizei numComponents) {
50450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    int sizePerComponent;
50550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
50650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    switch(type) {
50750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_BYTE:
50850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_UNSIGNED_BYTE:
50950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 1;
51050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
51150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_SHORT:
51250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_UNSIGNED_SHORT:
51350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 2;
51450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
51550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_FIXED:
51650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_FLOAT:
51750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    default:
51850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 4;
51950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
52050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
52150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
52250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return sizePerComponent * numComponents;
52350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
52450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
52550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Create and send a glVertexAttribPointerData trace message to the host. */
52650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_glVertexAttribPointerData(GLTraceContext *context,
52750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLuint indx, GLint size, GLenum type,
52850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
52950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLuint minIndex, GLuint maxIndex, nsecs_t startTime) {
53050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type,
53150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
53250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    int minIndex, int maxIndex) */
53350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage glmsg;
53450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLTraceContext *glContext = context;
53550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
53650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_function(GLMessage::glVertexAttribPointerData);
53750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
53850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument indx
53950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_indx = glmsg.add_args();
54050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->set_isarray(false);
54150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->set_type(GLMessage::DataType::INT);
54250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->add_intvalue(indx);
54350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
54450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument size
54550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_size = glmsg.add_args();
54650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->set_isarray(false);
54750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->set_type(GLMessage::DataType::INT);
54850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->add_intvalue(size);
54950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
55050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument type
55150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_type = glmsg.add_args();
55250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->set_isarray(false);
55350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->set_type(GLMessage::DataType::ENUM);
55450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->add_intvalue((int)type);
55550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
55650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument normalized
55750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_normalized = glmsg.add_args();
55850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->set_isarray(false);
55950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->set_type(GLMessage::DataType::BOOL);
56050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->add_boolvalue(normalized);
56150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
56250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument stride
56350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_stride = glmsg.add_args();
56450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->set_isarray(false);
56550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->set_type(GLMessage::DataType::INT);
56650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->add_intvalue(stride);
56750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
56850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument ptr
56950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_ptr = glmsg.add_args();
57050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->set_isarray(true);
57150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->set_type(GLMessage::DataType::BYTE);
57250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    int perVertexSize = vertexAttribSize(type, size);
57350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLchar *p = (GLchar*) ptr;
57450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    std::string data;
57550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLuint i = minIndex; i < maxIndex; i++) {
57650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        data.append(p, perVertexSize);
57750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        p += stride == 0 ? perVertexSize : stride;
57850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
57950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->add_rawbytes(data);
58050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
58150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument min index
58250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_min = glmsg.add_args();
58350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->set_isarray(false);
58450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->set_type(GLMessage::DataType::INT);
58550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->add_intvalue(minIndex);
58650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
58750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument max index
58850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_max = glmsg.add_args();
58950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->set_isarray(false);
59050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->set_type(GLMessage::DataType::INT);
59150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->add_intvalue(maxIndex);
59250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
59350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_context_id(context->getId());
59450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_start_time(startTime);
59550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_threadtime(0);
59650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_duration(0);
59750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
59850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->traceGLMessage(&glmsg);
59950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
60050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
60150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid findMinAndMaxIndices(GLvoid *indices, GLsizei count, GLenum type,
60250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLuint *minIndex, GLuint *maxIndex) {
60350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
60450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    *minIndex = UINT_MAX;
60550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    *maxIndex = 0;
60650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
60750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (indices == NULL) {
60850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        return;
60950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
61050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
61150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLsizei i = 0; i < count; i++) {
61250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (type == GL_UNSIGNED_BYTE) {
61350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            index = *((GLubyte*) indices + i);
61450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        } else {
61550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            index = *((GLushort*) indices + i);
61650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
61750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
61850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (index < *minIndex) *minIndex = index;
61950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (index > *maxIndex) *maxIndex = index;
62050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
62150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
62250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
62350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerData(GLTraceContext *context,
62450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLuint minIndex, GLuint maxIndex, nsecs_t time) {
62550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint maxAttribs = glGetInteger(context, GL_MAX_VERTEX_ATTRIBS);
62650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLuint index = 0; index < maxAttribs; index++) {
62750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (!glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_ENABLED)) {
62850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            // vertex array disabled
62950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            continue;
63050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
63150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
63250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)) {
63350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            // vbo
63450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            continue;
63550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
63650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
63750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint size = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_SIZE);
63850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLenum type = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_TYPE);
63950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLboolean norm = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
64050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLsizei stride = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_STRIDE);
64150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLvoid* ptr;
64250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->hooks->gl.glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
64350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
64450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        trace_glVertexAttribPointerData(context,
64550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    index, size, type, norm, stride, ptr,
64650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    minIndex, maxIndex, time);
64750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
64850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
64950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
65050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerDataForGlDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
6513ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
6523ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy        // only supported for GLES2 and above
6533ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy        return;
6543ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    }
6553ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy
65650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
65750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(2).intvalue(0);
65850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
65950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Vertex attrib pointer data patchup calls should appear as if
66050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // they occurred right before the draw call.
66150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    nsecs_t time = glmsg->start_time() - 1;
66250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
66350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerData(context, 0, count, time);
66450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
66550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
66650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerDataForGlDrawElements(GLTraceContext *context, GLMessage *glmsg,
66750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLvoid *indices) {
6683ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
6693ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy        // only supported for GLES2 and above
6703ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy        return;
6713ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    }
6723ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy
67350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
67450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(1).intvalue(0);
67550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum type = glmsg->args(2).intvalue(0);
67650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
67750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
67850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint minIndex, maxIndex;
67950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
68050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // The index buffer is either passed in as an argument to the glDrawElements() call,
68150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // or it is stored in the current GL_ELEMENT_ARRAY_BUFFER.
68250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *indexBuffer;
68350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (isUsingElementArrayBuffers(context)) {
68450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLsizeiptr eaBufferSize;
68550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLuint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
68650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->getBuffer(bufferId, &indexBuffer, &eaBufferSize);
68750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    } else {
68850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        indexBuffer = indices;
68950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
69050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
69150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Rather than sending vertex attribute data that corresponds to the indices
69250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // being drawn, we send the vertex attribute data for the entire range of
69350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // indices being drawn, including the ones not drawn. The min & max indices
69450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // provide the range of indices being drawn.
69550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    findMinAndMaxIndices(indexBuffer, count, type, &minIndex, &maxIndex);
69650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
69750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Vertex attrib pointer data patchup calls should appear as if
69850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // they occurred right before the draw call.
69950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    nsecs_t time = glmsg->start_time() - 1;
70050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
70150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerData(context, minIndex, maxIndex + 1, time);
70250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
70350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
70450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
70550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Trace all vertex attribute data stored in client space.
70650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerDataForGlDrawArrays(context, glmsg);
70750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
70850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Attach the FB if requested
70950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
71050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
71150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
71250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
71350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
71450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glDrawElements(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
71550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
71650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *indices = pointersToFixup[0];
71750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum type = glmsg->args(2).intvalue(0);
71850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(1).intvalue(0);
71950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
72050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
72150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Trace all vertex attribute data stored in client space.
72250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerDataForGlDrawElements(context, glmsg, indices);
72350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
72450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Fixup indices argument
72550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (!isUsingElementArrayBuffers(context)) {
72650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLMessage_DataType *arg_indices = glmsg->mutable_args(3);
72750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->set_isarray(true);
72850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->clear_intvalue();
72950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->set_type(GLMessage::DataType::INT);
73050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        for (GLsizei i = 0; i < count; i++) {
73150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            if (type == GL_UNSIGNED_BYTE) {
73250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                index = *((GLubyte*) indices + i);
73350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            } else {
73450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                index = *((GLushort*) indices + i);
73550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            }
73650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            arg_indices->add_intvalue(index);
73750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
73850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
73950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
74050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Attach the FB if requested
74150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
74250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
74350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
74450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
74550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
74605df4504e57657994a89e424b6881ee26d0f313cSiva Velusamyvoid fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
74705df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy                                             nsecs_t threadStart, nsecs_t threadEnd,
7489801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                             GLMessage *glmsg, void *pointersToFixup[]) {
74993a826f78f6313db791e6fc880439189897651b3Siva Velusamy    // for all messages, set the current context id
75093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    glmsg->set_context_id(context->getId());
75193a826f78f6313db791e6fc880439189897651b3Siva Velusamy
75256ac6ff9bdc3c117e820c5a361ab45049c8b03f8Siva Velusamy    // set start time and duration
75305df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_start_time(wallStart);
75405df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_duration((unsigned)(wallEnd - wallStart));
75505df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_threadtime((unsigned)(threadEnd - threadStart));
75656ac6ff9bdc3c117e820c5a361ab45049c8b03f8Siva Velusamy
75793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    // do any custom message dependent processing
7580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (glmsg->function()) {
75934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteBuffers:      /* glDeleteBuffers(GLsizei n, GLuint *buffers); */
76034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
76134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
76234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteTextures:     /* glDeleteTextures(GLsizei n, GLuint *textures); */
7639801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glDeleteGeneric(glmsg, pointersToFixup);
76434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        break;
76534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenBuffers:        /* void glGenBuffers(GLsizei n, GLuint *buffers); */
76634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenFramebuffers:   /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
76734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenRenderbuffers:  /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
76834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenTextures:       /* void glGenTextures(GLsizei n, GLuint *textures); */
7699801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGenGeneric(glmsg, pointersToFixup);
7700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
77188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glLinkProgram:       /* void glLinkProgram(GLuint program); */
77288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        fixup_glLinkProgram(glmsg);
77388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
77488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glGetActiveAttrib:
7759801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
77688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
77788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glGetActiveUniform:
7789801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
77988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
78088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glBindAttribLocation:
78188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
7829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
78388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
78450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GLMessage::glGetAttribLocation:
78550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GLMessage::glGetUniformLocation:
7860469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* int glGetAttribLocation(GLuint program, const GLchar* name) */
7870469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* int glGetUniformLocation(GLuint program, const GLchar* name) */
7889801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
7890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetBooleanv:
7919801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetBooleanv(glmsg, pointersToFixup);
7920469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetFloatv:
7949801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetFloatv(glmsg, pointersToFixup);
7950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7960469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetIntegerv:        /* void glGetIntegerv(GLenum pname, GLint *params); */
7979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_GenericIntArray(1, 1, glmsg, pointersToFixup[0]);
7980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7990469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetProgramiv:
8000469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetRenderbufferParameteriv:
8010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetShaderiv:
8020469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
8030469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
8040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
8059801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_GenericIntArray(2, 1, glmsg, pointersToFixup[0]);
8060469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetString:
8089801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetString(glmsg, pointersToFixup);
8090469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glTexImage2D:
8113f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
8129801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy            fixup_glTexImage2D(glmsg, pointersToFixup);
8133f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        }
8140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
81534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glTexSubImage2D:
81634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
8179801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy            fixup_glTexSubImage2D(glmsg, pointersToFixup);
81834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        }
81934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        break;
8203d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    case GLMessage::glCompressedTexImage2D:
8213d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
8223d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton            fixup_glCompressedTexImage2D(glmsg, pointersToFixup);
8233d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        }
8243d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        break;
8253d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton    case GLMessage::glCompressedTexSubImage2D:
8263d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
8273d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton            fixup_glCompressedTexSubImage2D(glmsg, pointersToFixup);
8283d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        }
8293d3c125423ab922e705c3f563c689bd7c4a04bacBen Clayton        break;
8300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glShaderSource:
8319801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glShaderSource(glmsg, pointersToFixup);
8320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
83388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform1iv:
83488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
8359801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 1, glmsg, pointersToFixup);
83688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
83788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform2iv:
83888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
8399801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 2, glmsg, pointersToFixup);
84088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
84188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform3iv:
84288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
8439801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 3, glmsg, pointersToFixup);
84488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
84588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform4iv:
84688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
8479801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 4, glmsg, pointersToFixup);
84888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
84988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform1fv:
85088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
8519801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 1, glmsg, pointersToFixup[0]);
85288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
85388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform2fv:
85488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
8559801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 2, glmsg, pointersToFixup[0]);
85688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
85788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform3fv:
85888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
8599801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 3, glmsg, pointersToFixup[0]);
86088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
86188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform4fv:
86288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
8639801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 4, glmsg, pointersToFixup[0]);
86488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
8650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix2fv:
8660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
8670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
8689801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(2, glmsg, pointersToFixup);
8690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix3fv:
8710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
8720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
8739801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(3, glmsg, pointersToFixup);
8740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix4fv:
8760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
8770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
8789801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(4, glmsg, pointersToFixup);
8790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8809291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy    case GLMessage::glBufferData:
8819291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
88250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glBufferData(context, glmsg, pointersToFixup);
8839291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        break;
8849291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy    case GLMessage::glBufferSubData:
8859291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
88650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glBufferSubData(context, glmsg, pointersToFixup);
8879291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        break;
8880469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glDrawArrays:
8890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
89050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glDrawArrays(context, glmsg);
8913f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        break;
8923f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    case GLMessage::glDrawElements:
8930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
89450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glDrawElements(context, glmsg, pointersToFixup);
8950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
896a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy    case GLMessage::glPushGroupMarkerEXT:
897a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        /* void PushGroupMarkerEXT(sizei length, const char *marker); */
8989801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
899a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        break;
900a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy    case GLMessage::glInsertEventMarkerEXT:
901a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        /* void InsertEventMarkerEXT(sizei length, const char *marker); */
9029801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
903a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        break;
9040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
9050469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
9060469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
9070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
9080469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
9090469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};
9100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};
911