diff options
author | Siva Velusamy <vsiva@google.com> | 2012-03-06 08:59:32 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-06 08:59:32 -0800 |
commit | aa521412126953f55a04b1fece9444779156e714 (patch) | |
tree | 2c525b08a03e6abac2371047258ed22aaf6c983e /opengl | |
parent | 6a1d3882829a5435d46a9ae0f016f8ea7f6dcb03 (diff) | |
parent | 1c5387e1cb12a2aa2b1aaf4c2f4f5c61be4828aa (diff) | |
download | frameworks_base-aa521412126953f55a04b1fece9444779156e714.zip frameworks_base-aa521412126953f55a04b1fece9444779156e714.tar.gz frameworks_base-aa521412126953f55a04b1fece9444779156e714.tar.bz2 |
Merge "gltrace: Send vertex attribute data after glDraw() call."
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/libs/GLES_trace/dev.make | 13 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/gltrace.proto | 2 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace.pb.cpp | 2 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace.pb.h | 6 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.cpp | 80 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.h | 25 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_fixup.cpp | 341 |
7 files changed, 418 insertions, 51 deletions
diff --git a/opengl/libs/GLES_trace/dev.make b/opengl/libs/GLES_trace/dev.make index 1d89999..a46260c 100644 --- a/opengl/libs/GLES_trace/dev.make +++ b/opengl/libs/GLES_trace/dev.make @@ -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 diff --git a/opengl/libs/GLES_trace/gltrace.proto b/opengl/libs/GLES_trace/gltrace.proto index 2893e6e..bbf3554 100644 --- a/opengl/libs/GLES_trace/gltrace.proto +++ b/opengl/libs/GLES_trace/gltrace.proto @@ -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 diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.cpp b/opengl/libs/GLES_trace/src/gltrace.pb.cpp index d5f8180..d587c49 100644 --- a/opengl/libs/GLES_trace/src/gltrace.pb.cpp +++ b/opengl/libs/GLES_trace/src/gltrace.pb.cpp @@ -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; diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.h b/opengl/libs/GLES_trace/src/gltrace.pb.h index a4fcbd3..0901be7 100644 --- a/opengl/libs/GLES_trace/src/gltrace.pb.h +++ b/opengl/libs/GLES_trace/src/gltrace.pb.h @@ -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); } diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp index 65b7662..45dbb43 100644 --- a/opengl/libs/GLES_trace/src/gltrace_context.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp @@ -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 diff --git a/opengl/libs/GLES_trace/src/gltrace_context.h b/opengl/libs/GLES_trace/src/gltrace_context.h index 129116a..323cfdc 100644 --- a/opengl/libs/GLES_trace/src/gltrace_context.h +++ b/opengl/libs/GLES_trace/src/gltrace_context.h @@ -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); }; diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp index c69ba5e..3597b26 100644 --- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp @@ -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); */ |