]> git.cworth.org Git - apitrace/blobdiff - glws_wgl.cpp
Move tracers to wrappers subdirectory.
[apitrace] / glws_wgl.cpp
index 94390da221f3b8b13eed1d74622da2d09cedb06d..efefff0e1e784faef84ba4928f7f9e0d64bcf068 100644 (file)
  *
  **************************************************************************/
 
-#include "glimports.hpp"
+
+/*
+ * WGL bindings.
+ */
+
+
+#include <iostream>
+
+#include "glproc.hpp"
 #include "glws.hpp"
 
 
 namespace glws {
 
 
+/*
+ * Several WGL functions come in two flavors:
+ * - GDI (ChoosePixelFormat, SetPixelFormat, SwapBuffers, etc)
+ * - WGL (wglChoosePixelFormat, wglSetPixelFormat, wglSwapBuffers, etc)
+ *
+ * The GDI entrypoints will inevitably dispatch to the first module named
+ * "OPENGL32", loading "C:\Windows\System32\opengl32.dll" if none was loaded so
+ * far.
+ *
+ * In order to use a implementation other than the one installed in the system
+ * (when specified via the TRACE_LIBGL environment variable), we need to use
+ * WGL entrypoints.
+ *
+ * See also:
+ * - http://www.opengl.org/archives/resources/faq/technical/mswindows.htm
+ */
+static __PFNWGLCHOOSEPIXELFORMAT pfnChoosePixelFormat = &ChoosePixelFormat;
+static __PFNWGLSETPIXELFORMAT pfnSetPixelFormat = &SetPixelFormat;
+static __PFNWGLSWAPBUFFERS pfnSwapBuffers = &SwapBuffers;
+
+
 static LRESULT CALLBACK
 WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
@@ -66,6 +95,7 @@ public:
     {
         static bool first = TRUE;
         RECT rect;
+        BOOL bRet;
 
         if (first) {
             WNDCLASS wc;
@@ -81,7 +111,7 @@ public:
         }
 
         dwExStyle = 0;
-        dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_OVERLAPPEDWINDOW;
+        dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
 
         int x = 0, y = 0;
 
@@ -124,9 +154,17 @@ public:
            pfd.dwFlags |= PFD_DOUBLEBUFFER;
         }
 
-        iPixelFormat = ChoosePixelFormat(hDC, &pfd);
+        iPixelFormat = pfnChoosePixelFormat(hDC, &pfd);
+        if (iPixelFormat <= 0) {
+            std::cerr << "error: ChoosePixelFormat failed\n";
+            exit(1);
+        }
 
-        SetPixelFormat(hDC, iPixelFormat, &pfd);
+        bRet = pfnSetPixelFormat(hDC, iPixelFormat, &pfd);
+        if (!bRet) {
+            std::cerr << "error: SetPixelFormat failed\n";
+            exit(1);
+        }
     }
 
     ~WglDrawable() {
@@ -136,17 +174,44 @@ public:
     
     void
     resize(int w, int h) {
-        Drawable::resize(w, h);
+        if (w == width && h == height) {
+            return;
+        }
+
         RECT rClient, rWindow;
         GetClientRect(hWnd, &rClient);
         GetWindowRect(hWnd, &rWindow);
         w += (rWindow.right  - rWindow.left) - rClient.right;
         h += (rWindow.bottom - rWindow.top)  - rClient.bottom;
         SetWindowPos(hWnd, NULL, rWindow.left, rWindow.top, w, h, SWP_NOMOVE);
+
+        Drawable::resize(w, h);
+    }
+
+    void show(void) {
+        if (visible) {
+            return;
+        }
+
+        ShowWindow(hWnd, SW_SHOW);
+
+        Drawable::show();
     }
 
     void swapBuffers(void) {
-        SwapBuffers(hDC);
+        BOOL bRet;
+        bRet = pfnSwapBuffers(hDC);
+        if (!bRet) {
+            std::cerr << "warning: SwapBuffers failed\n";
+        }
+
+        // Drain message queue to prevent window from being considered
+        // non-responsive
+        MSG msg;
+        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
     }
 };
 
@@ -157,8 +222,8 @@ public:
     HGLRC hglrc;
     WglContext *shareContext;
 
