Bug 675532 - Add GLX debugging mode. r=bjacob
authorMatt Woodrow <mwoodrow@mozilla.com>
Sat, 20 Aug 2011 14:04:24 +1200
changeset 76078 96e052b3e845f99e91bac5783ba94fc029870b80
parent 76077 8f1ad97f4bc2f48a73fc2573bf5f1dee1d168cf0
child 76079 58147380793b71cadae0ed29930b30f4a76e135a
push idunknown
push userunknown
push dateunknown
reviewersbjacob
bugs675532
milestone9.0a1
Bug 675532 - Add GLX debugging mode. r=bjacob
gfx/src/X11Util.h
gfx/thebes/GLContextProviderGLX.cpp
gfx/thebes/GLXLibrary.h
--- a/gfx/src/X11Util.h
+++ b/gfx/src/X11Util.h
@@ -121,27 +121,30 @@ private:
  * ScopedXErrorHandler was in place may then be caught by the other ScopedXErrorHandler. This is just a result of X being
  * asynchronous and us not doing any implicit syncing: the only method in this class what causes syncing is SyncAndGetError().
  *
  * This class is not thread-safe at all. It is assumed that only one thread is using any ScopedXErrorHandler's. Given that it's
  * not used on Mac, it should be easy to make it thread-safe by using thread-local storage with __thread.
  */
 class NS_GFX ScopedXErrorHandler
 {
+public:
     // trivial wrapper around XErrorEvent, just adding ctor initializing by zero.
     struct ErrorEvent
     {
         XErrorEvent mError;
 
         ErrorEvent()
         {
             memset(this, 0, sizeof(ErrorEvent));
         }
     };
 
+private:
+
     // this ScopedXErrorHandler's ErrorEvent object
     ErrorEvent mXError;
 
     // static pointer for use by the error handler
     static ErrorEvent* sXErrorPtr;
 
     // what to restore sXErrorPtr to on destruction
     ErrorEvent* mOldXErrorPtr;
--- a/gfx/thebes/GLContextProviderGLX.cpp
+++ b/gfx/thebes/GLContextProviderGLX.cpp
@@ -107,75 +107,79 @@ GLXLibrary::EnsureInitialized()
         mOGLLibrary = PR_LoadLibrary(libGLfilename);
         if (!mOGLLibrary) {
             NS_WARNING("Couldn't load OpenGL shared library.");
             return PR_FALSE;
         }
         reporter.SetSuccessful();
     }
 
