]> git.cworth.org Git - apitrace/commitdiff
stash: Trace and replay of glx-tfp works
authorCarl Worth <cworth@cworth.org>
Thu, 16 May 2013 22:19:36 +0000 (15:19 -0700)
committerCarl Worth <cworth@cworth.org>
Thu, 16 May 2013 22:21:38 +0000 (15:21 -0700)
Trace and replay of gnome-shell still doesn't work due to it manually
grubbing through the results of calling glXGetFBConfigs.

16 files changed:
CMakeLists.txt
common/os_dl.hpp
dispatch/CMakeLists.txt
dispatch/glproc.py
dispatch/glproc_gl.cpp
dispatch/xproc.hpp [new file with mode: 0644]
retrace/glretrace.hpp
retrace/glretrace_glx.cpp
retrace/glretrace_ws.cpp
retrace/glws.hpp
retrace/glws_egl_xlib.cpp
retrace/glws_glx.cpp
specs/xapi.py [new file with mode: 0644]
wrappers/CMakeLists.txt
wrappers/xtrace.cpp [new file with mode: 0644]
wrappers/xtrace.py [new file with mode: 0644]

index ac046f51266e469184860c78fe4fa7975d758de5..1f43f96a68e2e2bba5508d5072af69fb660d7e5a 100644 (file)
@@ -322,6 +322,7 @@ set_target_properties (common PROPERTIES
     COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
 )
 
