]> git.cworth.org Git - apitrace/commitdiff
Implement Xlib/GLX.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 2 Apr 2011 19:12:33 +0000 (20:12 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 2 Apr 2011 19:12:33 +0000 (20:12 +0100)
CMakeLists.txt
glretrace.hpp
glretrace.py
glretrace_xlib.cpp [new file with mode: 0644]

index d189597779d0c6ee2a035d0918e4d50741af94ed..7d919e8bcd5009de261d67c59ce988e9bbde9f0e 100644 (file)
@@ -28,8 +28,6 @@ else (NOT WIN32)
     find_package (DirectX)
 endif (NOT WIN32)
 
-find_package (GLUT)
-
 if (WIN32)
     # MSVC & MinGW only define & use APIENTRY
     add_definitions (-DGLAPIENTRY=__stdcall)
@@ -206,39 +204,36 @@ add_library (trace trace_model.cpp trace_parser.cpp ${os})
 add_executable (dump dump.cpp)
 target_link_libraries (dump trace)
 
-if (GLUT_INCLUDE_DIR)
-    add_custom_command (
-        OUTPUT glretrace.cpp
-        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glretrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glretrace.cpp
-        DEPENDS glretrace.py retrace.py codegen.py glapi.py glenum.py stdapi.py
-    )
+add_custom_command (
+    OUTPUT glretrace.cpp
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glretrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glretrace.cpp
+    DEPENDS glretrace.py retrace.py codegen.py glapi.py glenum.py stdapi.py
+)
 
-    add_custom_command (
-        OUTPUT glstate.cpp
-        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate.cpp
-        DEPENDS glstate.py glenum.py stdapi.py
-    )
+add_custom_command (
+    OUTPUT glstate.cpp
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate.cpp
+    DEPENDS glstate.py glenum.py stdapi.py
+)
 
-    include_directories (
-        ${CMAKE_CURRENT_BINARY_DIR}
-        ${OPENGL_INCLUDE_PATH}
-        ${GLUT_INCLUDE_DIR}
-    )
+include_directories (
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ${OPENGL_INCLUDE_PATH}
+)
 
-    add_executable (glretrace
-        glretrace.cpp
-        glstate.cpp
-        image.cpp 
-        ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
-    )
+add_executable (glretrace
+    glretrace.cpp
+    glretrace_xlib.cpp
+    glstate.cpp
+    image.cpp 
+    ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
+)
 
-    target_link_libraries (glretrace
-        trace
-        ${OPENGL_gl_LIBRARY}
-        ${OPENGL_glu_LIBRARY}
-        ${GLUT_glut_LIBRARY}
-    )
-endif (GLUT_INCLUDE_DIR)
+target_link_libraries (glretrace
+    trace
+    ${OPENGL_gl_LIBRARY}
+    ${OPENGL_glu_LIBRARY}
+)
 
 if (QT4_FOUND AND QJSON_FOUND)
     # Include the cmake file needed to use qt4
index a56606c5a89ab9a87cc37ae0487147d57ea308b2..a275f52a4eb9b2d4b0bbc76859378d5fe199fc03 100644 (file)
 namespace glretrace {
 
 
-struct Visual
+class Visual
 {
+public:
     unsigned long redMask;
     unsigned long greenMask;
     unsigned long blueMask;
     unsigned long alphaMask;
     bool doubleBuffer;
+
+    virtual ~Visual() {}
 };
 
 
-struct Context
+class Drawable
 {
+public:
     const Visual *visual;
+    unsigned width;
+    unsigned height;
+
+    Drawable(const Visual *vis) :
+        visual(vis)
+    {}
+
+    virtual ~Drawable() {}
+    
+    virtual void
+    resize(unsigned w, unsigned h) {
+        width = w;
+        height = h;
+    }
+
+    virtual void swapBuffers(void) = 0;
 };
 
 
-struct Drawable
+class Context
 {
-    unsigned width;
-    unsigned height;
+public:
+    const Visual *visual;
+    
+    Context(const Visual *vis) :
+        visual(vis)
+    {}
+
+    virtual ~Context() {}
 };
 
 
@@ -71,28 +97,14 @@ public:
 
     virtual ~WindowSystem() {}
 
-    //
-    // Drawables
-    //
-
+    virtual Visual *
+    createVisual(bool doubleBuffer=false) = 0;
+    
     virtual Drawable *
-    createDrawable(unsigned width = 0, unsigned height = 0) = 0;
-
-    virtual void
-    resizeDrawable(Drawable *drawable, unsigned width, unsigned height) = 0;
+    createDrawable(const Visual *visual) = 0;
 
-    virtual Void *
-    destroyDrawable(void) = 0;
-
-    // 
-    // Contexts
-    //
     virtual Context *
     createContext(const Visual *visual) = 0;
-
-    virtual void
-    deleteContext(Context *) = 0;
     
     virtual bool
     makeCurrent(Drawable *drawable, Context *context) = 0;
index fd1460a550444ec0048b1990fd06165cfa205c71..2f2b8fff198ef90d66eb21cb58c3909cf27e822b 100644 (file)
@@ -171,8 +171,7 @@ if __name__ == '__main__':
 
 #include "glproc.hpp"
 #include "glstate.hpp"
-
-#include <GL/glut.h>
+#include "glretrace.hpp"
 
 static bool double_buffer = false;
 static bool insideGlBeginEnd = false;
@@ -241,9 +240,10 @@ checkGlError(void) {
     print r'''
 
 static Trace::Parser parser;
-
-static void display_noop(void) {
-}
+static glretrace::WindowSystem *__ws = NULL;
+static glretrace::Visual *__visual = NULL;
+static glretrace::Drawable *__drawable = NULL;
+static glretrace::Context *__context = NULL;
 
 #include "image.hpp"
 
@@ -290,7 +290,14 @@ static void frame_complete(void) {
             delete ref;
         }
     }
+    
+    if (__reshape_window) {
+        // XXX: doesn't quite work
+        __drawable->resize(__window_width, __window_height);
+        __reshape_window = false;
+    }
 
+    __ws->processEvents();
 }
 
 static void display(void) {
@@ -315,21 +322,14 @@ static void display(void) {
                 };
                 frame_complete();
                 if (double_buffer)
-                    glutSwapBuffers();
+                    __drawable->swapBuffers();
                 else
                     glFlush();
-
-                // Return now to allow GLUT to resize the window.
-                delete call;
-                return;
             } else if (name == "glXMakeCurrent" ||
                        name == "wglMakeCurrent") {
                 glFlush();
                 if (!double_buffer) {
                     frame_complete();
-                    // Return now to allow GLUT to resize window.
-                    delete call;
-                    return;
                 }
             } else {
                 continue;
@@ -362,22 +362,12 @@ static void display(void) {
     }
 
     if (__wait) {
-        glutDisplayFunc(&display_noop);
-        glutIdleFunc(NULL);
+        while (__ws->processEvents()) {}
     } else {
         exit(0);
     }
 }
 
-static void idle(void) {
-    if (__reshape_window) {
-        // XXX: doesn't quite work
-        glutReshapeWindow(__window_width, __window_height);
-        __reshape_window = false;
-    }
-    glutPostRedisplay();
-}
-
 static void usage(void) {
     std::cout << 
         "Usage: glretrace [OPTION] TRACE\n"
@@ -431,14 +421,12 @@ int main(int argc, char **argv)
         }
     }
 
-    glutInit(&argc, argv);
-    glutInitWindowPosition(0, 0);
-    glutInitWindowSize(__window_width, __window_height);
-    glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | (double_buffer ? GLUT_DOUBLE : GLUT_SINGLE));
-    glutCreateWindow(argv[0]);
-
-    glutDisplayFunc(&display);
-    glutIdleFunc(&idle);
+    __ws = glretrace::createNativeWindowSystem();
+    __visual = __ws->createVisual(double_buffer);
+    __drawable = __ws->createDrawable(__visual);
+    __drawable->resize(__window_width, __window_height);
+    __context = __ws->createContext(__visual);
+    __ws->makeCurrent(__drawable, __context);
 
     for (GLuint h = 0; h < 1024; ++h) {
         __list_map[h] = h;
@@ -447,7 +435,7 @@ int main(int argc, char **argv)
     for ( ; i < argc; ++i) {
         if (parser.open(argv[i])) {
             __startTime = OS::GetTime();
-            glutMainLoop();
+            display();
             parser.close();
         }
     }
diff --git a/glretrace_xlib.cpp b/glretrace_xlib.cpp
new file mode 100644 (file)
index 0000000..a6764c5
--- /dev/null
@@ -0,0 +1,232 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * 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.
+ *
+ **************************************************************************/
+
+#include "glimports.hpp"
+#include "glretrace.hpp"
+
+
+namespace glretrace {
+
+
+class XlibVisual : public Visual
+{
+public:
+    XVisualInfo *visinfo;
+
+    XlibVisual(XVisualInfo *vi) :
+        visinfo(vi)
+    {}
+
+    ~XlibVisual() {
+        XFree(visinfo);
+    }
+};
+
+
+class XlibDrawable : public Drawable
+{
+public:
+    Display *display;
+    Window window;
+
+    XlibDrawable(const Visual *vis, Display *dpy, Window win) :
+        Drawable(vis),
+        display(dpy), 
+        window(win)
+    {}
+
+    ~XlibDrawable() {
+        XDestroyWindow(display, window);
+    }
+    
+    void
+    resize(unsigned w, unsigned h) {
+        Drawable::resize(w, h);
+        XResizeWindow(display, window, w, h);
+    }
+
+    void swapBuffers(void) {
+        glXSwapBuffers(display, window);
+    }
+};
+
+
+class XlibContext : public Context
+{
+public:
+    Display *display;
+    GLXContext context;
+    
+    XlibContext(const Visual *vis, Display *dpy, GLXContext ctx) :
+        Context(vis),
+        display(dpy), 
+        context(ctx)
+    {}
+
+    ~XlibContext() {
+        glXDestroyContext(display, context);
+    }
+};
+
+
+class XlibWindowSystem : public WindowSystem
+{
+private:
+    Display *display;
+    int screen;
+
+public:
+    Drawable *currentDrawable;
+    Context *currentContext;
+
+    XlibWindowSystem() {
+       display = XOpenDisplay(NULL);
+       screen = DefaultScreen(display);
+    }
+
+    ~XlibWindowSystem() {
+        XCloseDisplay(display);
+    }
+
+    Visual *
+    createVisual(bool doubleBuffer) {
+        int single_attribs[] = {
+            GLX_RGBA,
+            GLX_RED_SIZE, 1,
+            GLX_GREEN_SIZE, 1,
+            GLX_BLUE_SIZE, 1,
+            GLX_DEPTH_SIZE, 1,
+            None
+        };
+
+        int double_attribs[] = {
+            GLX_RGBA,
+            GLX_RED_SIZE, 1,
+            GLX_GREEN_SIZE, 1,
+            GLX_BLUE_SIZE, 1,
+            GLX_DOUBLEBUFFER,
+            GLX_DEPTH_SIZE, 1,
+            None
+        };
+
+        XVisualInfo *visinfo;
+        
+        visinfo = glXChooseVisual(display, screen, doubleBuffer ? double_attribs : single_attribs);
+
+        return new XlibVisual(visinfo);
+    }
+    
+    Drawable *
+    createDrawable(const Visual *visual)
+    {
+        XVisualInfo *visinfo = dynamic_cast<const XlibVisual *>(visual)->visinfo;
+
+        Window root = RootWindow(display, screen);
+
+        /* window attributes */
+        XSetWindowAttributes attr;
+        attr.background_pixel = 0;
+        attr.border_pixel = 0;
+        attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
+        attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+        
+        unsigned long mask;
+        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+        int x = 0, y = 0, width = 256, height = 256;
+
+        Window window = XCreateWindow(
+            display, root, 
+            x, y, width, height,
+            0, 
+            visinfo->depth, 
+            InputOutput,
+            visinfo->visual, 
+            mask, 
+            &attr);
+
+        XSizeHints sizehints;
+        sizehints.x = x;
+        sizehints.y = y;
+        sizehints.width  = width;
+        sizehints.height = height;
+        sizehints.flags = USSize | USPosition;
+        XSetNormalHints(display, window, &sizehints);
+        
+        const char *name = "glretrace";
+        XSetStandardProperties(
+            display, window, name, name,
+            None, (char **)NULL, 0, &sizehints);
+
+        XMapWindow(display, window);
+        
+        return new XlibDrawable(visual, display, window);
+    }
+
+    Context *
+    createContext(const Visual *visual)
+    {
+        XVisualInfo *visinfo = dynamic_cast<const XlibVisual *>(visual)->visinfo;
+        GLXContext context = glXCreateContext(display, visinfo, NULL, True);
+        return new XlibContext(visual, display, context);
+    }
+
+    bool
+    makeCurrent(Drawable *drawable, Context *context)
+    {
+        Window win = drawable ? dynamic_cast<XlibDrawable *>(drawable)->window : NULL;
+        GLXContext ctx = context ? dynamic_cast<XlibContext *>(context)->context : NULL;
+
+        bool ret = glXMakeCurrent(display, win, ctx);
+
+        if (drawable && context && ret) {
+            currentDrawable = drawable;
+            currentContext = context;
+        } else {
+            currentDrawable = NULL;
+            currentContext = NULL;
+        }
+
+        return ret;
+    }
+
+    bool
+    processEvents(void) {
+      while (XPending(display) > 0) {
+         XEvent event;
+         XNextEvent(display, &event);
+         // TODO
+      }
+      return true;
+    }
+};
+
+
+WindowSystem *createNativeWindowSystem(void) {
+    return new XlibWindowSystem();
+}
+
+
+} /* namespace glretrace */