From d493737765bed0fcbba908024d2314778c26b5c9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 24 Apr 2012 14:06:48 +0300 Subject: [PATCH] gles: track gl buffer contents in a shadow buffer This is needed since GLES/GLES2 don't support either glGetBufferSubData or glMapBufferOES. At the moment apitrace is only interested in GL_ELEMENT_ARRAY_BUFFER contents so don't track buffers of other types. Signed-off-by: Imre Deak --- helpers/glsize.hpp | 7 +++- wrappers/gltrace.hpp | 29 ++++++++++++++++ wrappers/gltrace.py | 81 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/helpers/glsize.hpp b/helpers/glsize.hpp index 24c0ac9..9d39a3b 100644 --- a/helpers/glsize.hpp +++ b/helpers/glsize.hpp @@ -340,6 +340,11 @@ _glDrawArrays_count(GLint first, GLsizei count) #define _glDrawArraysEXT_count _glDrawArrays_count +/* Forward declaration for definition in gltrace.py */ +void +_shadow_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, + GLvoid *data); + static inline GLuint _glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) { @@ -360,7 +365,7 @@ _glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indice return 0; } memset(temp, 0, size); - _glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp); + _shadow_glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp); indices = temp; } else { if (!indices) { diff --git a/wrappers/gltrace.hpp b/wrappers/gltrace.hpp index db824bb..155f827 100644 --- a/wrappers/gltrace.hpp +++ b/wrappers/gltrace.hpp @@ -28,6 +28,9 @@ #include "glimports.hpp" +#include +#include +#include namespace gltrace { @@ -39,6 +42,25 @@ enum Profile { PROFILE_ES2, }; +class Buffer { +public: + ~Buffer() + { + free(data); + } + + void resetData(const void *new_data, size_t new_size) + { + data = realloc(data, new_size); + size = new_size; + if (size) + memcpy(data, new_data, size); + } + + size_t size; + void *data; +}; + class Context { public: enum Profile profile; @@ -46,6 +68,7 @@ public: bool user_arrays_arb; bool user_arrays_nv; unsigned retain_count; + std::map buffers; Context(void) : profile(PROFILE_COMPAT), @@ -54,6 +77,12 @@ public: user_arrays_nv(false), retain_count(0) { } + + inline bool + needsShadowBuffers(void) + { + return profile == PROFILE_ES1 || profile == PROFILE_ES2; + } }; void diff --git a/wrappers/gltrace.py b/wrappers/gltrace.py index 411a19b..b97929e 100644 --- a/wrappers/gltrace.py +++ b/wrappers/gltrace.py @@ -141,6 +141,8 @@ class GlTracer(Tracer): print '}' print + self.defineShadowBufferHelper() + # Whether we need user arrays print 'static inline bool _need_user_arrays(void)' print '{' @@ -349,6 +351,81 @@ class GlTracer(Tracer): else: Tracer.traceApi(self, api) + def defineShadowBufferHelper(self): + print 'void _shadow_glGetBufferSubData(GLenum target, GLintptr offset,' + print ' GLsizeiptr size, GLvoid *data)' + print '{' + print ' struct gltrace::Context *ctx = gltrace::getContext();' + print ' if (!ctx->needsShadowBuffers() || target != GL_ELEMENT_ARRAY_BUFFER) {' + 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 '}' + + 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 + + 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 + + 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 ' }' + 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", @@ -632,8 +709,12 @@ class GlTracer(Tracer): print ' }' print ' }' + self.shadowBufferProlog(function) + Tracer.traceFunctionImplBody(self, function) + self.shadowBufferEpilog(function) + marker_functions = [ # GL_GREMEDY_string_marker 'glStringMarkerGREMEDY', -- 2.43.0