+target_link_libraries(common cairo)
 if (ANDROID)
     target_link_libraries (common
         log
index da51d414a600540ef0534884b28d4762856fc8a7..cecfa3550d96d6560c68cf9dfa5db5be486b83ff 100644 (file)
@@ -58,6 +58,7 @@ namespace os {
 
     inline Library
     openLibrary(const char *filename) {
+        std::cout << "In apitrace::openLibrary\n";
 #if defined(_WIN32)
         return LoadLibraryA(filename);
 #else
@@ -67,6 +68,7 @@ namespace os {
 
     inline void *
     getLibrarySymbol(Library library, const char *symbol) {
+        std::cout << "In apitrace::getLibrarySymbol\n";
 #if defined(_WIN32)
         return (void *)GetProcAddress(library, symbol);
 #else
index 0dad67fe3c73b4849fddbc7a3967b70a3f5dbff7..9f43f4bb10c43913af9fff221bf600f63cc169b2 100644 (file)
@@ -20,6 +20,7 @@ add_custom_command (
         ${CMAKE_SOURCE_DIR}/specs/glapi.py
         ${CMAKE_SOURCE_DIR}/specs/gltypes.py
         ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+        ${CMAKE_SOURCE_DIR}/specs/xapi.py
 )
 
 
index 488f91279da853bd3b4ce3ad45efbcf5733180bc..6c6e204eb241c7ada8e71d276d706ca1cd81781e 100644 (file)
@@ -37,6 +37,7 @@ from specs.wglapi import wglapi
 from specs.cglapi import cglapi
 from specs.eglapi import eglapi
 from specs.glesapi import glesapi
+from specs.xapi import xapi
 
 
 # See http://www.opengl.org/registry/ABI/
@@ -449,6 +450,9 @@ public_symbols = set([
     "wglUseFontOutlinesA",
     "wglUseFontOutlinesW",
 
+    # X
+    "XCreatePixmap",
+
 ])
 
 # EGL 1.4
@@ -533,6 +537,8 @@ if __name__ == '__main__':
     print
     dispatcher.dispatchModule(glxapi)
     print
+    dispatcher.dispatchModule(xapi)
+    print
     print '#endif'
     print
     dispatcher.dispatchModule(glapi)
index 8e1216f1dc999c75f2cd16a751f4403b924868f6..750c65c153388ca9fbb71cdb9649796bf6f81d73 100644 (file)
@@ -91,6 +91,8 @@ void * _libgl_sym(const char *symbol)
 {
     void *result;
 
+    printf ("In apitrace::_libgl_sym\n");
+
     if (!_libGlHandle) {
         /* 
          * Unfortunately we can't just dlopen the true dynamic library because
@@ -103,7 +105,7 @@ void * _libgl_sym(const char *symbol)
 
         if (mktemp(temp_filename) != NULL) {
             if (symlink(libgl_filename, temp_filename) == 0) {
-                _libGlHandle = dlopen(temp_filename, RTLD_LOCAL | RTLD_NOW | RTLD_FIRST);
+                _libGlHandle = dlopen(temp_filename, RTLD_LOCAL | RTLD_NOW);
                 remove(temp_filename);
             }
         }
diff --git a/dispatch/xproc.hpp b/dispatch/xproc.hpp
new file mode 100644 (file)
index 0000000..576673d
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _XPROC_HPP_
+#define _XPROC_HPP_
+
+#include <X/X11.h>
+
+#include "os.hpp"
+
+#if defined(HAVE_X11)
+
+typedef Pixmap (* PFN_XCREATEPIXMAP)(Display * dpy, Drawable d, unsigned int width, unsigned int height, unsigned int depth);
+static PFN_XCREATEPIXMAP _XCreatePixmap_ptr = NULL;
+
+static inline Pixmap _XCreatePixmap(Display * dpy, Drawable d, unsigned int width, unsigned int height, unsigned int depth) {
+    const char *_name = "XCreatePixmap";
+    if (!_XCreatePixmap_ptr) {
+        _XCreatePixmap_ptr = (PFN_XCREATEPIXMAP)_getPublicProcAddress(_name);
+        if (!_XCreatePixmap_ptr) {
+            os::log("error: unavailable function %s\n", _name);
+            os::abort();
+        }
+    }
+    return _XCreatePixmap_ptr(dpy, d, width, height, depth);
+}
+
+typedef int (* PFN_XFREEPIXMAP)(Display * dpy, Drawable pixmap);
+static PFN_XFREEPIXMAP _XFreePixmap_ptr = NULL;
+
+static inline int _XFreePixmap(Display * dpy, Drawable pixmap) {
+    const char *_name = "XFreePixmap";
+    if (!_XFreePixmap_ptr) {
+        _XFreePixmap_ptr = (PFN_XFREEPIXMAP)_getPrivateProcAddress(_name);
+        if (!_XFreePixmap_ptr) {
+            os::log("error: unavailable function %s\n", _name);
+            os::abort();
+        }
+    }
+    return _XFreePixmap_ptr(dpy, pixmap);
+}
+
+#ifdef RETRACE
+#define XCreatePixmap _XCreatePixmap
+#define XFreePixmap _XFreePixmap
+#endif /* RETRACE */
+
+
+#endif
index 7441b56938e22481e0110b181b74b7de81a55c98..1f5f451a750a03d975943e006786442a2f724b26 100644 (file)
@@ -88,6 +88,35 @@ createContext(Context *shareContext = 0);
 bool
 makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context);
 
+void
+createWindow(glws::Drawable *drawable);
+
+void
+destroyWindow(glws::Drawable *drawable);
+
+glws::Drawable *
+createPixmap(unsigned width, unsigned height, unsigned depth);
+
+glws::Drawable *
+createGLPixmap(GLXFBConfig fbconfig, glws::Drawable *pixmap,
+               unsigned width, unsigned height, int *attrib_list);
+
+void
+bindTexImage(glws::Drawable *drawable, int buffer);
+
+void
+releaseTexImage(glws::Drawable *drawable, int buffer);
+
+void
+copySubBuffer(glws::Drawable *drawable, int x, int y, int width, int height);
+
+void
+putImageData(glws::Drawable *drawable, char *data,
+             int width, int height, int depth,
+             int bits_per_pixel, int bytes_per_line, int byte_order);
+
+GLXFBConfig
+chooseConfig(int *attrib_list);
 
 void
 checkGlError(trace::Call &call);
index 4ab3d676c189f4984fbc0bb1b6c329c4037e5d86..eb64b6bfb86d37d176901b50ef7031d95f033a87 100644 (file)
 
 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;
 static DrawableMap drawable_map;
 static ContextMap context_map;
-
+static PixmapDescMap pixmap_desc_map;
+static ConfigMap config_map;
 
 static glws::Drawable *
 getDrawable(unsigned long drawable_id) {
@@ -161,19 +169,146 @@ 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();
+        }
+    }
+
+    printf("Looking for %p in FB-config map\n", orig_fbconfig);
+    fbconfig = config_map[orig_fbconfig];
+
+    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++) {
+        printf("Mapping FB config %p to %p\n", orig_configs->values[i]->toPointer(), config);
+        config_map[static_cast<GLXFBConfig>(orig_configs->values[i]->toPointer())] = config;
+    }
+}
+
 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},
@@ -182,15 +317,18 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     //{"glXCreateGLXPixmapWithConfigSGIX", &retrace_glXCreateGLXPixmapWithConfigSGIX},
     {"glXCreateNewContext", &retrace_glXCreateNewContext},
     {"glXCreatePbuffer", &retrace_glXCreatePbuffer},
-    //{"glXCreatePixmap", &retrace_glXCreatePixmap},
-    //{"glXCreateWindow", &retrace_glXCreateWindow},
+    {"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},
     //{"glXDestroyPixmap", &retrace_glXDestroyPixmap},
-    //{"glXDestroyWindow", &retrace_glXDestroyWindow},
+    {"glXDestroyWindow", &retrace_glXDestroyWindow},
     //{"glXFreeContextEXT", &retrace_glXFreeContextEXT},
     {"glXGetAGPOffsetMESA", &retrace::ignore},
     {"glXGetClientString", &retrace::ignore},
@@ -238,7 +376,7 @@ 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},
     //{"glXSelectEventSGIX", &retrace_glXSelectEventSGIX},
index ac03fcc97de6d56390f807a3b1661e6571d489c1..03e1fc1db7655ecf4b66e170d6d6caf539b1966a 100644 (file)
@@ -249,5 +249,65 @@ parseAttrib(const trace::Value *attribs, int param, int default_ = 0) {
     return default_;
 }
 
+void
+createWindow(glws::Drawable *window)
+{
+    glws::Visual *visual = getVisual(getDefaultProfile());
+
+    glws::createWindow(window, visual);
+}
+
+void
+destroyWindow(glws::Drawable *window)
+{
+    glws::destroyWindow(window);
+}
+
+glws::Drawable *
+createPixmap(unsigned width, unsigned height, unsigned depth)
+{
+    return glws::createPixmap(width, height, depth);
+}
+
+glws::Drawable *
+createGLPixmap(GLXFBConfig fbconfig, glws::Drawable *pixmap,
+               unsigned width, unsigned height, int *attrib_list)
+{
+    return glws::createGLPixmap(fbconfig, pixmap, width, height, attrib_list);
+}
+
+void
+bindTexImage(glws::Drawable *pixmap, int buffer)
+{
+    glws::bindTexImage(pixmap, buffer);
+}
+
+void
+releaseTexImage(glws::Drawable *pixmap, int buffer)
+{
+    glws::releaseTexImage(pixmap, buffer);
+}
+
+void
+copySubBuffer(glws::Drawable *drawable, int x, int y, int width, int height)
+{
+    glws::copySubBuffer(drawable, x, y, width, height);
+}
+
+void
+putImageData(glws::Drawable *drawable, char *data,
+             int width, int height, int depth,
+             int bits_per_pixel, int bytes_per_line, int byte_order)
+{
+    glws::putImageData(drawable, data, width, height, depth,
+                       bits_per_pixel, bytes_per_line, byte_order);
+}
+
+GLXFBConfig
+chooseConfig(int *attrib_list)
+{
+    return glws::chooseConfig(attrib_list);
+}
+
 
 } /* namespace glretrace */
index c76e19321706a5c8a02fca80dfcce7774ad2ce6f..d07eeb4db88c9132ac07db566c2ed57a5165bf93 100644 (file)
@@ -95,7 +95,6 @@ public:
     virtual ~Visual() {}
 };
 
