Merge "gltrace: Send vertex attribute data after glDraw() call."

This commit is contained in:
Siva Velusamy 2012-03-06 08:59:32 -08:00 committed by Android (Google) Code Review
commit 2178dcf149
7 changed files with 418 additions and 51 deletions

View File

@ -6,10 +6,9 @@ genproto: gltrace.proto
aprotoc --cpp_out=src --java_out=java gltrace.proto
mv src/gltrace.pb.cc src/gltrace.pb.cpp
# NOTE: $OUT should be defined in the shell by doing a "lunch <config>"
# push updated files to device
push:
adb push $(OUT)/system/lib/libGLESv2.so /system/lib/
adb push $(OUT)/system/lib/libGLESv1_CM.so /system/lib/
adb push $(OUT)/system/lib/libGLES_trace.so /system/lib/
adb push $(OUT)/system/lib/libEGL.so /system/lib/
sync:
adb root
adb remount
adb shell stop
adb sync
adb shell start

View File

@ -510,7 +510,7 @@ message GLMessage {
eglGetSystemTimeNV = 2045;
invalid = 3000;
frameBufferContents = 3001;
glVertexAttribPointerData = 3001;
}
// A GL call's return data and arguments are formatted into this DataType

View File

@ -1018,7 +1018,7 @@ const GLMessage_Function GLMessage::eglGetRenderBufferANDROID;
const GLMessage_Function GLMessage::eglGetSystemTimeFrequencyNV;
const GLMessage_Function GLMessage::eglGetSystemTimeNV;
const GLMessage_Function GLMessage::invalid;
const GLMessage_Function GLMessage::frameBufferContents;
const GLMessage_Function GLMessage::glVertexAttribPointerData;
const GLMessage_Function GLMessage::Function_MIN;
const GLMessage_Function GLMessage::Function_MAX;
const int GLMessage::Function_ARRAYSIZE;

View File

@ -535,11 +535,11 @@ enum GLMessage_Function {
GLMessage_Function_eglGetSystemTimeFrequencyNV = 2044,
GLMessage_Function_eglGetSystemTimeNV = 2045,
GLMessage_Function_invalid = 3000,
GLMessage_Function_frameBufferContents = 3001
GLMessage_Function_glVertexAttribPointerData = 3001
};
bool GLMessage_Function_IsValid(int value);
const GLMessage_Function GLMessage_Function_Function_MIN = GLMessage_Function_glActiveTexture;
const GLMessage_Function GLMessage_Function_Function_MAX = GLMessage_Function_frameBufferContents;
const GLMessage_Function GLMessage_Function_Function_MAX = GLMessage_Function_glVertexAttribPointerData;
const int GLMessage_Function_Function_ARRAYSIZE = GLMessage_Function_Function_MAX + 1;
// ===================================================================
@ -1351,7 +1351,7 @@ class GLMessage : public ::google::protobuf::MessageLite {
static const Function eglGetSystemTimeFrequencyNV = GLMessage_Function_eglGetSystemTimeFrequencyNV;
static const Function eglGetSystemTimeNV = GLMessage_Function_eglGetSystemTimeNV;
static const Function invalid = GLMessage_Function_invalid;
static const Function frameBufferContents = GLMessage_Function_frameBufferContents;
static const Function glVertexAttribPointerData = GLMessage_Function_glVertexAttribPointerData;
static inline bool Function_IsValid(int value) {
return GLMessage_Function_IsValid(value);
}

View File

@ -129,13 +129,14 @@ GLTraceContext *GLTraceState::getTraceContext(EGLContext c) {
return mPerContextState[c];
}
GLTraceContext::GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream) {
mId = id;
mState = state;
GLTraceContext::GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream) :
mId(id),
mState(state),
mBufferedOutputStream(stream),
mElementArrayBuffers(DefaultKeyedVector<GLuint, ElementArrayBuffer*>(NULL))
{
fbcontents = fbcompressed = NULL;
fbcontentsSize = 0;
mBufferedOutputStream = stream;
}
int GLTraceContext::getId() {
@ -208,5 +209,74 @@ void GLTraceContext::traceGLMessage(GLMessage *msg) {
}
}
void GLTraceContext::bindBuffer(GLuint bufferId, GLvoid *data, GLsizeiptr size) {
// free previously bound buffer if any
ElementArrayBuffer *oldBuffer = mElementArrayBuffers.valueFor(bufferId);
if (oldBuffer != NULL) {
delete oldBuffer;
}
mElementArrayBuffers.add(bufferId, new ElementArrayBuffer(data, size));
}
void GLTraceContext::getBuffer(GLuint bufferId, GLvoid **data, GLsizeiptr *size) {
ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
if (buffer == NULL) {
*data = NULL;
*size = 0;
} else {
*data = buffer->getBuffer();
*size = buffer->getSize();
}
}
void GLTraceContext::updateBufferSubData(GLuint bufferId, GLintptr offset, GLvoid *data,
GLsizeiptr size) {
ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
if (buffer != NULL) {
buffer->updateSubBuffer(offset, data, size);
}
}
void GLTraceContext::deleteBuffer(GLuint bufferId) {
ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
if (buffer != NULL) {
delete buffer;
mElementArrayBuffers.removeItem(bufferId);
}
}
ElementArrayBuffer::ElementArrayBuffer(GLvoid *buf, GLsizeiptr size) {
mBuf = malloc(size);
mSize = size;
if (buf != NULL) {
memcpy(mBuf, buf, size);
}
}
ElementArrayBuffer::~ElementArrayBuffer() {
if (mBuf != NULL) {
free(mBuf);
mSize = 0;
}
mBuf = NULL;
}
void ElementArrayBuffer::updateSubBuffer(GLintptr offset, const GLvoid* data, GLsizeiptr size) {
if (offset + size <= mSize) {
memcpy((char*)mBuf + offset, data, size);
}
}
GLvoid *ElementArrayBuffer::getBuffer() {
return mBuf;
}
GLsizeiptr ElementArrayBuffer::getSize() {
return mSize;
}
}; // namespace gltrace
}; // namespace android

