Merge "gltrace: Send vertex attribute data after glDraw() call."
This commit is contained in:
commit
2178dcf149
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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); */
|
||||
|
|
Loading…
Reference in New Issue