-
 class Drawable
 {
 public:
@@ -130,7 +129,6 @@ public:
     virtual void swapBuffers(void) = 0;
 };
 
-
 class Context
 {
 public:
@@ -170,6 +168,36 @@ createContext(const Visual *visual, Context *shareContext = 0, Profile profile =
 bool
 makeCurrent(Drawable *drawable, Context *context);
 
+void
+createWindow(Drawable *drawable, const Visual *visual);
+
+void
+destroyWindow(Drawable *drawable);
+
+Drawable *
+createPixmap(unsigned width, unsigned height, unsigned depth);
+
+Drawable *
+createGLPixmap(GLXFBConfig fbconfig, Drawable *pixmap,
+               unsigned width, unsigned height, int *attrib_list);
+
+void
+bindTexImage(glws::Drawable *pixmap, int buffer);
+
+void
+releaseTexImage(glws::Drawable *pixmap, int buffer);
+
+void
+copySubBuffer(glws::Drawable *drawable, int x, int y, int width, int height);
+
+void
+putImageData(glws::Drawable *drawable, char *data,
+             int width, int height, int depth,
+             int bits_per_pixel, int bytes_per_line, int byte_order);
+
+GLXFBConfig
+chooseConfig(int *attrib_list);
+
 bool
 processEvents(void);
 
index 5aacdfed2b5bea5c0b738b907711d936610a93f8..9c233f969b6f48574097031ad7d1c11b1cff3e5c 100644 (file)
@@ -481,5 +481,30 @@ processEvents(void) {
     return true;
 }
 
+void
+createWindow(Drawable *drawable, const Visual *_visual)
+{
+    EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable);
+    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
+
+    eglDrawable->surface = eglCreateWindowSurface(display, visual->config,
+                                                  eglDrawable->window, NULL);
+}
+
+void
+destroyWindow(Drawable *drawable)
+{
+    EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable);
+
+    eglDestroySurface(display, eglDrawable->surface);
+}
+
+Pixmap
+createPixmap(unsigned width, unsigned height, unsigned depth)
+{
+    return XCreatePixmap(display, DefaultRootWindow(display),
+                         width, height, depth);
+}
+
 
 } /* namespace glws */