View File

@ -19,6 +19,7 @@
#include <map>
#include <pthread.h>
#include <utils/KeyedVector.h>
#include "hooks.h"
#include "gltrace_transport.h"
@ -32,6 +33,20 @@ enum FBBinding {CURRENTLY_BOUND_FB, FB0};
class GLTraceState;
class ElementArrayBuffer {
GLvoid *mBuf;
GLsizeiptr mSize;
public:
ElementArrayBuffer():mBuf(NULL), mSize(0) {}
ElementArrayBuffer(GLvoid *buf, GLsizeiptr size);
~ElementArrayBuffer();
void updateSubBuffer(GLintptr offset, const GLvoid* data, GLsizeiptr size);
GLvoid *getBuffer();
GLsizeiptr getSize();
};
/** GL Trace Context info associated with each EGLContext */
class GLTraceContext {
int mId; /* unique context id */
@ -43,6 +58,9 @@ class GLTraceContext {
BufferedOutputStream *mBufferedOutputStream; /* stream where trace info is sent */
/* list of element array buffers in use. */
DefaultKeyedVector<GLuint, ElementArrayBuffer*> mElementArrayBuffers;
void resizeFBMemory(unsigned minSize);
public:
gl_hooks_t *hooks;
@ -53,6 +71,13 @@ public:
void getCompressedFB(void **fb, unsigned *fbsize,
unsigned *fbwidth, unsigned *fbheight,
FBBinding fbToRead);
// Methods to work with element array buffers
void bindBuffer(GLuint bufferId, GLvoid *data, GLsizeiptr size);
void getBuffer(GLuint bufferId, GLvoid **data, GLsizeiptr *size);
void updateBufferSubData(GLuint bufferId, GLintptr offset, GLvoid *data, GLsizeiptr size);
void deleteBuffer(GLuint bufferId);
void traceGLMessage(GLMessage *msg);
};

View File

@ -193,7 +193,7 @@ void fixup_glTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
GLint border,
GLenum format,
GLenum type,
const GLvoid *data);
const GLvoid *data);
*/
int widthIndex = 3;
int heightIndex = 4;
@ -218,7 +218,7 @@ void fixup_glTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
}
void fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
/* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
const GLint* length) */
GLMessage_DataType arg_count = glmsg->args(1);
GLMessage_DataType arg_lenp = glmsg->args(3);
@ -256,33 +256,13 @@ void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg, void *s
}
void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
/* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */
GLMessage_DataType arg_count = glmsg->args(1);
int n_matrices = arg_count.intvalue(0);
fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
}
void fixup_glBufferData(int sizeIndex, int dataIndex, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
/* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
GLsizeiptr size = glmsg->args(sizeIndex).intvalue(0);
GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
GLvoid *datap = (GLvoid *) pointersToFixup[0];
if (datap == NULL) {
// glBufferData can be called with a NULL data pointer
return;
}
arg_datap->set_type(GLMessage::DataType::VOID);
arg_datap->set_isarray(true);
arg_datap->clear_intvalue();
arg_datap->add_rawbytes(datap, size);
}
void fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glGen*(GLsizei n, GLuint * buffers); */
GLMessage_DataType arg_n = glmsg->args(0);
@ -375,7 +355,7 @@ int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar
}
}
void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
void *pointersToFixup[]) {
/* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
@ -400,6 +380,303 @@ void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
arg_location->add_intvalue(location);
}
GLint glGetInteger(GLTraceContext *context, GLenum param) {
GLint x;
context->hooks->gl.glGetIntegerv(param, &x);
return x;
}
GLint glGetVertexAttrib(GLTraceContext *context, GLuint index, GLenum pname) {
GLint x;
context->hooks->gl.glGetVertexAttribiv(index, pname, &x);
return x;
}
bool isUsingArrayBuffers(GLTraceContext *context) {
return glGetInteger(context, GL_ARRAY_BUFFER_BINDING) != 0;
}
bool isUsingElementArrayBuffers(GLTraceContext *context) {
return glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0;
}
/** Copy @len bytes of data from @src into the @dataIndex'th argument of the message. */
void addGlBufferData(GLMessage *glmsg, int dataIndex, GLvoid *src, GLsizeiptr len) {
GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
arg_datap->set_type(GLMessage::DataType::VOID);
arg_datap->set_isarray(true);
arg_datap->clear_intvalue();
arg_datap->add_rawbytes(src, len);
}
void fixup_glBufferData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
GLsizeiptr size = glmsg->args(1).intvalue(0);
GLvoid *datap = (GLvoid *) pointersToFixup[0];
// Save element array buffers for future use to fixup glVertexAttribPointers
// when a glDrawElements() call is performed.
GLenum target = glmsg->args(0).intvalue(0);
if (target == GL_ELEMENT_ARRAY_BUFFER) {
GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
context->bindBuffer(bufferId, datap, size);
}
// add buffer data to the protobuf message
if (datap != NULL) {
addGlBufferData(glmsg, 2, datap, size);
}
}
void fixup_glBufferSubData(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
GLenum target = glmsg->args(0).intvalue(0);
GLintptr offset = glmsg->args(1).intvalue(0);
GLsizeiptr size = glmsg->args(2).intvalue(0);
GLvoid *datap = (GLvoid *) pointersToFixup[0];
if (target == GL_ELEMENT_ARRAY_BUFFER) {
GLint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
context->updateBufferSubData(bufferId, offset, datap, size);
}
// add buffer data to the protobuf message
addGlBufferData(glmsg, 3, datap, size);
}
/** Obtain the size of each vertex attribute. */
int vertexAttribSize(GLenum type, GLsizei numComponents) {
int sizePerComponent;
switch(type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
sizePerComponent = 1;
break;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
sizePerComponent = 2;
break;
case GL_FIXED:
case GL_FLOAT:
default:
sizePerComponent = 4;
break;
}
return sizePerComponent * numComponents;
}
/** Create and send a glVertexAttribPointerData trace message to the host. */
void trace_glVertexAttribPointerData(GLTraceContext *context,
GLuint indx, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const GLvoid* ptr,
GLuint minIndex, GLuint maxIndex, nsecs_t startTime) {
/* void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const GLvoid* ptr,
int minIndex, int maxIndex) */
GLMessage glmsg;
GLTraceContext *glContext = context;
glmsg.set_function(GLMessage::glVertexAttribPointerData);
// copy argument indx
GLMessage_DataType *arg_indx = glmsg.add_args();
arg_indx->set_isarray(false);
arg_indx->set_type(GLMessage::DataType::INT);
arg_indx->add_intvalue(indx);
// copy argument size
GLMessage_DataType *arg_size = glmsg.add_args();
arg_size->set_isarray(false);
arg_size->set_type(GLMessage::DataType::INT);
arg_size->add_intvalue(size);
// copy argument type
GLMessage_DataType *arg_type = glmsg.add_args();
arg_type->set_isarray(false);
arg_type->set_type(GLMessage::DataType::ENUM);
arg_type->add_intvalue((int)type);
// copy argument normalized
GLMessage_DataType *arg_normalized = glmsg.add_args();
arg_normalized->set_isarray(false);
arg_normalized->set_type(GLMessage::DataType::BOOL);
arg_normalized->add_boolvalue(normalized);
// copy argument stride
GLMessage_DataType *arg_stride = glmsg.add_args();
arg_stride->set_isarray(false);
arg_stride->set_type(GLMessage::DataType::INT);
arg_stride->add_intvalue(stride);
// copy argument ptr
GLMessage_DataType *arg_ptr = glmsg.add_args();
arg_ptr->set_isarray(true);
arg_ptr->set_type(GLMessage::DataType::BYTE);
int perVertexSize = vertexAttribSize(type, size);
GLchar *p = (GLchar*) ptr;
std::string data;
for (GLuint i = minIndex; i < maxIndex; i++) {
data.append(p, perVertexSize);
p += stride == 0 ? perVertexSize : stride;
}
arg_ptr->add_rawbytes(data);
// copy argument min index
GLMessage_DataType *arg_min = glmsg.add_args();
arg_min->set_isarray(false);
arg_min->set_type(GLMessage::DataType::INT);
arg_min->add_intvalue(minIndex);
// copy argument max index
GLMessage_DataType *arg_max = glmsg.add_args();
arg_max->set_isarray(false);
arg_max->set_type(GLMessage::DataType::INT);
arg_max->add_intvalue(maxIndex);
glmsg.set_context_id(context->getId());
glmsg.set_start_time(startTime);
glmsg.set_threadtime(0);
glmsg.set_duration(0);
context->traceGLMessage(&glmsg);
}
void findMinAndMaxIndices(GLvoid *indices, GLsizei count, GLenum type,
GLuint *minIndex, GLuint *maxIndex) {
GLuint index;
*minIndex = UINT_MAX;
*maxIndex = 0;
if (indices == NULL) {
return;
}
for (GLsizei i = 0; i < count; i++) {
if (type == GL_UNSIGNED_BYTE) {
index = *((GLubyte*) indices + i);
} else {
index = *((GLushort*) indices + i);
}
if (index < *minIndex) *minIndex = index;
if (index > *maxIndex) *maxIndex = index;
}
}
void trace_VertexAttribPointerData(GLTraceContext *context,
GLuint minIndex, GLuint maxIndex, nsecs_t time) {
GLuint maxAttribs = glGetInteger(context, GL_MAX_VERTEX_ATTRIBS);
for (GLuint index = 0; index < maxAttribs; index++) {
if (!glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_ENABLED)) {
// vertex array disabled
continue;
}
if (glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)) {
// vbo
continue;
}
GLint size = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_SIZE);
GLenum type = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_TYPE);
GLboolean norm = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
GLsizei stride = glGetVertexAttrib(context, index, GL_VERTEX_ATTRIB_ARRAY_STRIDE);
GLvoid* ptr;
context->hooks->gl.glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
trace_glVertexAttribPointerData(context,
index, size, type, norm, stride, ptr,
minIndex, maxIndex, time);
}
}
void trace_VertexAttribPointerDataForGlDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
/* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
GLsizei count = glmsg->args(2).intvalue(0);
// Vertex attrib pointer data patchup calls should appear as if
// they occurred right before the draw call.
nsecs_t time = glmsg->start_time() - 1;
trace_VertexAttribPointerData(context, 0, count, time);
}
void trace_VertexAttribPointerDataForGlDrawElements(GLTraceContext *context, GLMessage *glmsg,
GLvoid *indices) {
/* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
GLsizei count = glmsg->args(1).intvalue(0);
GLenum type = glmsg->args(2).intvalue(0);
GLuint index;
GLuint minIndex, maxIndex;
// The index buffer is either passed in as an argument to the glDrawElements() call,
// or it is stored in the current GL_ELEMENT_ARRAY_BUFFER.
GLvoid *indexBuffer;
if (isUsingElementArrayBuffers(context)) {
GLsizeiptr eaBufferSize;
GLuint bufferId = glGetInteger(context, GL_ELEMENT_ARRAY_BUFFER_BINDING);
context->getBuffer(bufferId, &indexBuffer, &eaBufferSize);
} else {
indexBuffer = indices;
}
// Rather than sending vertex attribute data that corresponds to the indices
// being drawn, we send the vertex attribute data for the entire range of
// indices being drawn, including the ones not drawn. The min & max indices
// provide the range of indices being drawn.
findMinAndMaxIndices(indexBuffer, count, type, &minIndex, &maxIndex);
// Vertex attrib pointer data patchup calls should appear as if
// they occurred right before the draw call.
nsecs_t time = glmsg->start_time() - 1;
trace_VertexAttribPointerData(context, minIndex, maxIndex + 1, time);
}
void fixup_glDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
// Trace all vertex attribute data stored in client space.
trace_VertexAttribPointerDataForGlDrawArrays(context, glmsg);
// Attach the FB if requested
if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
}
}
void fixup_glDrawElements(GLTraceContext *context, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
GLvoid *indices = pointersToFixup[0];
GLenum type = glmsg->args(2).intvalue(0);
GLsizei count = glmsg->args(1).intvalue(0);
GLuint index;
// Trace all vertex attribute data stored in client space.
trace_VertexAttribPointerDataForGlDrawElements(context, glmsg, indices);
// Fixup indices argument
if (!isUsingElementArrayBuffers(context)) {
GLMessage_DataType *arg_indices = glmsg->mutable_args(3);
arg_indices->set_isarray(true);
arg_indices->clear_intvalue();
arg_indices->set_type(GLMessage::DataType::INT);
for (GLsizei i = 0; i < count; i++) {
if (type == GL_UNSIGNED_BYTE) {
index = *((GLubyte*) indices + i);
} else {
index = *((GLushort*) indices + i);
}
arg_indices->add_intvalue(index);
}
}
// Attach the FB if requested
if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
}
}
void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
nsecs_t threadStart, nsecs_t threadEnd,
GLMessage *glmsg, void *pointersToFixup[]) {
@ -438,8 +715,8 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
/* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
break;
case GLMessage::glGetAttribLocation:
case GLMessage::glGetUniformLocation:
case GLMessage::glGetAttribLocation:
case GLMessage::glGetUniformLocation:
/* int glGetAttribLocation(GLuint program, const GLchar* name) */
/* int glGetUniformLocation(GLuint program, const GLchar* name) */
fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
@ -526,23 +803,19 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
break;
case GLMessage::glBufferData:
/* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
fixup_glBufferData(1, 2, glmsg, pointersToFixup);
fixup_glBufferData(context, glmsg, pointersToFixup);
break;
case GLMessage::glBufferSubData:
/* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
fixup_glBufferData(2, 3, glmsg, pointersToFixup);
fixup_glBufferSubData(context, glmsg, pointersToFixup);
break;
case GLMessage::glDrawArrays:
/* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
}
fixup_glDrawArrays(context, glmsg);
break;
case GLMessage::glDrawElements:
/* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
}
fixup_glDrawElements(context, glmsg, pointersToFixup);
break;
case GLMessage::glPushGroupMarkerEXT:
/* void PushGroupMarkerEXT(sizei length, const char *marker); */