-    WglContext(const Visual *vis, WglContext *share) :
-        Context(vis),
+    WglContext(const Visual *vis, Profile prof, WglContext *share) :
+        Context(vis, prof),
         hglrc(0),
         shareContext(share)
     {}
@@ -171,65 +236,97 @@ public:
 };
 
 
-class WglWindowSystem : public WindowSystem
-{
-public:
-    Visual *
-    createVisual(bool doubleBuffer) {
-        Visual *visual = new Visual();
+void
+init(void) {
+    /*
+     * OpenGL library must be loaded by the time we call GDI.
+     */
 
-        visual->doubleBuffer = doubleBuffer;
+    const char * libgl_filename = getenv("TRACE_LIBGL");
 
-        return visual;
+    if (libgl_filename) {
+        pfnChoosePixelFormat = &wglChoosePixelFormat;
+        pfnSetPixelFormat = &wglSetPixelFormat;
+        pfnSwapBuffers = &wglSwapBuffers;
+    } else {
+        libgl_filename = "OPENGL32";
     }
-    
-    Drawable *
-    createDrawable(const Visual *visual, int width, int height)
-    {
-        return new WglDrawable(visual, width, height);
+
+    __libGlHandle = LoadLibraryA(libgl_filename);
+    if (!__libGlHandle) {
+        std::cerr << "error: unable to open " << libgl_filename << "\n";
+        exit(1);
     }
+}
 
-    Context *
-    createContext(const Visual *visual, Context *shareContext)
-    {
-        return new WglContext(visual, dynamic_cast<WglContext *>(shareContext));
+void
+cleanup(void) {
+}
+
+Visual *
+createVisual(bool doubleBuffer, Profile profile) {
+    if (profile != PROFILE_COMPAT) {
+        return NULL;
     }
 
-    bool
-    makeCurrent(Drawable *drawable, Context *context)
-    {
-        if (!drawable || !context) {
-            return wglMakeCurrent(NULL, NULL);
-        } else {
-            WglDrawable *wglDrawable = dynamic_cast<WglDrawable *>(drawable);
-            WglContext *wglContext = dynamic_cast<WglContext *>(context);
+    Visual *visual = new Visual();
+
+    visual->doubleBuffer = doubleBuffer;
+
+    return visual;
+}
+
+Drawable *
+createDrawable(const Visual *visual, int width, int height)
+{
+    return new WglDrawable(visual, width, height);
+}
 
+Context *
+createContext(const Visual *visual, Context *shareContext, Profile profile)
+{
+    if (profile != PROFILE_COMPAT) {
+        return NULL;
+    }
+
+    return new WglContext(visual, profile, static_cast<WglContext *>(shareContext));
+}
+
+bool
+makeCurrent(Drawable *drawable, Context *context)
+{
+    if (!drawable || !context) {
+        return wglMakeCurrent(NULL, NULL);
+    } else {
+        WglDrawable *wglDrawable = static_cast<WglDrawable *>(drawable);
+        WglContext *wglContext = static_cast<WglContext *>(context);
+
+        if (!wglContext->hglrc) {
+            wglContext->hglrc = wglCreateContext(wglDrawable->hDC);
             if (!wglContext->hglrc) {
-                wglContext->hglrc = wglCreateContext(wglDrawable->hDC);
-                if (!wglContext->hglrc) {
-                    return false;
-                }
-                if (wglContext->shareContext) {
-                    wglShareLists(wglContext->shareContext->hglrc,
-                                  wglContext->hglrc);
+                std::cerr << "error: wglCreateContext failed\n";
+                exit(1);
+                return false;
+            }
+            if (wglContext->shareContext) {
+                BOOL bRet;
+                bRet = wglShareLists(wglContext->shareContext->hglrc,
+                                     wglContext->hglrc);
+                if (!bRet) {
+                    std::cerr << "warning: wglShareLists failed\n";
                 }
             }
-
-            return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);
         }
-    }
 
-    bool
-    processEvents(void) {
-        // TODO
-        return true;
+        return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);
     }
-};
-
+}
 
-WindowSystem *createNativeWindowSystem(void) {
-    return new WglWindowSystem();
+bool
+processEvents(void) {
+    // TODO
+    return true;
 }
 
 
-} /* namespace glretrace */
+} /* namespace glws */