index 1494d060d7245cae687637db7c5452cc6a6c2f2b..ce742ac260001e815d7ed2f55ad9413c729f443f 100644 (file)
@@ -31,6 +31,8 @@
 #include "glproc.hpp"
 #include "glws.hpp"
 
+#include <cairo/cairo-xlib.h>
+
 
 namespace glws {
 
@@ -149,6 +151,12 @@ public:
         glXWaitX();
     }
 
+    GlxDrawable(const unsigned pixmap_id, int width, int height) :
+        Drawable(NULL, width, height, false)
+    {
+        window = pixmap_id;
+    }
+
     void processKeys(void) {
         XEvent event;
         while (XCheckWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event)) {
@@ -220,7 +228,6 @@ public:
     }
 };
 
-
 class GlxContext : public Context
 {
 public:
@@ -398,5 +405,142 @@ processEvents(void) {
     return true;
 }
 
+void
+createWindow(Drawable *drawable, const Visual *_visual)
+{
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+    const GlxVisual *visual = static_cast<const GlxVisual *>(_visual);
+
+    glXCreateWindow(display, visual->fbconfig, glxDrawable->window, NULL);
+}
+
+Drawable *
+createPixmap(unsigned width, unsigned height, unsigned depth)
+{
+    Pixmap pixmap;
+
+    pixmap = XCreatePixmap(display, DefaultRootWindow(display),
+                           width, height, depth);
+
+    printf ("Replayed XCreatePixmap to create pixmap %ld\n", pixmap);
+
+    return new GlxDrawable(pixmap, width, height);
+}
+
+Drawable *
+createGLPixmap(GLXFBConfig fbconfig, Drawable *_pixmap,
+             unsigned width, unsigned height, int *attrib_list)
+{
+    GlxDrawable *pixmap = static_cast<GlxDrawable *>(_pixmap);
+    Pixmap gl_pixmap;
+
+    gl_pixmap = glXCreatePixmap(display, fbconfig, pixmap->window, attrib_list);
+
+    printf ("And replayed glXCreatePixmap to create pixmap %ld\n", gl_pixmap);
+
+    return new GlxDrawable(gl_pixmap, width, height);
+}
+
+void
+destroyWindow(Drawable *drawable)
+{
+/*
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+
+    glXDestroyWindow(display, glxDrawable->window);
+*/
+}
+
+void
+bindTexImage(Drawable *drawable, int buffer)
+{
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+
+    glXBindTexImageEXT(display, glxDrawable->window, buffer, NULL);
+}
+
+void
+releaseTexImage(Drawable *drawable, int buffer)
+{
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+
+    glXReleaseTexImageEXT(display, glxDrawable->window, buffer);
+}
+
+void
+copySubBuffer(Drawable *drawable, int x, int y, int width, int height)
+{
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+
+    glXCopySubBufferMESA(display, glxDrawable->window, x, y, width, height);
+}
+
+void
+putImageData(glws::Drawable *drawable, char *data,
+             int width, int height, int depth,
+             int bits_per_pixel, int bytes_per_line, int byte_order)
+{
+    GlxDrawable *glxDrawable = static_cast<GlxDrawable *>(drawable);
+    GC gc;
+    XImage image;
+
+    printf ("Calling XPutImage to pixmap %ld\n", glxDrawable->window);
+
+    image.width = width;
+    image.height = height;
+    image.format = ZPixmap;
+    image.data = data;
+    image.byte_order = byte_order;
+    image.bitmap_unit = 32;
+    image.bitmap_bit_order = byte_order;
+    image.bitmap_pad = 32;
+    image.depth = depth,
+    image.bytes_per_line = bytes_per_line;
+    image.bits_per_pixel = bits_per_pixel;
+    image.red_mask = 0;
+    image.green_mask = 0;
+    image.blue_mask = 0;
+    image.obdata = 0;
+
+    XInitImage(&image);
+
+    {
+        Window root;
+        int x_ignore, y_ignore;
+        unsigned width, height, depth, border_width_ignore;
+        XGetGeometry(display, glxDrawable->window, &root, &x_ignore, &y_ignore,
+                     &width, &height, &border_width_ignore, &depth);
+    }
+
+    gc = XCreateGC(display, glxDrawable->window, 0, NULL);
+    XPutImage(display, glxDrawable->window, gc, &image, 0, 0, 0, 0, width, height);
+
+    {
+        static int count = 0;
+        char filename[] = "put-image-data-X.png";
+        cairo_surface_t *surface;
+
+        surface = cairo_xlib_surface_create(display, glxDrawable->window, DefaultVisual(display, DefaultScreen(display)), width, height);
+
+        filename[15] = '0' + count;
+        cairo_surface_write_to_png(surface, filename);
+
+        cairo_surface_destroy(surface);
+        count++;
+    }
+
+}
+
+GLXFBConfig
+chooseConfig(int *attrib_list)
+{
+    GLXFBConfig *configs;
+    int nelements;
+    configs = glXChooseFBConfig(display, DefaultScreen(display), attrib_list, &nelements);
+    if (nelements)
+        return configs[nelements - 1];
+    else
+        return NULL;
+}
 
-} /* namespace glws */
+} /* drawable glws */
diff --git a/specs/xapi.py b/specs/xapi.py
new file mode 100644 (file)
index 0000000..5792278
--- /dev/null
@@ -0,0 +1,43 @@
+##########################################################################
+#
+# Copyright 2013 Intel Corporation
+# Copyright 2008-2009 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+"""X API description (minimal functions needed to enable GLX tracing)."""
+
+
+from stdapi import *
+from glapi import *
+
+Display = Opaque("Display *")
+Pixmap = Alias("Pixmap", UInt32)
+Drawable = Alias("Drawable", UInt32)
+
+xapi = Module("X")
+
+xapi.addFunctions([
+    Function(Pixmap, "XCreatePixmap", [(Display, "dpy"), (Drawable, "d"),
+                                       (UInt, "width"), (UInt, "height"), (UInt, "depth")]),
+    Function(Int, "XFreePixmap", [(Display, "dpy"), (Drawable, "pixmap")]),
+])
index 6b76e589b04c4103848d2841b3e287878258e4c8..aa4fde33d32a7920dcb8ccbf567994d64868576d 100644 (file)
@@ -399,10 +399,25 @@ elseif (X11_FOUND)
             ${CMAKE_SOURCE_DIR}/specs/stdapi.py
     )
 
