]> git.cworth.org Git - apitrace/blobdiff - retrace/glretrace_glx.cpp
stash: Trace and replay of gnome-shell works
[apitrace] / retrace / glretrace_glx.cpp
index bc63063d5a0c6394e885f6491300c86e3e7d2b80..f740a8c62a6937e2bd9e836f45424d199393c1ce 100644 (file)
 #include "retrace.hpp"
 #include "glretrace.hpp"
 
+#include <vector>
+
+#ifndef GLX_PBUFFER_HEIGHT
+#define GLX_PBUFFER_HEIGHT 0x8040
+#endif
+
+#ifndef GLX_PBUFFER_WIDTH
+#define GLX_PBUFFER_WIDTH 0x8041
+#endif
+
 
 using namespace glretrace;
 
+typedef struct {
+    int width;
+    int height;
+    int depth;
+} PixmapDesc;
 
 typedef std::map<unsigned long, glws::Drawable *> DrawableMap;
 typedef std::map<unsigned long long, Context *> ContextMap;
+typedef std::map<unsigned long, PixmapDesc *> PixmapDescMap;
+typedef std::map<GLXFBConfig, GLXFBConfig> ConfigMap;
+typedef std::map<GLXFBConfig, std::vector<int> > ConfigAttribListMap;
 static DrawableMap drawable_map;
 static ContextMap context_map;
