gltrace_fixup.cpp revision 300ad09822db1013d9f28c4bca3680f865533ab6
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>
1888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES/gl.h>
1988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES/glext.h>
200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <GLES2/gl2.h>
2188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include <GLES2/gl2ext.h>
220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace.pb.h"
2488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy#include "gltrace_api.h"
250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_context.h"
260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_fixup.h"
270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android {
290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace {
300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyunsigned getBytesPerTexel(const GLenum format, const GLenum type) {
320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /*
330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    Description from glTexImage2D spec:
340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    Data is read from data as a sequence of unsigned bytes or shorts, depending on type.
360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    When type is GL_UNSIGNED_BYTE, each of the bytes is interpreted as one color component.
370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    When type is one of GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or
380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GL_UNSIGNED_SHORT_5_5_5_1, each unsigned short value is interpreted as containing all
390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    the components for a single texel, with the color components arranged according to
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    format. Color components are treated as groups of one, two, three, or four values,
410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    again based on format. Groups of components are referred to as texels.
420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    width × height texels are read from memory, starting at location data. By default,
440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    these texels are taken from adjacent memory locations, except that after all width
450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    texels are read, the read pointer is advanced to the next four-byte boundary.
460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    The four-byte row alignment is specified by glPixelStorei with argument
470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    */
490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (type) {
510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_5_6_5:
520469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_4_4_4_4:
530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_SHORT_5_5_5_1:
540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 2;
550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_UNSIGNED_BYTE:
560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
58e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GetBytesPerPixel: unknown type %x", type);
590469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (format) {
620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_ALPHA:
630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_LUMINANCE:
640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 1;
650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_LUMINANCE_ALPHA:
660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 2;
670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_RGB:
680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 3;
690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GL_RGBA:
700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case 0x80E1: // GL_BGRA_EXT
710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return 4;
720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
73e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GetBytesPerPixel: unknown format %x", format);
740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    return 1;   // in doubt...
770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
799801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericFloatArray(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
809801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_floatarray = glmsg->mutable_args(argIndex);
819801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLfloat *floatp = (GLfloat *)src;
829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
839801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    if (floatp == NULL) {
849801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        return;
859801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
869801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
879801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->set_type(GLMessage::DataType::FLOAT);
889801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->set_isarray(true);
899801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_floatarray->clear_floatvalue();
909801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
919801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    for (int i = 0; i < nFloats; i++, floatp++) {
929801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        arg_floatarray->add_floatvalue(*floatp);
939801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
949801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
959801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
969801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg, void *src) {
979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
989801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLint *intp = (GLint *)src;
999801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1009801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    if (intp == NULL) {
1019801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        return;
1029801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
1039801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1049801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->set_type(GLMessage::DataType::INT);
1059801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->set_isarray(true);
1069801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_intarray->clear_intvalue();
1079801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1089801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    for (int i = 0; i < nInts; i++, intp++) {
1099801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        arg_intarray->add_intvalue(*intp);
1109801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    }
1119801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
1129801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1139801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg, void *src) {
1149801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    // fixup as if they were ints
1159801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(argIndex, nEnums, glmsg, src);
1169801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1179801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    // and then set the data type to be enum
1189801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
1199801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    arg_enumarray->set_type(GLMessage::DataType::ENUM);
1209801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy}
1219801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy
1220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/** Generic helper function: extract pointer at argIndex and
1230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    replace it with the C style string at *pointer */
1249801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_CStringPtr(int argIndex, GLMessage *glmsg, void *src) {
1250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
1269801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar *ptr = (GLchar *) src;
1270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->set_type(GLMessage::DataType::CHAR);
1290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->set_isarray(true);
1300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg->add_charvalue(ptr);
1310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1339801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetString(GLMessage *glmsg, void *pointersToFixup[]) {
1340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* const GLubyte* GLTrace_glGetString(GLenum name) */
1350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *ret = glmsg->mutable_returnvalue();
1369801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar *ptr = (GLchar *) pointersToFixup[0];
1370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (ptr != NULL) {
1390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->set_type(GLMessage::DataType::CHAR);
1400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->set_isarray(true);
1410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        ret->add_charvalue(ptr);
1420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
145a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy/* Add the contents of the framebuffer to the protobuf message */
14693a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid fixup_addFBContents(GLTraceContext *context, GLMessage *glmsg, FBBinding fbToRead) {
147a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    void *fbcontents;
1480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    unsigned fbsize, fbwidth, fbheight;
14993a826f78f6313db791e6fc880439189897651b3Siva Velusamy    context->getCompressedFB(&fbcontents, &fbsize, &fbwidth, &fbheight, fbToRead);
1500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
151a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    GLMessage_FrameBuffer *fb = glmsg->mutable_fb();
152a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->set_width(fbwidth);
153a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->set_height(fbheight);
154a8cfde8897c840ce6a491a054ade806b41df2a70Siva Velusamy    fb->add_contents(fbcontents, fbsize);
1550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
15734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy/** Common fixup routing for glTexImage2D & glTexSubImage2D. */
1589801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg, void *dataSrc) {
15934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_width  = glmsg->args(widthIndex);
16034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_height = glmsg->args(heightIndex);
16134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
1620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_format = glmsg->args(6);
1630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_type   = glmsg->args(7);
1640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);
1650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei width  = arg_width.intvalue(0);
1670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei height = arg_height.intvalue(0);
1680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLenum format  = arg_format.intvalue(0);
1690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLenum type    = arg_type.intvalue(0);
1709801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    void *data     = (void *) dataSrc;
1710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int bytesPerTexel = getBytesPerTexel(format, type);
1730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_data->set_type(GLMessage::DataType::BYTE);
1750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_data->clear_rawbytes();
1760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (data != NULL) {
17834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        arg_data->set_isarray(true);
1790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        arg_data->add_rawbytes(data, bytesPerTexel * width * height);
1800469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    } else {
18134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        arg_data->set_isarray(false);
1820469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        arg_data->set_type(GLMessage::DataType::VOID);
1830469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1840469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1850469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
18634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
1879801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
18834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /* void glTexImage2D(GLenum target,
18934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint level,
19034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint internalformat,
19134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei width,
19234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei height,
19334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint border,
19434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum format,
19534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum type,
19650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                        const GLvoid *data);
19734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    */
19834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int widthIndex = 3;
19934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int heightIndex = 4;
2009801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
20134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
20234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2039801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
20434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /*
20534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    void glTexSubImage2D(GLenum target,
20634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint level,
20734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint xoffset,
20834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLint yoffset,
20934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei width,
21034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLsizei height,
21134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum format,
21234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        GLenum type,
21334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy                        const GLvoid * data);
21434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    */
21534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int widthIndex = 4;
21634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    int heightIndex = 5;
2179801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
21834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
21934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2209801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
22150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
2220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                    const GLint* length) */
2230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_count  = glmsg->args(1);
2240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_lenp   = glmsg->args(3);
2250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);
2260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei count = arg_count.intvalue(0);
2289801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLchar **stringpp = (GLchar **) pointersToFixup[0];
2299801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLint *lengthp = (GLint *) pointersToFixup[1];
2300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->set_type(GLMessage::DataType::CHAR);
2320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->set_isarray(true);
2330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->clear_charvalue();
2340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    ::std::string src = "";
2360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    for (int i = 0; i < count; i++) {
2370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        if (lengthp != NULL)
2380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy            src.append(*stringpp, *lengthp);
2390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        else
2400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy            src.append(*stringpp);  // assume null terminated
2410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        stringpp++;
2420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        lengthp++;
2430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
2440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_strpp->add_charvalue(src);
2460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2489801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg,
2499801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                                                    void *pointersToFixup[]) {
25088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
2519801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(argIndex, nIntegers, glmsg, pointersToFixup[0]);
25288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
25388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
2549801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
2559801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericFloatArray(argIndex, nFloats, glmsg, src);
2560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2589801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
25950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
2600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                const GLfloat* value) */
2610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_count  = glmsg->args(1);
2620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int n_matrices = arg_count.intvalue(0);
2639801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
2640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2669801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
2670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGen*(GLsizei n, GLuint * buffers); */
2680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType arg_n  = glmsg->args(0);
2690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLsizei n = arg_n.intvalue(0);
2700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2719801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
2720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2749801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glDeleteGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
27534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    /* void glDelete*(GLsizei n, GLuint *buffers); */
27634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLMessage_DataType arg_n  = glmsg->args(0);
27734c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    GLsizei n = arg_n.intvalue(0);
27834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2799801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
28034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy}
28134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy
2829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetBooleanv(GLMessage *glmsg, void *pointersToFixup[]) {
2830469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGetBooleanv(GLenum pname, GLboolean *params); */
2840469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
2859801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLboolean *src = (GLboolean*) pointersToFixup[0];
2860469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2870469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_type(GLMessage::DataType::BOOL);
2880469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_isarray(true);
2890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->clear_boolvalue();
2900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->add_boolvalue(*src);
2910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2920469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2939801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamyvoid fixup_glGetFloatv(GLMessage *glmsg, void *pointersToFixup[]) {
2940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    /* void glGetFloatv(GLenum pname, GLfloat *params); */
2950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
2969801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    GLfloat *src = (GLfloat*) pointersToFixup[0];
2970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
2980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_type(GLMessage::DataType::FLOAT);
2990469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->set_isarray(true);
3000469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->clear_floatvalue();
3010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    arg_params->add_floatvalue(*src);
3020469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
3030469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
30488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamyvoid fixup_glLinkProgram(GLMessage *glmsg) {
30588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glLinkProgram(GLuint program); */
30688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLuint program = glmsg->args(0).intvalue(0);
30788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
30888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* We don't have to fixup this call, but as soon as a program is linked,
30988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       we obtain information about all active attributes and uniforms to
31088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       pass on to the debugger. Note that in order to pass this info to
31188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       the debugger, all we need to do is call the trace versions of the
31288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy       necessary calls. */
31388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
31488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLint n, maxNameLength;
31588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLchar *name;
31688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLint size;
31788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLenum type;
31888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
31988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // obtain info regarding active attributes
32088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
32188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
32288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
32388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    name = (GLchar *) malloc(maxNameLength);
32488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    for (int i = 0; i < n; i++) {
32588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        GLTrace_glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name);
32688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
32788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    free(name);
32888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
32988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // obtain info regarding active uniforms
33088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
33188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
33288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
33388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    name = (GLchar *) malloc(maxNameLength);
33488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    for (int i = 0; i < n; i++) {
33588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        GLTrace_glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name);
33688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
33788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    free(name);
33888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
33988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
34088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy/** Given a glGetActive[Uniform|Attrib] call, obtain the location
3419801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy *  of the variable of given name in the call.
34288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy */
343300ad09822db1013d9f28c4bca3680f865533ab6Andrew HsiehGLint getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar *name) {
34488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLMessage_Function func = glmsg->function();
34588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
34688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return -1;
34788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
34888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
34988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    int program = glmsg->args(0).intvalue(0);
35088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
35188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    if (func == GLMessage::glGetActiveAttrib) {
35288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return context->hooks->gl.glGetAttribLocation(program, name);
35388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    } else {
35488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        return context->hooks->gl.glGetUniformLocation(program, name);
35588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    }
35688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
35788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
35850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
3599801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                                                void *pointersToFixup[]) {
36088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
36188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy                GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
36288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    /* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
36388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy                GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
36488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
3659801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(3, 1, glmsg, pointersToFixup[0]);     // length
3669801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericIntArray(4, 1, glmsg, pointersToFixup[1]);     // size
3679801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_GenericEnumArray(5, 1, glmsg, pointersToFixup[2]);    // type
3689801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy    fixup_CStringPtr(6, glmsg, pointersToFixup[3]);             // name
36988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
37088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // The index argument in the glGetActive[Attrib|Uniform] functions
37188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // does not correspond to the actual location index as used in
37288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // glUniform*() or glVertexAttrib*() to actually upload the data.
37388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // In order to make things simpler for the debugger, we also pass
37488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // a hidden location argument that stores the actual location.
37588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    // append the location value to the end of the argument list
376300ad09822db1013d9f28c4bca3680f865533ab6Andrew Hsieh    GLint location = getShaderVariableLocation(context, glmsg, (GLchar*)pointersToFixup[3]);
37788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    GLMessage_DataType *arg_location = glmsg->add_args();
37888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->set_isarray(false);
37988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->set_type(GLMessage::DataType::INT);
38088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    arg_location->add_intvalue(location);
38188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy}
38288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy
38350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLint glGetInteger(GLTraceContext *context, GLenum param) {
38450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLint x;
38550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->hooks->gl.glGetIntegerv(param, &x);
38650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return x;
38750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
38850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
38950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLint glGetVertexAttrib(GLTraceContext *context, GLuint index, GLenum pname) {
39050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLint x;
39150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->hooks->gl.glGetVertexAttribiv(index, pname, &x);
39250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return x;
39350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
39450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
39550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamybool isUsingArrayBuffers(GLTraceContext *context) {
39650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return glGetInteger(context, GL_ARRAY_BUFFER_BINDING) != 0;
39750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
39850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
39950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamybool isUsingElementArrayBuffers(GLTraceContext *context) {
40050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0;
40150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
40250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
40350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Copy @len bytes of data from @src into the @dataIndex'th argument of the message. */
40450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid addGlBufferData(GLMessage *glmsg, int dataIndex, GLvoid *src, GLsizeiptr len) {
40550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
40650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->set_type(GLMessage::DataType::VOID);
40750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->set_isarray(true);
40850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->clear_intvalue();
40950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_datap->add_rawbytes(src, len);
41050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
41150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
41250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glBufferData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
41350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
41450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizeiptr size = glmsg->args(1).intvalue(0);
41550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *datap = (GLvoid *) pointersToFixup[0];
41650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
41750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Save element array buffers for future use to fixup glVertexAttribPointers
41850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // when a glDrawElements() call is performed.
41950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum target = glmsg->args(0).intvalue(0);
42050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (target == GL_ELEMENT_ARRAY_BUFFER) {
42150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
42250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->bindBuffer(bufferId, datap, size);
42350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
42450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
42550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // add buffer data to the protobuf message
42650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (datap != NULL) {
42750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        addGlBufferData(glmsg, 2, datap, size);
42850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
42950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
43050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
43150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glBufferSubData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
43250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
43350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum target = glmsg->args(0).intvalue(0);
43450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLintptr offset = glmsg->args(1).intvalue(0);
43550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizeiptr size = glmsg->args(2).intvalue(0);
43650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *datap = (GLvoid *) pointersToFixup[0];
43750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (target == GL_ELEMENT_ARRAY_BUFFER) {
43850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
43950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->updateBufferSubData(bufferId, offset, datap, size);
44050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
44150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
44250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // add buffer data to the protobuf message
44350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    addGlBufferData(glmsg, 3, datap, size);
44450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
44550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
44650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Obtain the size of each vertex attribute. */
44750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyint vertexAttribSize(GLenum type, GLsizei numComponents) {
44850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    int sizePerComponent;
44950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
45050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    switch(type) {
45150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_BYTE:
45250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_UNSIGNED_BYTE:
45350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 1;
45450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
45550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_SHORT:
45650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_UNSIGNED_SHORT:
45750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 2;
45850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
45950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_FIXED:
46050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GL_FLOAT:
46150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    default:
46250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        sizePerComponent = 4;
46350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        break;
46450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
46550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
46650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return sizePerComponent * numComponents;
46750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
46850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
46950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy/** Create and send a glVertexAttribPointerData trace message to the host. */
47050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_glVertexAttribPointerData(GLTraceContext *context,
47150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLuint indx, GLint size, GLenum type,
47250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
47350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLuint minIndex, GLuint maxIndex, nsecs_t startTime) {
47450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type,
47550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    GLboolean normalized, GLsizei stride, const GLvoid* ptr,
47650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    int minIndex, int maxIndex) */
47750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage glmsg;
47850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLTraceContext *glContext = context;
47950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
48050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_function(GLMessage::glVertexAttribPointerData);
48150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
48250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument indx
48350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_indx = glmsg.add_args();
48450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->set_isarray(false);
48550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->set_type(GLMessage::DataType::INT);
48650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_indx->add_intvalue(indx);
48750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
48850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument size
48950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_size = glmsg.add_args();
49050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->set_isarray(false);
49150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->set_type(GLMessage::DataType::INT);
49250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_size->add_intvalue(size);
49350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
49450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument type
49550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_type = glmsg.add_args();
49650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->set_isarray(false);
49750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->set_type(GLMessage::DataType::ENUM);
49850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_type->add_intvalue((int)type);
49950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
50050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument normalized
50150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_normalized = glmsg.add_args();
50250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->set_isarray(false);
50350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->set_type(GLMessage::DataType::BOOL);
50450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_normalized->add_boolvalue(normalized);
50550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
50650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument stride
50750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_stride = glmsg.add_args();
50850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->set_isarray(false);
50950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->set_type(GLMessage::DataType::INT);
51050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_stride->add_intvalue(stride);
51150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
51250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument ptr
51350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_ptr = glmsg.add_args();
51450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->set_isarray(true);
51550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->set_type(GLMessage::DataType::BYTE);
51650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    int perVertexSize = vertexAttribSize(type, size);
51750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLchar *p = (GLchar*) ptr;
51850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    std::string data;
51950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLuint i = minIndex; i < maxIndex; i++) {
52050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        data.append(p, perVertexSize);
52150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        p += stride == 0 ? perVertexSize : stride;
52250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
52350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_ptr->add_rawbytes(data);
52450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
52550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument min index
52650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_min = glmsg.add_args();
52750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->set_isarray(false);
52850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->set_type(GLMessage::DataType::INT);
52950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_min->add_intvalue(minIndex);
53050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
53150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // copy argument max index
53250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLMessage_DataType *arg_max = glmsg.add_args();
53350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->set_isarray(false);
53450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->set_type(GLMessage::DataType::INT);
53550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    arg_max->add_intvalue(maxIndex);
53650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
53750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_context_id(context->getId());
53850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_start_time(startTime);
53950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_threadtime(0);
54050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    glmsg.set_duration(0);
54150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
54250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    context->traceGLMessage(&glmsg);
54350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
54450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
54550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid findMinAndMaxIndices(GLvoid *indices, GLsizei count, GLenum type,
54650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLuint *minIndex, GLuint *maxIndex) {
54750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
54850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    *minIndex = UINT_MAX;
54950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    *maxIndex = 0;
55050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
55150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (indices == NULL) {
55250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        return;
55350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
55450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
55550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLsizei i = 0; i < count; i++) {
55650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (type == GL_UNSIGNED_BYTE) {
55750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            index = *((GLubyte*) indices + i);
55850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        } else {
55950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            index = *((GLushort*) indices + i);
56050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
56150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
56250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (index < *minIndex) *minIndex = index;
56350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (index > *maxIndex) *maxIndex = index;
56450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
56550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
56650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
56750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerData(GLTraceContext *context,
56850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLuint minIndex, GLuint maxIndex, nsecs_t time) {
56950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint maxAttribs = glGetInteger(context, GL_MAX_VERTEX_ATTRIBS);
57050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    for (GLuint index = 0; index < maxAttribs; index++) {
57150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (!glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_ENABLED)) {
57250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            // vertex array disabled
57350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            continue;
57450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
57550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
57650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        if (glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)) {
57750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            // vbo
57850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            continue;
57950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
58050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
58150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLint size = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_SIZE);
58250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLenum type = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_TYPE);
58350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLboolean norm = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
58450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLsizei stride = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_STRIDE);
58550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLvoid* ptr;
58650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->hooks->gl.glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
58750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
58850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        trace_glVertexAttribPointerData(context,
58950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    index, size, type, norm, stride, ptr,
59050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                    minIndex, maxIndex, time);
59150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
59250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
59350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
59450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerDataForGlDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
59550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
59650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(2).intvalue(0);
59750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
59850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Vertex attrib pointer data patchup calls should appear as if
59950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // they occurred right before the draw call.
60050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    nsecs_t time = glmsg->start_time() - 1;
60150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
60250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerData(context, 0, count, time);
60350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
60450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
60550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid trace_VertexAttribPointerDataForGlDrawElements(GLTraceContext *context, GLMessage *glmsg,
60650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                            GLvoid *indices) {
60750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
60850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(1).intvalue(0);
60950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum type = glmsg->args(2).intvalue(0);
61050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
61150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
61250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint minIndex, maxIndex;
61350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
61450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // The index buffer is either passed in as an argument to the glDrawElements() call,
61550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // or it is stored in the current GL_ELEMENT_ARRAY_BUFFER.
61650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *indexBuffer;
61750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (isUsingElementArrayBuffers(context)) {
61850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLsizeiptr eaBufferSize;
61950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLuint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
62050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        context->getBuffer(bufferId, &indexBuffer, &eaBufferSize);
62150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    } else {
62250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        indexBuffer = indices;
62350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
62450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
62550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Rather than sending vertex attribute data that corresponds to the indices
62650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // being drawn, we send the vertex attribute data for the entire range of
62750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // indices being drawn, including the ones not drawn. The min & max indices
62850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // provide the range of indices being drawn.
62950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    findMinAndMaxIndices(indexBuffer, count, type, &minIndex, &maxIndex);
63050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
63150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Vertex attrib pointer data patchup calls should appear as if
63250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // they occurred right before the draw call.
63350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    nsecs_t time = glmsg->start_time() - 1;
63450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
63550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerData(context, minIndex, maxIndex + 1, time);
63650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
63750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
63850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
63950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Trace all vertex attribute data stored in client space.
64050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerDataForGlDrawArrays(context, glmsg);
64150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
64250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Attach the FB if requested
64350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
64450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
64550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
64650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
64750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
64850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid fixup_glDrawElements(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
64950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
65050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLvoid *indices = pointersToFixup[0];
65150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLenum type = glmsg->args(2).intvalue(0);
65250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLsizei count = glmsg->args(1).intvalue(0);
65350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    GLuint index;
65450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
65550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Trace all vertex attribute data stored in client space.
65650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    trace_VertexAttribPointerDataForGlDrawElements(context, glmsg, indices);
65750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
65850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Fixup indices argument
65950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (!isUsingElementArrayBuffers(context)) {
66050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        GLMessage_DataType *arg_indices = glmsg->mutable_args(3);
66150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->set_isarray(true);
66250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->clear_intvalue();
66350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        arg_indices->set_type(GLMessage::DataType::INT);
66450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        for (GLsizei i = 0; i < count; i++) {
66550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            if (type == GL_UNSIGNED_BYTE) {
66650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                index = *((GLubyte*) indices + i);
66750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            } else {
66850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                index = *((GLushort*) indices + i);
66950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            }
67050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy            arg_indices->add_intvalue(index);
67150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        }
67250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
67350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
67450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // Attach the FB if requested
67550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
67650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
67750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
67850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
67950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
68005df4504e57657994a89e424b6881ee26d0f313cSiva Velusamyvoid fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
68105df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy                                             nsecs_t threadStart, nsecs_t threadEnd,
6829801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy                                             GLMessage *glmsg, void *pointersToFixup[]) {
68393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    // for all messages, set the current context id
68493a826f78f6313db791e6fc880439189897651b3Siva Velusamy    glmsg->set_context_id(context->getId());
68593a826f78f6313db791e6fc880439189897651b3Siva Velusamy
68656ac6ff9bdc3c117e820c5a361ab45049c8b03f8Siva Velusamy    // set start time and duration
68705df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_start_time(wallStart);
68805df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_duration((unsigned)(wallEnd - wallStart));
68905df4504e57657994a89e424b6881ee26d0f313cSiva Velusamy    glmsg->set_threadtime((unsigned)(threadEnd - threadStart));
69056ac6ff9bdc3c117e820c5a361ab45049c8b03f8Siva Velusamy
69193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    // do any custom message dependent processing
6920469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    switch (glmsg->function()) {
69334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteBuffers:      /* glDeleteBuffers(GLsizei n, GLuint *buffers); */
69434c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
69534c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
69634c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glDeleteTextures:     /* glDeleteTextures(GLsizei n, GLuint *textures); */
6979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glDeleteGeneric(glmsg, pointersToFixup);
69834c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        break;
69934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenBuffers:        /* void glGenBuffers(GLsizei n, GLuint *buffers); */
70034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenFramebuffers:   /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
70134c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenRenderbuffers:  /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
70234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glGenTextures:       /* void glGenTextures(GLsizei n, GLuint *textures); */
7039801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGenGeneric(glmsg, pointersToFixup);
7040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
70588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glLinkProgram:       /* void glLinkProgram(GLuint program); */
70688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        fixup_glLinkProgram(glmsg);
70788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
70888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glGetActiveAttrib:
7099801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
71088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
71188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glGetActiveUniform:
7129801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
71388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
71488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glBindAttribLocation:
71588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
7169801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
71788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
71850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GLMessage::glGetAttribLocation:
71950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    case GLMessage::glGetUniformLocation:
7200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* int glGetAttribLocation(GLuint program, const GLchar* name) */
7210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* int glGetUniformLocation(GLuint program, const GLchar* name) */
7229801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
7230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetBooleanv:
7259801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetBooleanv(glmsg, pointersToFixup);
7260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetFloatv:
7289801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetFloatv(glmsg, pointersToFixup);
7290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetIntegerv:        /* void glGetIntegerv(GLenum pname, GLint *params); */
7319801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_GenericIntArray(1, 1, glmsg, pointersToFixup[0]);
7320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetProgramiv:
7340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetRenderbufferParameteriv:
7350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetShaderiv:
7360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
7370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
7380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
7399801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_GenericIntArray(2, 1, glmsg, pointersToFixup[0]);
7400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glGetString:
7429801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glGetString(glmsg, pointersToFixup);
7430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glTexImage2D:
7453f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
7469801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy            fixup_glTexImage2D(glmsg, pointersToFixup);
7473f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        }
7480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
74934c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy    case GLMessage::glTexSubImage2D:
75034c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
7519801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy            fixup_glTexSubImage2D(glmsg, pointersToFixup);
75234c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        }
75334c726efb54a941a97a6d7252e7c1442d2eded56Siva Velusamy        break;
7540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glShaderSource:
7559801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glShaderSource(glmsg, pointersToFixup);
7560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
75788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform1iv:
75888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
7599801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 1, glmsg, pointersToFixup);
76088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
76188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform2iv:
76288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
7639801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 2, glmsg, pointersToFixup);
76488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
76588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform3iv:
76688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
7679801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 3, glmsg, pointersToFixup);
76888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
76988e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform4iv:
77088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
7719801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGenericInteger(2, 4, glmsg, pointersToFixup);
77288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
77388e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform1fv:
77488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
7759801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 1, glmsg, pointersToFixup[0]);
77688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
77788e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform2fv:
77888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
7799801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 2, glmsg, pointersToFixup[0]);
78088e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
78188e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform3fv:
78288e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
7839801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 3, glmsg, pointersToFixup[0]);
78488e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
78588e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy    case GLMessage::glUniform4fv:
78688e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        /* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
7879801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformGeneric(2, 4, glmsg, pointersToFixup[0]);
78888e8e5a3f16f0003bd2b43142241b8e1a9a46abeSiva Velusamy        break;
7890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix2fv:
7900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
7910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
7929801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(2, glmsg, pointersToFixup);
7930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix3fv:
7950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
7960469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
7979801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(3, glmsg, pointersToFixup);
7980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
7990469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glUniformMatrix4fv:
8000469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
8010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                                                    const GLfloat* value) */
8029801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_glUniformMatrixGeneric(4, glmsg, pointersToFixup);
8030469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8049291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy    case GLMessage::glBufferData:
8059291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
80650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glBufferData(context, glmsg, pointersToFixup);
8079291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        break;
8089291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy    case GLMessage::glBufferSubData:
8099291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
81050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glBufferSubData(context, glmsg, pointersToFixup);
8119291da97cbb5f8d3ae5eb9e8d5415ef85916d982Siva Velusamy        break;
8120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    case GLMessage::glDrawArrays:
8130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
81450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glDrawArrays(context, glmsg);
8153f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy        break;
8163f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    case GLMessage::glDrawElements:
8170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
81850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        fixup_glDrawElements(context, glmsg, pointersToFixup);
8190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
820a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy    case GLMessage::glPushGroupMarkerEXT:
821a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        /* void PushGroupMarkerEXT(sizei length, const char *marker); */
8229801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
823a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        break;
824a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy    case GLMessage::glInsertEventMarkerEXT:
825a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        /* void InsertEventMarkerEXT(sizei length, const char *marker); */
8269801142afbe3d906259b634ef3bc8bebdafe0083Siva Velusamy        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
827a7167f364737c12e621d836f470cf328c6e111cdSiva Velusamy        break;
8280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    default:
8290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        break;
8300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
8310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
8320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
8330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};
8340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};
835