+    add_custom_command (
+        OUTPUT xtrace.cpp
+        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/xtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/xtrace.cpp
+        DEPENDS
+            xtrace.py
+            gltrace.py
+            trace.py
+            ${CMAKE_SOURCE_DIR}/specs/xapi.py
+            ${CMAKE_SOURCE_DIR}/specs/glapi.py
+            ${CMAKE_SOURCE_DIR}/specs/glparams.py
+            ${CMAKE_SOURCE_DIR}/specs/gltypes.py
+            ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+    )
+
     add_library (glxtrace SHARED
         glxtrace.cpp
         glcaps.cpp
         gltrace_state.cpp
+        xtrace.cpp
     )
 
     add_dependencies (glxtrace glproc)
diff --git a/wrappers/xtrace.cpp b/wrappers/xtrace.cpp
new file mode 100644 (file)
index 0000000..3ca8463
--- /dev/null
@@ -0,0 +1,183 @@
+/* Check that our prototypes match */
+#include <X11/X.h>
+
+#include "trace_writer_local.hpp"
+
+#include <cairo/cairo-xlib.h>
+
+#include "glproc.hpp"
+
+#ifdef _WIN32
+#  include <malloc.h> // alloca
+#  ifndef alloca
+#    define alloca _alloca
+#  endif
+#else
+#  include <alloca.h> // alloca
+#endif
+
+#include "trace.hpp"
+
+static std::map<void *, void *> g_WrappedObjects;
+
+
+static const char * _XCreatePixmap_args[5] = {"dpy", "d", "width", "height", "depth"};
+static const trace::FunctionSig _XCreatePixmap_sig = {2466, "XCreatePixmap", 5, _XCreatePixmap_args};
+
+static const char * _XFreePixmap_args[2] = {"dpy", "pixmap"};
+static const trace::FunctionSig _XFreePixmap_sig = {2467, "XFreePixmap", 2, _XFreePixmap_args};
+
+static const char * _PutImageData_args[8] = {"drawable", "data", "width", "height", "depth", "bits_per_pixel", "bytes_per_line", "byte_order"};
+static const trace::FunctionSig _PutImageData_sig = {2468, "PutImageData", 8, _PutImageData_args};
+
+void
+emit_fake_put_image_data(Display *dpy, Drawable pixmap)
+{
+    Window root;
+    int x_ignore, y_ignore;
+    unsigned width, height, depth, border_width_ignore;
+
+    XGetGeometry(dpy, pixmap, &root, &x_ignore, &y_ignore,
+                 &width, &height, &border_width_ignore, &depth);
+
+    {
+        static int count = 0;
+        char filename[] = "image-data-X.png";
+        cairo_surface_t *surface;
+
+        surface = cairo_xlib_surface_create(dpy, pixmap, DefaultVisual(dpy, DefaultScreen(dpy)), width, height);
+
+        filename[11] = '0' + count;
+        cairo_surface_write_to_png(surface, filename);
+
+        cairo_surface_destroy(surface);
+        count++;
+    }
+
+
+    XImage *image = XGetImage(dpy, pixmap, 0, 0, width, height, AllPlanes, ZPixmap);
+    unsigned _call = trace::localWriter.beginEnter(&_PutImageData_sig);
+    trace::localWriter.beginArg(0);
+    trace::localWriter.writeUInt(pixmap);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(1);
+    trace::localWriter.writeBlob(image->data, image->bytes_per_line * image->height);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(2);
+    trace::localWriter.writeSInt(width);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(3);
+    trace::localWriter.writeSInt(height);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(4);
+    trace::localWriter.writeSInt(image->depth);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(5);
+    trace::localWriter.writeSInt(image->bits_per_pixel);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(6);
+    trace::localWriter.writeSInt(image->bytes_per_line);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(7);
+    trace::localWriter.writeSInt(image->byte_order);
+    trace::localWriter.endArg();
+    trace::localWriter.endEnter();
+    trace::localWriter.beginLeave(_call);
+    trace::localWriter.endLeave();
+}
+
+void
+emit_fake_x_create_pixmap(Display *dpy, Drawable pixmap)
+{
+    Window root;
+    int x_ignore, y_ignore;
+    unsigned width, height, depth, border_width_ignore;
+    XGetGeometry(dpy, pixmap, &root, &x_ignore, &y_ignore,
+                 &width, &height, &border_width_ignore, &depth);
+    unsigned _call = trace::localWriter.beginEnter(&_XCreatePixmap_sig);
+    printf("Yes, really emitting fake XCreatePixmap (call no. %d)\n", _call);
+    trace::localWriter.beginArg(0);
+    trace::localWriter.writePointer((uintptr_t)dpy);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(1);
+    trace::localWriter.writeUInt(root);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(2);
+    trace::localWriter.writeUInt(width);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(3);
+    trace::localWriter.writeUInt(height);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(4);
+    trace::localWriter.writeUInt(depth);
+    trace::localWriter.endArg();
+    trace::localWriter.endEnter();
+    trace::localWriter.beginLeave(_call);
+    trace::localWriter.beginReturn();
+    trace::localWriter.writeUInt(pixmap);
+    trace::localWriter.endReturn();
+    trace::localWriter.endLeave();
+}
+
+#if 0
+extern "C" PUBLIC
+Pixmap XCreatePixmap(Display * dpy, Drawable d, unsigned int width, unsigned int height, unsigned int depth) {
+    Pixmap _result;
+    if (!trace::isTracingEnabled()) {
+    _result = _XCreatePixmap(dpy, d, width, height, depth);
+        return _result;
+    }
+    unsigned _call = trace::localWriter.beginEnter(&_XCreatePixmap_sig);
+    trace::localWriter.beginArg(0);
+    trace::localWriter.writePointer((uintptr_t)dpy);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(1);
+    trace::localWriter.writeUInt(d);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(2);
+    trace::localWriter.writeUInt(width);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(3);
+    trace::localWriter.writeUInt(height);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(4);
+    trace::localWriter.writeUInt(depth);
+    trace::localWriter.endArg();
+    trace::localWriter.endEnter();
+    _result = _XCreatePixmap(dpy, d, width, height, depth);
+    trace::localWriter.beginLeave(_call);
+    if (true) {
+    }
+    trace::localWriter.beginReturn();
+    trace::localWriter.writeUInt(_result);
+    trace::localWriter.endReturn();
+    trace::localWriter.endLeave();
+    return _result;
+}
+
+extern "C" PUBLIC
+int XFreePixmap(Display * dpy, Drawable pixmap) {
+    int _result;
+    if (!trace::isTracingEnabled()) {
+    _result = _XFreePixmap(dpy, pixmap);
+        return _result;
+    }
+    unsigned _call = trace::localWriter.beginEnter(&_XFreePixmap_sig);
+    trace::localWriter.beginArg(0);
+    trace::localWriter.writePointer((uintptr_t)dpy);
+    trace::localWriter.endArg();
+    trace::localWriter.beginArg(1);
+    trace::localWriter.writeUInt(pixmap);
+    trace::localWriter.endArg();
+    trace::localWriter.endEnter();
+    _result = _XFreePixmap(dpy, pixmap);
+    trace::localWriter.beginLeave(_call);
+    if (true) {
+    }
+    trace::localWriter.beginReturn();
+    trace::localWriter.writeSInt(_result);
+    trace::localWriter.endReturn();
+    trace::localWriter.endLeave();
+    return _result;
+}
+#endif
diff --git a/wrappers/xtrace.py b/wrappers/xtrace.py
new file mode 100644 (file)
index 0000000..3636de3
--- /dev/null
@@ -0,0 +1,52 @@
+##########################################################################
+#
+# Copyright 2013 Intel Corporation
+# Copyright 2011 Jose Fonseca
+# Copyright 2008-2010 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+
+"""X tracing generator (minimal calls needed to enable GLX tracing)."""
+
+from trace import Tracer
+from specs.stdapi import Module, API
+from specs.xapi import xapi
+
+class XTracer(Tracer):
+    pass
+
+if __name__ == '__main__':
+    print '/* Check that our prototypes match */'
+    print '#include <X11/X.h>'
+    print
+    print '#include "trace_writer_local.hpp"'
+    print
+    print '#include "glproc.hpp"'
+    print
+
+    module = Module()
+    module.mergeModule(xapi)
+    api = API()
+    api.addModule(module)
+    tracer = XTracer()
+    tracer.traceApi(api)