summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
authorSiva Velusamy <vsiva@google.com>2012-03-06 08:59:32 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-03-06 08:59:32 -0800
commitaa521412126953f55a04b1fece9444779156e714 (patch)
tree2c525b08a03e6abac2371047258ed22aaf6c983e /opengl
parent6a1d3882829a5435d46a9ae0f016f8ea7f6dcb03 (diff)
parent1c5387e1cb12a2aa2b1aaf4c2f4f5c61be4828aa (diff)
downloadframeworks_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.make13
-rw-r--r--opengl/libs/GLES_trace/gltrace.proto2
-rw-r--r--opengl/libs/GLES_trace/src/gltrace.pb.cpp2
-rw-r--r--opengl/libs/GLES_trace/src/gltrace.pb.h6
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_context.cpp80
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_context.h25
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_fixup.cpp341
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); */