]> git.cworth.org Git - apitrace/commitdiff
Cleanup shadow buffers.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 3 Nov 2012 10:13:17 +0000 (10:13 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 3 Nov 2012 10:21:56 +0000 (10:21 +0000)
- More defensive code.
- Use _glFoo instead of glFoo to avoid nested calls in the trace
- Handle glMapBufferOES/UnmapBufferOES too.

wrappers/gltrace.hpp
wrappers/gltrace.py

index 155f82760cd641139e5ddd4ef28c8923fe67fce3..55c1dcc2691d81be1ae7213e973a7cf7b6188c79 100644 (file)
 #define _GLTRACE_HPP_
 
 
-#include "glimports.hpp"
 #include <string.h>
 #include <stdlib.h>
 #include <map>
 
+#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 <GLuint, class Buffer *> buffers;
+
+    // TODO: This will fail for buffers shared by multiple contexts.
+    std::map <GLuint, Buffer> buffers;
 
     Context(void) :
         profile(PROFILE_COMPAT),
index b97929edafc9d25fcaa6357067f2468e4fbe22fe..96da4e85c576e25af119696f9c849ae2ecbb3724 100644 (file)
@@ -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',