From bad1fde2495d16e6a1f90571c317836300840dd5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 16 May 2013 15:19:36 -0700 Subject: [PATCH] stash: Trace and replay of glx-tfp works Trace and replay of gnome-shell still doesn't work due to it manually grubbing through the results of calling glXGetFBConfigs. --- CMakeLists.txt | 1 + common/os_dl.hpp | 2 + dispatch/CMakeLists.txt | 1 + dispatch/glproc.py | 6 ++ dispatch/glproc_gl.cpp | 4 +- dispatch/xproc.hpp | 46 ++++++++++ retrace/glretrace.hpp | 29 ++++++ retrace/glretrace_glx.cpp | 154 ++++++++++++++++++++++++++++++-- retrace/glretrace_ws.cpp | 60 +++++++++++++ retrace/glws.hpp | 32 ++++++- retrace/glws_egl_xlib.cpp | 25 ++++++ retrace/glws_glx.cpp | 148 +++++++++++++++++++++++++++++- specs/xapi.py | 43 +++++++++ wrappers/CMakeLists.txt | 15 ++++ wrappers/xtrace.cpp | 183 ++++++++++++++++++++++++++++++++++++++ wrappers/xtrace.py | 52 +++++++++++ 16 files changed, 788 insertions(+), 13 deletions(-) create mode 100644 dispatch/xproc.hpp create mode 100644 specs/xapi.py create mode 100644 wrappers/xtrace.cpp create mode 100644 wrappers/xtrace.py diff --git a/CMakeLists.txt b/CMakeLists.txt index ac046f5..1f43f96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/common/os_dl.hpp b/common/os_dl.hpp index da51d41..cecfa35 100644 --- a/common/os_dl.hpp +++ b/common/os_dl.hpp @@ -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 diff --git a/dispatch/CMakeLists.txt b/dispatch/CMakeLists.txt index 0dad67f..9f43f4b 100644 --- a/dispatch/CMakeLists.txt +++ b/dispatch/CMakeLists.txt @@ -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 ) diff --git a/dispatch/glproc.py b/dispatch/glproc.py index 488f912..6c6e204 100644 --- a/dispatch/glproc.py +++ b/dispatch/glproc.py @@ -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) diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp index 8e1216f..750c65c 100644 --- a/dispatch/glproc_gl.cpp +++ b/dispatch/glproc_gl.cpp @@ -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 index 0000000..576673d --- /dev/null +++ b/dispatch/xproc.hpp @@ -0,0 +1,46 @@ +#ifndef _XPROC_HPP_ +#define _XPROC_HPP_ + +#include + +#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 diff --git a/retrace/glretrace.hpp b/retrace/glretrace.hpp index 7441b56..1f5f451 100644 --- a/retrace/glretrace.hpp +++ b/retrace/glretrace.hpp @@ -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); diff --git a/retrace/glretrace_glx.cpp b/retrace/glretrace_glx.cpp index 4ab3d67..eb64b6b 100644 --- a/retrace/glretrace_glx.cpp +++ b/retrace/glretrace_glx.cpp @@ -40,12 +40,20 @@ using namespace glretrace; +typedef struct { + int width; + int height; + int depth; +} PixmapDesc; typedef std::map DrawableMap; typedef std::map ContextMap; +typedef std::map PixmapDescMap; +typedef std::map 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(_allocator.alloc(&call.arg(3), sizeof *attrib_list)); + if (attrib_list) { + const trace::Array *arg_list = dynamic_cast(&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((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(_allocator.alloc(&call.arg(2), sizeof *attrib_list)); + if (attrib_list) { + const trace::Array *arg_list = dynamic_cast(&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(&call.arg(3))->values[0]->toSInt(); + orig_configs = dynamic_cast(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(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}, diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp index ac03fcc..03e1fc1 100644 --- a/retrace/glretrace_ws.cpp +++ b/retrace/glretrace_ws.cpp @@ -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 */ diff --git a/retrace/glws.hpp b/retrace/glws.hpp index c76e193..d07eeb4 100644 --- a/retrace/glws.hpp +++ b/retrace/glws.hpp @@ -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); diff --git a/retrace/glws_egl_xlib.cpp b/retrace/glws_egl_xlib.cpp index 5aacdfe..9c233f9 100644 --- a/retrace/glws_egl_xlib.cpp +++ b/retrace/glws_egl_xlib.cpp @@ -481,5 +481,30 @@ processEvents(void) { return true; } +void +createWindow(Drawable *drawable, const Visual *_visual) +{ + EglDrawable *eglDrawable = static_cast(drawable); + const EglVisual *visual = static_cast(_visual); + + eglDrawable->surface = eglCreateWindowSurface(display, visual->config, + eglDrawable->window, NULL); +} + +void +destroyWindow(Drawable *drawable) +{ + EglDrawable *eglDrawable = static_cast(drawable); + + eglDestroySurface(display, eglDrawable->surface); +} + +Pixmap +createPixmap(unsigned width, unsigned height, unsigned depth) +{ + return XCreatePixmap(display, DefaultRootWindow(display), + width, height, depth); +} + } /* namespace glws */ diff --git a/retrace/glws_glx.cpp b/retrace/glws_glx.cpp index 1494d06..ce742ac 100644 --- a/retrace/glws_glx.cpp +++ b/retrace/glws_glx.cpp @@ -31,6 +31,8 @@ #include "glproc.hpp" #include "glws.hpp" +#include + 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(drawable); + const GlxVisual *visual = static_cast(_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(_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(drawable); + + glXDestroyWindow(display, glxDrawable->window); +*/ +} + +void +bindTexImage(Drawable *drawable, int buffer) +{ + GlxDrawable *glxDrawable = static_cast(drawable); + + glXBindTexImageEXT(display, glxDrawable->window, buffer, NULL); +} + +void +releaseTexImage(Drawable *drawable, int buffer) +{ + GlxDrawable *glxDrawable = static_cast(drawable); + + glXReleaseTexImageEXT(display, glxDrawable->window, buffer); +} + +void +copySubBuffer(Drawable *drawable, int x, int y, int width, int height) +{ + GlxDrawable *glxDrawable = static_cast(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(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 index 0000000..5792278 --- /dev/null +++ b/specs/xapi.py @@ -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")]), +]) diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index 6b76e58..aa4fde3 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -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 index 0000000..3ca8463 --- /dev/null +++ b/wrappers/xtrace.cpp @@ -0,0 +1,183 @@ +/* Check that our prototypes match */ +#include + +#include "trace_writer_local.hpp" + +#include + +#include "glproc.hpp" + +#ifdef _WIN32 +# include // alloca +# ifndef alloca +# define alloca _alloca +# endif +#else +# include // alloca +#endif + +#include "trace.hpp" + +static std::map 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 index 0000000..3636de3 --- /dev/null +++ b/wrappers/xtrace.py @@ -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 ' + 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) -- 2.43.0