#include "retrace.hpp"
#include "glretrace.hpp"
+#include <vector>
#ifndef GLX_PBUFFER_HEIGHT
#define GLX_PBUFFER_HEIGHT 0x8040
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) {
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},
//{"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},
{"glXGetCurrentDrawable", &retrace::ignore},
{"glXGetCurrentReadDrawable", &retrace::ignore},
{"glXGetCurrentReadDrawableSGI", &retrace::ignore},
- {"glXGetFBConfigAttrib", &retrace::ignore},
+ {"glXGetFBConfigAttrib", &retrace_glXGetFBConfigAttrib},
{"glXGetFBConfigAttribSGIX", &retrace::ignore},
{"glXGetFBConfigFromVisualSGIX", &retrace::ignore},
{"glXGetFBConfigs", &retrace::ignore},
{"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},