+    if (PR_GetEnv("MOZ_GLX_DEBUG")) {
+        mDebug = PR_TRUE;
+    }
+
     LibrarySymbolLoader::SymLoadStruct symbols[] = {
         /* functions that were in GLX 1.0 */
-        { (PRFuncPtr*) &xDestroyContext, { "glXDestroyContext", NULL } },
-        { (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } },
-        { (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
-        { (PRFuncPtr*) &xQueryVersion, { "glXQueryVersion", NULL } },
-        { (PRFuncPtr*) &xGetCurrentContext, { "glXGetCurrentContext", NULL } },
-        { (PRFuncPtr*) &xWaitGL, { "glXWaitGL", NULL } },
+        { (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", NULL } },
+        { (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", NULL } },
+        { (PRFuncPtr*) &xSwapBuffersInternal, { "glXSwapBuffers", NULL } },
+        { (PRFuncPtr*) &xQueryVersionInternal, { "glXQueryVersion", NULL } },
+        { (PRFuncPtr*) &xGetCurrentContextInternal, { "glXGetCurrentContext", NULL } },
+        { (PRFuncPtr*) &xWaitGLInternal, { "glXWaitGL", NULL } },
         /* functions introduced in GLX 1.1 */
-        { (PRFuncPtr*) &xQueryExtensionsString, { "glXQueryExtensionsString", NULL } },
-        { (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } },
-        { (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } },
+        { (PRFuncPtr*) &xQueryExtensionsStringInternal, { "glXQueryExtensionsString", NULL } },
+        { (PRFuncPtr*) &xGetClientStringInternal, { "glXGetClientString", NULL } },
+        { (PRFuncPtr*) &xQueryServerStringInternal, { "glXQueryServerString", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols13[] = {
         /* functions introduced in GLX 1.3 */
-        { (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } },
-        { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } },
+        { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", NULL } },
+        { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", NULL } },
         // WARNING: xGetFBConfigs not set in symbols13_ext
-        { (PRFuncPtr*) &xGetFBConfigs, { "glXGetFBConfigs", NULL } },
-        { (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
+        { (PRFuncPtr*) &xGetFBConfigsInternal, { "glXGetFBConfigs", NULL } },
+        { (PRFuncPtr*) &xGetVisualFromFBConfigInternal, { "glXGetVisualFromFBConfig", NULL } },
         // WARNING: symbols13_ext sets xCreateGLXPixmapWithConfig instead
-        { (PRFuncPtr*) &xCreatePixmap, { "glXCreatePixmap", NULL } },
-        { (PRFuncPtr*) &xDestroyPixmap, { "glXDestroyPixmap", NULL } },
-        { (PRFuncPtr*) &xCreateNewContext, { "glXCreateNewContext", NULL } },
+        { (PRFuncPtr*) &xCreatePixmapInternal, { "glXCreatePixmap", NULL } },
+        { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyPixmap", NULL } },
+        { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateNewContext", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols13_ext[] = {
         /* extension equivalents for functions introduced in GLX 1.3 */
         // GLX_SGIX_fbconfig extension
-        { (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfigSGIX", NULL } },
-        { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttribSGIX", NULL } },
+        { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", NULL } },
+        { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttribSGIX", NULL } },
         // WARNING: no xGetFBConfigs equivalent in extensions
-        { (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
+        { (PRFuncPtr*) &xGetVisualFromFBConfigInternal, { "glXGetVisualFromFBConfig", NULL } },
         // WARNING: different from symbols13:
-        { (PRFuncPtr*) &xCreateGLXPixmapWithConfig, { "glXCreateGLXPixmapWithConfigSGIX", NULL } },
-        { (PRFuncPtr*) &xDestroyPixmap, { "glXDestroyGLXPixmap", NULL } }, // not from ext
-        { (PRFuncPtr*) &xCreateNewContext, { "glXCreateContextWithConfigSGIX", NULL } },
+        { (PRFuncPtr*) &xCreateGLXPixmapWithConfigInternal, { "glXCreateGLXPixmapWithConfigSGIX", NULL } },
+        { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyGLXPixmap", NULL } }, // not from ext
+        { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateContextWithConfigSGIX", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols14[] = {
         /* functions introduced in GLX 1.4 */
-        { (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddress", NULL } },
+        { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols14_ext[] = {
         /* extension equivalents for functions introduced in GLX 1.4 */
         // GLX_ARB_get_proc_address extension
-        { (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddressARB", NULL } },
+        { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols_texturefrompixmap[] = {
-        { (PRFuncPtr*) &xBindTexImage, { "glXBindTexImageEXT", NULL } },
-        { (PRFuncPtr*) &xReleaseTexImage, { "glXReleaseTexImageEXT", NULL } },
+        { (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", NULL } },
+        { (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", NULL } },
         { NULL, { NULL } }
     };
 
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
@@ -230,17 +234,17 @@ GLXLibrary::EnsureInitialized()
     }
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym14)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
     if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
         LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, 
-                                         (LibrarySymbolLoader::PlatformLookupFunction)xGetProcAddress))
+                                         (LibrarySymbolLoader::PlatformLookupFunction)&xGetProcAddress))
     {
         mHasTextureFromPixmap = PR_TRUE;
     } else {
         NS_WARNING("Texture from pixmap disabled");
     }
 
     gIsATI = serverVendor && DoesVendorStringMatch(serverVendor, "ATI");
     gIsChromium = (serverVendor &&
@@ -336,16 +340,289 @@ GLXLibrary::ReleaseTexImage(GLXPixmap aP
     if (!mHasTextureFromPixmap) {
         return;
     }
 
     Display *display = DefaultXDisplay();
     xReleaseTexImage(display, aPixmap, GLX_FRONT_LEFT_EXT);
 }
 
+#ifdef DEBUG
+
+static int (*sOldErrorHandler)(Display *, XErrorEvent *);
+ScopedXErrorHandler::ErrorEvent sErrorEvent;
+static int GLXErrorHandler(Display *display, XErrorEvent *ev)
+{
+    if (!sErrorEvent.mError.error_code) {
+        sErrorEvent.mError = *ev;
+    }
+    return 0;
+}
+
+void
+GLXLibrary::BeforeGLXCall()
+{
+    if (mDebug) {
+        sOldErrorHandler = XSetErrorHandler(GLXErrorHandler);
+    }
+}
+
+void
+GLXLibrary::AfterGLXCall()
+{
+    XSync(DefaultXDisplay(), False);
+    if (mDebug && sErrorEvent.mError.error_code) {
+        char buffer[2048];
+        XGetErrorText(DefaultXDisplay(), sErrorEvent.mError.error_code, buffer, sizeof(buffer));
+        printf_stderr("X ERROR: %s (%i) - Request: %i.%i, Serial: %i",
+                      buffer,
+                      sErrorEvent.mError.error_code,
+                      sErrorEvent.mError.request_code,
+                      sErrorEvent.mError.minor_code,
+                      sErrorEvent.mError.serial);
+        NS_ABORT();
+    }
+    XSetErrorHandler(sOldErrorHandler);
+}
+
+#define BEFORE_GLX_CALL do {                     \
+    sGLXLibrary.BeforeGLXCall();                 \
+} while (0)
+    
+#define AFTER_GLX_CALL do {                      \
+    sGLXLibrary.AfterGLXCall();                  \
+} while (0)
+
+#else
+
+#define BEFORE_GLX_CALL do { } while(0)
+#define AFTER_GLX_CALL do { } while(0)
+
+#endif
+    
+void 
+GLXLibrary::xDestroyContext(Display* display, GLXContext context)
+{
+    BEFORE_GLX_CALL;
+    xDestroyContextInternal(display, context);
+    AFTER_GLX_CALL;
+}
+
+Bool 
+GLXLibrary::xMakeCurrent(Display* display, 
+                         GLXDrawable drawable, 
+                         GLXContext context)
+{
+    BEFORE_GLX_CALL;
+    Bool result = xMakeCurrentInternal(display, drawable, context);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+GLXContext 
+GLXLibrary::xGetCurrentContext()
+{
+    BEFORE_GLX_CALL;
+    GLXContext result = xGetCurrentContextInternal();
+    AFTER_GLX_CALL;
+    return result;
+}
+
+/* static */ void* 
+GLXLibrary::xGetProcAddress(const char *procName)
+{
+    BEFORE_GLX_CALL;
+    void* result = sGLXLibrary.xGetProcAddressInternal(procName);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+GLXFBConfig*
+GLXLibrary::xChooseFBConfig(Display* display, 
+                            int screen, 
+                            const int *attrib_list, 
+                            int *nelements)
+{
+    BEFORE_GLX_CALL;
+    GLXFBConfig* result = xChooseFBConfigInternal(display, screen, attrib_list, nelements);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+GLXFBConfig* 
+GLXLibrary::xGetFBConfigs(Display* display, 
+                          int screen, 
+                          int *nelements)
+{
+    BEFORE_GLX_CALL;
+    GLXFBConfig* result = xGetFBConfigsInternal(display, screen, nelements);
+    AFTER_GLX_CALL;
+    return result;
+}
+    
+GLXContext
+GLXLibrary::xCreateNewContext(Display* display, 
+                              GLXFBConfig config, 
+                              int render_type, 
+                              GLXContext share_list, 
+                              Bool direct)
+{
+    BEFORE_GLX_CALL;
+    GLXContext result = xCreateNewContextInternal(display, config, 
+	                                              render_type,
+	                                              share_list, direct);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+XVisualInfo*
+GLXLibrary::xGetVisualFromFBConfig(Display* display, 
+                                   GLXFBConfig config)
+{
+    BEFORE_GLX_CALL;
+    XVisualInfo* result = xGetVisualFromFBConfigInternal(display, config);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+int
+GLXLibrary::xGetFBConfigAttrib(Display *display,
+                               GLXFBConfig config,
+                               int attribute,
+                               int *value)
+{
+    BEFORE_GLX_CALL;
+    int result = xGetFBConfigAttribInternal(display, config,
+                                            attribute, value);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+void
+GLXLibrary::xSwapBuffers(Display *display, GLXDrawable drawable)
+{
+    BEFORE_GLX_CALL;
+    xSwapBuffersInternal(display, drawable);
+    AFTER_GLX_CALL;
+}
+
+const char *
+GLXLibrary::xQueryExtensionsString(Display *display,
+                                   int screen)
+{
+    BEFORE_GLX_CALL;
+    const char *result = xQueryExtensionsStringInternal(display, screen);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+const char *
+GLXLibrary::xGetClientString(Display *display,
+                             int screen)
+{
+    BEFORE_GLX_CALL;
+    const char *result = xGetClientStringInternal(display, screen);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+const char *
+GLXLibrary::xQueryServerString(Display *display,
+                               int screen, int name)
+{
+    BEFORE_GLX_CALL;
+    const char *result = xQueryServerStringInternal(display, screen, name);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+GLXPixmap
+GLXLibrary::xCreatePixmap(Display *display, 
+                          GLXFBConfig config,
+                          Pixmap pixmap,
+                          const int *attrib_list)
+{
+    BEFORE_GLX_CALL;
+    GLXPixmap result = xCreatePixmapInternal(display, config,
+                                             pixmap, attrib_list);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+GLXPixmap
+GLXLibrary::xCreateGLXPixmapWithConfig(Display *display,
+                                       GLXFBConfig config,
+                                       Pixmap pixmap)
+{
+    BEFORE_GLX_CALL;
+    GLXPixmap result = xCreateGLXPixmapWithConfigInternal(display, config, pixmap);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+void
+GLXLibrary::xDestroyPixmap(Display *display, GLXPixmap pixmap)
+{
+    BEFORE_GLX_CALL;
+    xDestroyPixmapInternal(display, pixmap);
+    AFTER_GLX_CALL;
+}
+
+GLXContext
+GLXLibrary::xCreateContext(Display *display,
+                           XVisualInfo *vis,
+                           GLXContext shareList,
+                           Bool direct)
+{
+    BEFORE_GLX_CALL;
+    GLXContext result = xCreateContextInternal(display, vis, shareList, direct);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+Bool
+GLXLibrary::xQueryVersion(Display *display,
+                          int *major,
+                          int *minor)
+{
+    BEFORE_GLX_CALL;
+    Bool result = xQueryVersionInternal(display, major, minor);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+void
+GLXLibrary::xBindTexImage(Display *display,
+                          GLXDrawable drawable,
+                          int buffer,
+                          const int *attrib_list)
+{
+    BEFORE_GLX_CALL;
+    xBindTexImageInternal(display, drawable, buffer, attrib_list);
+    AFTER_GLX_CALL;
+}
+
+void
+GLXLibrary::xReleaseTexImage(Display *display,
+                             GLXDrawable drawable,
+                             int buffer)
+{
+    BEFORE_GLX_CALL;
+    xReleaseTexImageInternal(display, drawable, buffer);
+    AFTER_GLX_CALL;
+}
+
+void 
+GLXLibrary::xWaitGL()
+{
+    BEFORE_GLX_CALL;
+    xWaitGLInternal();
+    AFTER_GLX_CALL;
+}
+
 GLXLibrary sGLXLibrary;
 
 class GLContextGLX : public GLContext
 {
 public:
     static already_AddRefed<GLContextGLX>
     CreateGLContext(const ContextFormat& format,
                     Display *display,
@@ -461,17 +738,17 @@ TRY_AGAIN_NO_SHARING:
             NS_ASSERTION(succeeded, "Failed to make GL context current!");
         }
 
         return succeeded;
     }
 
     PRBool SetupLookupFunction()
     {
-        mLookupFunc = (PlatformLookupFunction)sGLXLibrary.xGetProcAddress;
+        mLookupFunc = (PlatformLookupFunction)&GLXLibrary::xGetProcAddress;
         return PR_TRUE;
     }
 
     void *GetNativeData(NativeDataType aType)
     {
         switch(aType) {
         case NativeGLContext:
             return mContext;
@@ -1045,8 +1322,9 @@ GLContextProviderGLX::GetGlobalContext()
 void
 GLContextProviderGLX::Shutdown()
 {
     gGlobalContext = nsnull;
 }
 
 } /* namespace gl */
 } /* namespace mozilla */
+
--- a/gfx/thebes/GLXLibrary.h
+++ b/gfx/thebes/GLXLibrary.h
@@ -44,118 +44,181 @@ typedef realGLboolean GLboolean;
 
 namespace mozilla {
 namespace gl {
 
 class GLXLibrary
 {
 public:
     GLXLibrary() : mInitialized(PR_FALSE), mTriedInitializing(PR_FALSE),
-                   mHasTextureFromPixmap(PR_FALSE), mOGLLibrary(nsnull) {}
-
-    typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
-                                                          GLXContext);
-    PFNGLXDESTROYCONTEXTPROC xDestroyContext;
-    typedef Bool (GLAPIENTRY * PFNGLXMAKECURRENTPROC) (Display*,
-                                                       GLXDrawable,
-                                                       GLXContext);
-    PFNGLXMAKECURRENTPROC xMakeCurrent;
-    typedef GLXContext (GLAPIENTRY * PFNGLXGETCURRENTCONTEXT) ();
-    PFNGLXGETCURRENTCONTEXT xGetCurrentContext;
-    typedef void* (GLAPIENTRY * PFNGLXGETPROCADDRESSPROC) (const char *);
-    PFNGLXGETPROCADDRESSPROC xGetProcAddress;
-    typedef GLXFBConfig* (GLAPIENTRY * PFNGLXCHOOSEFBCONFIG) (Display *,
-                                                              int,
-                                                              const int *,
-                                                              int *);
-    PFNGLXCHOOSEFBCONFIG xChooseFBConfig;
-    typedef GLXFBConfig* (GLAPIENTRY * PFNGLXGETFBCONFIGS) (Display *,
-                                                            int,
-                                                            int *);
-    PFNGLXGETFBCONFIGS xGetFBConfigs;
-    typedef GLXContext (GLAPIENTRY * PFNGLXCREATENEWCONTEXT) (Display *,
-                                                              GLXFBConfig,
-                                                              int,
-                                                              GLXContext,
-                                                              Bool);
-    PFNGLXCREATENEWCONTEXT xCreateNewContext;
-    typedef XVisualInfo* (GLAPIENTRY * PFNGLXGETVISUALFROMFBCONFIG) (Display *,
-                                                                     GLXFBConfig);
-    PFNGLXGETVISUALFROMFBCONFIG xGetVisualFromFBConfig;
-    typedef int (GLAPIENTRY * PFNGLXGETFBCONFIGATTRIB) (Display *, 
-                                                        GLXFBConfig,
-                                                        int,
-                                                        int *);
-    PFNGLXGETFBCONFIGATTRIB xGetFBConfigAttrib;
+                   mHasTextureFromPixmap(PR_FALSE), mDebug(PR_FALSE),
+                   mOGLLibrary(nsnull) {}
 
-    typedef void (GLAPIENTRY * PFNGLXSWAPBUFFERS) (Display *,
-                                                   GLXDrawable);
-    PFNGLXSWAPBUFFERS xSwapBuffers;
-    typedef const char * (GLAPIENTRY * PFNGLXQUERYEXTENSIONSSTRING) (Display *,
-                                                                     int);
-    PFNGLXQUERYEXTENSIONSSTRING xQueryExtensionsString;
-    typedef const char * (GLAPIENTRY * PFNGLXGETCLIENTSTRING) (Display *,
-                                                               int);
-    PFNGLXGETCLIENTSTRING xGetClientString;
-    typedef const char * (GLAPIENTRY * PFNGLXQUERYSERVERSTRING) (Display *,
-                                                                 int,
-                                                                 int);
-    PFNGLXQUERYSERVERSTRING xQueryServerString;
-
-    typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEPIXMAP) (Display *,
-                                                         GLXFBConfig,
-                                                         Pixmap,
-                                                         const int *);
-    PFNGLXCREATEPIXMAP xCreatePixmap;
-    typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEGLXPIXMAPWITHCONFIG)
-                                                        (Display *,
-                                                         GLXFBConfig,
-                                                         Pixmap);
-    PFNGLXCREATEGLXPIXMAPWITHCONFIG xCreateGLXPixmapWithConfig;
-    typedef void (GLAPIENTRY * PFNGLXDESTROYPIXMAP) (Display *,
-                                                     GLXPixmap);
-    PFNGLXDESTROYPIXMAP xDestroyPixmap;
-    typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXT) (Display *,
-                                                           XVisualInfo *,
-                                                           GLXContext,
-                                                           Bool);
-    PFNGLXCREATECONTEXT xCreateContext;
-    typedef Bool (GLAPIENTRY * PFNGLXQUERYVERSION) (Display *,
-                                                    int *,
-                                                    int *);
-    PFNGLXQUERYVERSION xQueryVersion;
-
-    typedef void (GLAPIENTRY * PFNGLXBINDTEXIMAGE) (Display *,
-                                                    GLXDrawable,
-                                                    int,
-                                                    const int *);
-    PFNGLXBINDTEXIMAGE xBindTexImage;
-
-    typedef void (GLAPIENTRY * PFNGLXRELEASETEXIMAGE) (Display *,
-                                                       GLXDrawable,
-                                                       int);
-    PFNGLXRELEASETEXIMAGE xReleaseTexImage;
-
-    typedef void (GLAPIENTRY * PFNGLXWAITGL) ();
-    PFNGLXWAITGL xWaitGL;
+    void xDestroyContext(Display* display, GLXContext context);
+    Bool xMakeCurrent(Display* display, 
+                      GLXDrawable drawable, 
+                      GLXContext context);
+    GLXContext xGetCurrentContext();
+    static void* xGetProcAddress(const char *procName);
+    GLXFBConfig* xChooseFBConfig(Display* display, 
+                                 int screen, 
+                                 const int *attrib_list, 
+                                 int *nelements);
+    GLXFBConfig* xGetFBConfigs(Display* display, 
+                               int screen, 
+                               int *nelements);
+    GLXContext xCreateNewContext(Display* display, 
+                                 GLXFBConfig config, 
+                                 int render_type, 
+                                 GLXContext share_list, 
+                                 Bool direct);
+    XVisualInfo* xGetVisualFromFBConfig(Display* display, 
+                                        GLXFBConfig config);
+    int xGetFBConfigAttrib(Display *display,
+                           GLXFBConfig config,
+                           int attribute,
+                           int *value);
+    void xSwapBuffers(Display *display, GLXDrawable drawable);
+    const char * xQueryExtensionsString(Display *display,
+                                        int screen);
+    const char * xGetClientString(Display *display,
+                                  int screen);
+    const char * xQueryServerString(Display *display,
+                                    int screen, int name);
+    GLXPixmap xCreatePixmap(Display *display, 
+                            GLXFBConfig config,
+                            Pixmap pixmap,
+                            const int *attrib_list);
+    GLXPixmap xCreateGLXPixmapWithConfig(Display *display,
+                                         GLXFBConfig config,
+                                         Pixmap pixmap);
+    void xDestroyPixmap(Display *display, GLXPixmap pixmap);
+    GLXContext xCreateContext(Display *display,
+                              XVisualInfo *vis,
+                              GLXContext shareList,
+                              Bool direct);
+    Bool xQueryVersion(Display *display,
+                       int *major,
+                       int *minor);
+    void xBindTexImage(Display *display,
+                       GLXDrawable drawable,
+                       int buffer,
+                       const int *attrib_list);
+    void xReleaseTexImage(Display *display,
+                          GLXDrawable drawable,
+                          int buffer);
+    void xWaitGL();
 
     PRBool EnsureInitialized();
 
     GLXPixmap CreatePixmap(gfxASurface* aSurface);
     void DestroyPixmap(GLXPixmap aPixmap);
     void BindTexImage(GLXPixmap aPixmap);
     void ReleaseTexImage(GLXPixmap aPixmap);
 
     PRBool HasTextureFromPixmap() { return mHasTextureFromPixmap; }
     PRBool SupportsTextureFromPixmap(gfxASurface* aSurface);
 
 private:
+    
+    typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
+                                                          GLXContext);
+    PFNGLXDESTROYCONTEXTPROC xDestroyContextInternal;
+    typedef Bool (GLAPIENTRY * PFNGLXMAKECURRENTPROC) (Display*,
+                                                       GLXDrawable,
+                                                       GLXContext);
+    PFNGLXMAKECURRENTPROC xMakeCurrentInternal;
+    typedef GLXContext (GLAPIENTRY * PFNGLXGETCURRENTCONTEXT) ();
+    PFNGLXGETCURRENTCONTEXT xGetCurrentContextInternal;
+    typedef void* (GLAPIENTRY * PFNGLXGETPROCADDRESSPROC) (const char *);
+    PFNGLXGETPROCADDRESSPROC xGetProcAddressInternal;
+    typedef GLXFBConfig* (GLAPIENTRY * PFNGLXCHOOSEFBCONFIG) (Display *,
+                                                              int,
+                                                              const int *,
+                                                              int *);
+    PFNGLXCHOOSEFBCONFIG xChooseFBConfigInternal;
+    typedef GLXFBConfig* (GLAPIENTRY * PFNGLXGETFBCONFIGS) (Display *,
+                                                            int,
+                                                            int *);
+    PFNGLXGETFBCONFIGS xGetFBConfigsInternal;
+    typedef GLXContext (GLAPIENTRY * PFNGLXCREATENEWCONTEXT) (Display *,
+                                                              GLXFBConfig,
+                                                              int,
+                                                              GLXContext,
+                                                              Bool);
+    PFNGLXCREATENEWCONTEXT xCreateNewContextInternal;
+    typedef XVisualInfo* (GLAPIENTRY * PFNGLXGETVISUALFROMFBCONFIG) (Display *,
+                                                                     GLXFBConfig);
+    PFNGLXGETVISUALFROMFBCONFIG xGetVisualFromFBConfigInternal;
+    typedef int (GLAPIENTRY * PFNGLXGETFBCONFIGATTRIB) (Display *, 
+                                                        GLXFBConfig,
+                                                        int,
+                                                        int *);
+    PFNGLXGETFBCONFIGATTRIB xGetFBConfigAttribInternal;
+
+    typedef void (GLAPIENTRY * PFNGLXSWAPBUFFERS) (Display *,
+                                                   GLXDrawable);
+    PFNGLXSWAPBUFFERS xSwapBuffersInternal;
+    typedef const char * (GLAPIENTRY * PFNGLXQUERYEXTENSIONSSTRING) (Display *,
+                                                                     int);
+    PFNGLXQUERYEXTENSIONSSTRING xQueryExtensionsStringInternal;
+    typedef const char * (GLAPIENTRY * PFNGLXGETCLIENTSTRING) (Display *,
+                                                               int);
+    PFNGLXGETCLIENTSTRING xGetClientStringInternal;
+    typedef const char * (GLAPIENTRY * PFNGLXQUERYSERVERSTRING) (Display *,
+                                                                 int,
+                                                                 int);
+    PFNGLXQUERYSERVERSTRING xQueryServerStringInternal;
+
+    typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEPIXMAP) (Display *,
+                                                         GLXFBConfig,
+                                                         Pixmap,
+                                                         const int *);
+    PFNGLXCREATEPIXMAP xCreatePixmapInternal;
+    typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEGLXPIXMAPWITHCONFIG)
+                                                        (Display *,
+                                                         GLXFBConfig,
+                                                         Pixmap);
+    PFNGLXCREATEGLXPIXMAPWITHCONFIG xCreateGLXPixmapWithConfigInternal;
+    typedef void (GLAPIENTRY * PFNGLXDESTROYPIXMAP) (Display *,
+                                                     GLXPixmap);
+    PFNGLXDESTROYPIXMAP xDestroyPixmapInternal;
+    typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXT) (Display *,
+                                                           XVisualInfo *,
+                                                           GLXContext,
+                                                           Bool);
+    PFNGLXCREATECONTEXT xCreateContextInternal;
+    typedef Bool (GLAPIENTRY * PFNGLXQUERYVERSION) (Display *,
+                                                    int *,
+                                                    int *);
+    PFNGLXQUERYVERSION xQueryVersionInternal;
+
+    typedef void (GLAPIENTRY * PFNGLXBINDTEXIMAGE) (Display *,
+                                                    GLXDrawable,
+                                                    int,
+                                                    const int *);
+    PFNGLXBINDTEXIMAGE xBindTexImageInternal;
+
+    typedef void (GLAPIENTRY * PFNGLXRELEASETEXIMAGE) (Display *,
+                                                       GLXDrawable,
+                                                       int);
+    PFNGLXRELEASETEXIMAGE xReleaseTexImageInternal;
+
+    typedef void (GLAPIENTRY * PFNGLXWAITGL) ();
+    PFNGLXWAITGL xWaitGLInternal;
+
+#ifdef DEBUG
+    void BeforeGLXCall();
+    void AfterGLXCall();
+#endif
+
     PRBool mInitialized;
     PRBool mTriedInitializing;
     PRBool mHasTextureFromPixmap;
+    PRBool mDebug;
     PRLibrary *mOGLLibrary;
 };
 
 // a global GLXLibrary instance
 extern GLXLibrary sGLXLibrary;
 
 } /* namespace gl */
 } /* namespace mozilla */