-
+static PixmapDescMap pixmap_desc_map;
+static ConfigMap config_map;
+static ConfigAttribListMap config_attrib_list_map;
 
 static glws::Drawable *
 getDrawable(unsigned long drawable_id) {
@@ -103,9 +123,13 @@ static void retrace_glXDestroyContext(trace::Call &call) {
 }
 
 static void retrace_glXSwapBuffers(trace::Call &call) {
+    glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
+
     frame_complete(call);
     if (retrace::doubleBuffer) {
-        currentDrawable->swapBuffers();
+        if (drawable) {
+            drawable->swapBuffers();
+        }
     } else {
         glFlush();
     }
@@ -119,6 +143,28 @@ static void retrace_glXCreateNewContext(trace::Call &call) {
     context_map[orig_context] = context;
 }
 
+static void retrace_glXCreatePbuffer(trace::Call &call) {
+    const trace::Value *attrib_list = dynamic_cast<const trace::Array *>(&call.arg(2));
+    int width = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_WIDTH, 0);
+    int height = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_HEIGHT, 0);
+
+    unsigned long long orig_drawable = call.ret->toUInt();
+
+    glws::Drawable *drawable = glretrace::createPbuffer(width, height);
+    
+    drawable_map[orig_drawable] = drawable;
+}
+
+static void retrace_glXDestroyPbuffer(trace::Call &call) {
+    glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
+
+    if (!drawable) {
+        return;
+    }
+
+    delete drawable;
+}
+
 static void retrace_glXMakeContextCurrent(trace::Call &call) {
     glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
     Context *new_context = getContext(call.arg(3).toUIntPtr());
@@ -126,19 +172,165 @@ static void retrace_glXMakeContextCurrent(trace::Call &call) {
     glretrace::makeCurrent(call, new_drawable, new_context);
 }
 
+static void retrace_glXCreateWindow(trace::Call &call) {
+    glws::Drawable *window = getDrawable(call.arg(2).toUInt());
+
+    glretrace::createWindow(window);
+}
+
+static void retrace_glXDestroyWindow(trace::Call &call) {
+    glws::Drawable *window = getDrawable(call.arg(1).toUInt());
+
+    glretrace::destroyWindow(window);
+}
+
+static void retrace_XCreatePixmap(trace::Call &call) {
+    unsigned pixmap_id = call.ret->toUInt();
+
+    PixmapDesc *desc = new(PixmapDesc);
+
+    desc->width = call.arg(2).toUInt();
+    desc->height = call.arg(3).toUInt();
+    desc->depth = call.arg(4).toUInt();
+
+    pixmap_desc_map[pixmap_id] = desc;
+}
+
+static void retrace_XFreePixmap(trace::Call &call) {
+    unsigned pixmap_id = call.arg(1).toUInt();
+    PixmapDescMap::iterator it;
+
+    it = pixmap_desc_map.find(pixmap_id);
+    delete it->second;
+    pixmap_desc_map.erase(it);
+}
+
+static void retrace_glXCreatePixmap(trace::Call &call) {
+    retrace::ScopedAllocator _allocator;
+    GLXFBConfig fbconfig, orig_fbconfig = (GLXFBConfig) call.arg(1).toPointer();
+    unsigned orig_pixmap = call.arg(2).toUInt();
+    unsigned orig_gl_pixmap = call.ret->toUInt();
+    PixmapDesc *desc = pixmap_desc_map[orig_pixmap];
+    glws::Drawable *pixmap, *gl_pixmap;
+
+    int *attrib_list;
+    attrib_list = static_cast<int *>(_allocator.alloc(&call.arg(3), sizeof *attrib_list));
+    if (attrib_list) {
+        const trace::Array *arg_list = dynamic_cast<const trace::Array *>(&call.arg(3));
+        for (size_t i = 0; i < arg_list->values.size(); i++) {
+            attrib_list[i] = (*arg_list->values[i]).toSInt();
+        }
+    }
+
+    fbconfig = config_map[orig_fbconfig];
+
+    if (! fbconfig) {
+        std::vector<int> *attrib_list = &config_attrib_list_map[orig_fbconfig];
+        attrib_list->push_back(0);
+        fbconfig = glretrace::chooseConfig(attrib_list->data());
+        if (fbconfig) {
+            config_map[orig_fbconfig] = fbconfig;
+        } else {
+            fprintf(stderr, "Error: Failed to find suitable fbconfig\n");
+        }
+    }
+
+    pixmap = glretrace::createPixmap(desc->width, desc->height, desc->depth);
+
+    gl_pixmap = glretrace::createGLPixmap(fbconfig, pixmap, desc->width, desc->height, attrib_list);
+
+    drawable_map[orig_pixmap] = pixmap;
+    drawable_map[orig_gl_pixmap] = gl_pixmap;
+}
+
+static void retrace_glXBindTexImageEXT(trace::Call &call) {
+    glws::Drawable *pixmap = getDrawable(call.arg(1).toUInt());
+
+    glretrace::bindTexImage(pixmap, call.arg(2).toSInt());
+}
+
+static void retrace_glXReleaseTexImageEXT(trace::Call &call) {
+    glws::Drawable *pixmap = getDrawable(call.arg(1).toUInt());
+
+    glretrace::releaseTexImage(pixmap, call.arg(2).toSInt());
+}
+
+static void retrace_glXCopySubBufferMESA(trace::Call &call) {
+    glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
+    int x, y, width, height;
+
+    x = call.arg(2).toSInt();
+    y = call.arg(3).toSInt();
+    width = call.arg(4).toSInt();
+    height = call.arg(5).toSInt();
+
+    glretrace::copySubBuffer(drawable, x, y, width, height);
+}
+
+static void retrace_PutImageData(trace::Call &call) {
+    glws::Drawable *drawable = getDrawable(call.arg(0).toUInt());
+    int width, height, depth, bits_per_pixel, bytes_per_line, byte_order;
+    char *data;
+
+    data = static_cast<char *>((call.arg(1)).toPointer());
+    width = call.arg(2).toSInt();
+    height = call.arg(3).toSInt();
+    depth = call.arg(4).toSInt();
+    bits_per_pixel = call.arg(5).toSInt();
+    bytes_per_line = call.arg(6).toSInt();
+    byte_order = call.arg(7).toSInt();
+
+    glretrace::putImageData(drawable, data, width, height, depth,
+                            bits_per_pixel, bytes_per_line, byte_order);
+}
+
+static void retrace_glXChooseFBConfig(trace::Call &call) {
+    retrace::ScopedAllocator _allocator;
+    int orig_nelements;
+    const trace::Array *orig_configs;
+    GLXFBConfig config;
+
+    int *attrib_list;
+    attrib_list = static_cast<int *>(_allocator.alloc(&call.arg(2), sizeof *attrib_list));
+    if (attrib_list) {
+        const trace::Array *arg_list = dynamic_cast<const trace::Array *>(&call.arg(2));
+        for (size_t i = 0; i < arg_list->values.size(); i++) {
+            attrib_list[i] = arg_list->values[i]->toSInt();
+        }
+    }   
+
+    orig_nelements = dynamic_cast<const trace::Array *>(&call.arg(3))->values[0]->toSInt();
+    orig_configs = dynamic_cast<const trace::Array *>(call.ret);
+
+    config = glretrace::chooseConfig(attrib_list);
+    for (size_t i = 0; i < orig_nelements; i++) {
+        config_map[static_cast<GLXFBConfig>(orig_configs->values[i]->toPointer())] = config;
+    }
+}
+
+static void retrace_glXGetFBConfigAttrib(trace::Call &call) {
+    GLXFBConfig config = static_cast<GLXFBConfig>(call.arg(1).toPointer());
+    int attribute = call.arg(2).toUInt();
+    int value = dynamic_cast<const trace::Array *>(&call.arg(3))->values[0]->toSInt();
+
+    std::vector<int> *attrib_list = &config_attrib_list_map[config];
+    attrib_list->push_back(attribute);
+    attrib_list->push_back(value);
+}
+
 const retrace::Entry glretrace::glx_callbacks[] = {
     //{"glXBindChannelToWindowSGIX", &retrace_glXBindChannelToWindowSGIX},
     //{"glXBindSwapBarrierNV", &retrace_glXBindSwapBarrierNV},
     //{"glXBindSwapBarrierSGIX", &retrace_glXBindSwapBarrierSGIX},
-    //{"glXBindTexImageEXT", &retrace_glXBindTexImageEXT},
+    {"glXBindTexImageEXT", &retrace_glXBindTexImageEXT},
     //{"glXChannelRectSGIX", &retrace_glXChannelRectSGIX},
     //{"glXChannelRectSyncSGIX", &retrace_glXChannelRectSyncSGIX},
-    {"glXChooseFBConfig", &retrace::ignore},
+    {"glXChooseFBConfig", &retrace_glXChooseFBConfig},
     {"glXChooseFBConfigSGIX", &retrace::ignore},
     {"glXChooseVisual", &retrace::ignore},
     //{"glXCopyContext", &retrace_glXCopyContext},
     //{"glXCopyImageSubDataNV", &retrace_glXCopyImageSubDataNV},
-    //{"glXCopySubBufferMESA", &retrace_glXCopySubBufferMESA},
+    {"glXCopySubBufferMESA", &retrace_glXCopySubBufferMESA},
     {"glXCreateContextAttribsARB", &retrace_glXCreateContextAttribsARB},
     {"glXCreateContext", &retrace_glXCreateContext},
     //{"glXCreateContextWithConfigSGIX", &retrace_glXCreateContextWithConfigSGIX},
@@ -146,16 +338,19 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     //{"glXCreateGLXPixmap", &retrace_glXCreateGLXPixmap},
     //{"glXCreateGLXPixmapWithConfigSGIX", &retrace_glXCreateGLXPixmapWithConfigSGIX},
     {"glXCreateNewContext", &retrace_glXCreateNewContext},
-    //{"glXCreatePbuffer", &retrace_glXCreatePbuffer},
-    //{"glXCreatePixmap", &retrace_glXCreatePixmap},
-    //{"glXCreateWindow", &retrace_glXCreateWindow},
+    {"glXCreatePbuffer", &retrace_glXCreatePbuffer},
+    {"glXCreatePixmap", &retrace_glXCreatePixmap},
+    {"XCreatePixmap", &retrace_XCreatePixmap},
+    {"XFreePixmap", &retrace_XFreePixmap},
+    {"PutImageData", &retrace_PutImageData},
+    {"glXCreateWindow", &retrace_glXCreateWindow},
     //{"glXCushionSGI", &retrace_glXCushionSGI},
     {"glXDestroyContext", &retrace_glXDestroyContext},
     //{"glXDestroyGLXPbufferSGIX", &retrace_glXDestroyGLXPbufferSGIX},
     //{"glXDestroyGLXPixmap", &retrace_glXDestroyGLXPixmap},
-    //{"glXDestroyPbuffer", &retrace_glXDestroyPbuffer},
+    {"glXDestroyPbuffer", &retrace_glXDestroyPbuffer},
     //{"glXDestroyPixmap", &retrace_glXDestroyPixmap},
-    //{"glXDestroyWindow", &retrace_glXDestroyWindow},
+    {"glXDestroyWindow", &retrace_glXDestroyWindow},
     //{"glXFreeContextEXT", &retrace_glXFreeContextEXT},
     {"glXGetAGPOffsetMESA", &retrace::ignore},
     {"glXGetClientString", &retrace::ignore},
@@ -167,7 +362,7 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     {"glXGetCurrentDrawable", &retrace::ignore},
     {"glXGetCurrentReadDrawable", &retrace::ignore},
     {"glXGetCurrentReadDrawableSGI", &retrace::ignore},
-    {"glXGetFBConfigAttrib", &retrace::ignore},
+    {"glXGetFBConfigAttrib", &retrace_glXGetFBConfigAttrib},
     {"glXGetFBConfigAttribSGIX", &retrace::ignore},
     {"glXGetFBConfigFromVisualSGIX", &retrace::ignore},
     {"glXGetFBConfigs", &retrace::ignore},
@@ -176,6 +371,7 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     {"glXGetProcAddress", &retrace::ignore},
     {"glXGetSelectedEvent", &retrace::ignore},
     {"glXGetSelectedEventSGIX", &retrace::ignore},
+    {"glXGetSwapIntervalMESA", &retrace::ignore},
     {"glXGetSyncValuesOML", &retrace::ignore},
     {"glXGetVideoSyncSGI", &retrace::ignore},
     {"glXGetVisualFromFBConfig", &retrace::ignore},
@@ -202,9 +398,9 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     {"glXQuerySwapGroupNV", &retrace::ignore},
     {"glXQueryVersion", &retrace::ignore},
     //{"glXReleaseBuffersMESA", &retrace_glXReleaseBuffersMESA},
-    //{"glXReleaseTexImageEXT", &retrace_glXReleaseTexImageEXT},
+    {"glXReleaseTexImageEXT", &retrace_glXReleaseTexImageEXT},
     //{"glXResetFrameCountNV", &retrace_glXResetFrameCountNV},
-    //{"glXSelectEvent", &retrace_glXSelectEvent},
+    {"glXSelectEvent", &retrace::ignore},
     //{"glXSelectEventSGIX", &retrace_glXSelectEventSGIX},
     //{"glXSet3DfxModeMESA", &retrace_glXSet3DfxModeMESA},
     //{"glXSwapBuffersMscOML", &retrace_glXSwapBuffersMscOML},