From 219c9f26228f33212cd6c433ecde107a0fac4c9e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 3 Nov 2012 10:13:17 +0000 Subject: [PATCH] Cleanup shadow buffers. - More defensive code. - Use _glFoo instead of glFoo to avoid nested calls in the trace - Handle glMapBufferOES/UnmapBufferOES too. --- wrappers/gltrace.hpp | 50 +++++++++++++++++++++------ wrappers/gltrace.py | 80 ++++++++++++++------------------------------ 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/wrappers/gltrace.hpp b/wrappers/gltrace.hpp index 155f827..55c1dcc 100644 --- a/wrappers/gltrace.hpp +++ b/wrappers/gltrace.hpp @@ -27,11 +27,12 @@ #define _GLTRACE_HPP_ -#include "glimports.hpp" #include #include #include +#include "glimports.hpp" + namespace gltrace { @@ -42,23 +43,50 @@ enum Profile { PROFILE_ES2, }; + +/** + * OpenGL ES buffers cannot be read. This class is used to track index buffer + * contents. + */ class Buffer { public: - ~Buffer() - { + GLsizeiptr size; + GLvoid *data; + + Buffer() : + size(0), + data(0) + {} + + ~Buffer() { free(data); } - void resetData(const void *new_data, size_t new_size) - { - data = realloc(data, new_size); + void + bufferData(GLsizeiptr new_size, const void *new_data) { + if (new_size < 0) { + new_size = 0; + } size = new_size; - if (size) + data = realloc(data, new_size); + if (new_size && new_data) { memcpy(data, new_data, size); + } } - size_t size; - void *data; + void + bufferSubData(GLsizeiptr offset, GLsizeiptr length, const void *new_data) { + if (offset >= 0 && offset < size && length > 0 && offset + length <= size && new_data) { + memcpy((uint8_t *)data + offset, new_data, length); + } + } + + void + getSubData(GLsizeiptr offset, GLsizeiptr length, void *out_data) { + if (offset >= 0 && offset < size && length > 0 && offset + length <= size && out_data) { + memcpy(out_data, (uint8_t *)data + offset, length); + } + } }; class Context { @@ -68,7 +96,9 @@ public: bool user_arrays_arb; bool user_arrays_nv; unsigned retain_count; - std::map buffers; + + // TODO: This will fail for buffers shared by multiple contexts. + std::map buffers; Context(void) : profile(PROFILE_COMPAT), diff --git a/wrappers/gltrace.py b/wrappers/gltrace.py index b97929e..96da4e8 100644 --- a/wrappers/gltrace.py +++ b/wrappers/gltrace.py @@ -357,75 +357,46 @@ class GlTracer(Tracer): print '{' print ' struct gltrace::Context *ctx = gltrace::getContext();' print ' if (!ctx->needsShadowBuffers() || target != GL_ELEMENT_ARRAY_BUFFER) {' - print ' glGetBufferSubData(target, offset, size, data);' + print ' _glGetBufferSubData(target, offset, size, data);' print ' return;' print ' }' print - print ' struct gltrace::Buffer *buf;' - print ' GLint buf_id;' - print - print ' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buf_id);' - print ' buf = ctx->buffers[buf_id];' - print ' assert(size + offset <= buf->size);' - print ' memcpy(data, (uint8_t *)buf->data + offset, size);' + print ' GLint buffer_binding = 0;' + print ' _glGetIntegerv(target, &buffer_binding);' + print ' if (buffer_binding > 0) {' + print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];' + print ' buf.getSubData(offset, size, data);' + print ' }' print '}' + def shadowBufferMethod(self, method): + # Emit code to fetch the shadow buffer, and invoke a method + print ' gltrace::Context *ctx = gltrace::getContext();' + print ' if (ctx->needsShadowBuffers() && target == GL_ELEMENT_ARRAY_BUFFER) {' + print ' GLint buffer_binding = 0;' + print ' _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buffer_binding);' + print ' if (buffer_binding > 0) {' + print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];' + print ' buf.' + method + ';' + print ' }' + print ' }' + print + def shadowBufferProlog(self, function): if function.name == 'glBufferData': - print ' gltrace::Context *ctx = gltrace::getContext();' - print ' if (ctx->needsShadowBuffers() && target == GL_ELEMENT_ARRAY_BUFFER) {' - print ' struct gltrace::Buffer *buf;' - print ' GLint buf_id;' - print - print ' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buf_id);' - print ' buf = ctx->buffers[buf_id];' - print ' buf->resetData(data, size);' - print ' }' - print + self.shadowBufferMethod('bufferData(size, data)') if function.name == 'glBufferSubData': - print ' gltrace::Context *ctx = gltrace::getContext();' - print ' if (ctx->needsShadowBuffers() && target == GL_ELEMENT_ARRAY_BUFFER) {' - print ' struct gltrace::Buffer *buf;' - print ' GLint buf_id;' - print - print ' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buf_id);' - print ' buf = ctx->buffers[buf_id];' - print ' memcpy((uint8_t *)buf->data + offset, data, size);' - print ' }' - print + self.shadowBufferMethod('bufferSubData(offset, size, data)') if function.name == 'glDeleteBuffers': print ' gltrace::Context *ctx = gltrace::getContext();' print ' if (ctx->needsShadowBuffers()) {' - print ' int i;' - print - print ' for (i = 0; i < n; i++) {' - print ' unsigned long buf_id;' - print ' struct gltrace::Buffer *buf;' - print - print ' buf_id = buffer[i];' - print ' buf = ctx->buffers[buf_id];' - print ' if (buf) {' - print ' ctx->buffers.erase(buf_id);' - print ' delete buf;' - print ' }' + print ' for (GLsizei i = 0; i < n; i++) {' + print ' ctx->buffers.erase(buffer[i]);' print ' }' print ' }' - def shadowBufferEpilog(self, function): - if function.name == 'glGenBuffers': - print ' gltrace::Context *ctx = gltrace::getContext();' - print ' if (ctx->needsShadowBuffers()) {' - print ' int i;' - print ' for (i = 0; i < n; i++) {' - print ' GLuint buf_id = buffer[i];' - print ' ctx->buffers[buf_id] = new gltrace::Buffer;' - print ' }' - print ' }' - print - - array_pointer_function_names = set(( "glVertexPointer", "glNormalPointer", @@ -634,6 +605,7 @@ class GlTracer(Tracer): print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);' print ' if (map && size > 0) {' self.emit_memcpy('map', 'map', 'size') + self.shadowBufferMethod('bufferSubData(0, size, map)') print ' }' print ' }' if function.name == 'glUnmapNamedBufferEXT': @@ -713,8 +685,6 @@ class GlTracer(Tracer): Tracer.traceFunctionImplBody(self, function) - self.shadowBufferEpilog(function) - marker_functions = [ # GL_GREMEDY_string_marker 'glStringMarkerGREMEDY', -- 2.45.2