From dad31edd2d5be5a2902f6b011910f418882c9367 Mon Sep 17 00:00:00 2001 From: Tom Cooksey <thomas.cooksey@nokia.com> Date: Sun, 23 Aug 2009 12:08:20 +0200 Subject: Use glXGetProcAddress to resolve glx extensions On systems where the GL driver is pluggable (like Mesa), we have to use the glXGetProcAddressARB extension to resolve other function pointers as the symbols wont be in the GL library, but rather in a plugin loaded by the GL library. This fix basically makes texture-from-pixmap work on Mesa drivers like intel i915 & friends. Reviewed-by: Trond --- src/opengl/qgl_x11.cpp | 92 +++++++++++++++++++++++++-------------- src/opengl/qglpixelbuffer_x11.cpp | 33 ++++---------- 2 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index da7972d..86e593d 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -331,6 +331,62 @@ static void find_trans_colors() QGLFormat UNIX/GLX-specific code *****************************************************************************/ +void* qglx_getProcAddress(const char* procName) +{ + // On systems where the GL driver is pluggable (like Mesa), we have to use + // the glXGetProcAddressARB extension to resolve other function pointers as + // the symbols wont be in the GL library, but rather in a plugin loaded by + // the GL library. + typedef void* (*qt_glXGetProcAddressARB)(const char *); + static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; + static bool triedResolvingGlxGetProcAddress = false; + if (!triedResolvingGlxGetProcAddress) { + triedResolvingGlxGetProcAddress = true; + QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); + if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) { +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) + void *handle = dlopen(NULL, RTLD_LAZY); + if (handle) { + glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); + dlclose(handle); + } + if (!glXGetProcAddressARB) +#endif + { +#if !defined(QT_NO_LIBRARY) + extern const QString qt_gl_library_name(); + QLibrary lib(qt_gl_library_name()); + glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); +#endif + } + } + } + + void *procAddress = 0; + if (glXGetProcAddressARB) + procAddress = glXGetProcAddressARB(procName); + + // If glXGetProcAddress didn't work, try looking the symbol up in the GL library +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) + if (!procAddress) { + void *handle = dlopen(NULL, RTLD_LAZY); + if (handle) { + procAddress = dlsym(handle, procName); + dlclose(handle); + } + } +#endif +#if !defined(QT_NO_LIBRARY) + if (!procAddress) { + extern const QString qt_gl_library_name(); + QLibrary lib(qt_gl_library_name()); + procAddress = lib.resolve(procName); + } +#endif + + return procAddress; +} + bool QGLFormat::hasOpenGL() { return glXQueryExtension(X11->display, 0, 0) != 0; @@ -819,23 +875,8 @@ void QGLContext::swapBuffers() const if (!resolved) { QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI"); - glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI"); - dlclose(handle); - } - if (!glXGetVideoSyncSGI) -#endif - { -#if !defined(QT_NO_LIBRARY) - extern const QString qt_gl_library_name(); - QLibrary lib(qt_gl_library_name()); - glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI"); - glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI"); -#endif - } + glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI"); + glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI"); } resolved = true; } @@ -1568,21 +1609,8 @@ bool qt_resolveTextureFromPixmap() QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) { -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - glXBindTexImageEXT = (qt_glXBindTexImageEXT) dlsym(handle, "glXBindTexImageEXT"); - glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) dlsym(handle, "glXReleaseTexImageEXT"); - dlclose(handle); - } - if (!glXBindTexImageEXT) -#endif - { - extern const QString qt_gl_library_name(); - QLibrary lib(qt_gl_library_name()); - glXBindTexImageEXT = (qt_glXBindTexImageEXT) lib.resolve("glXBindTexImageEXT"); - glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) lib.resolve("glXReleaseTexImageEXT"); - } + glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); + glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); } } diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp index 793471d..6971133 100644 --- a/src/opengl/qglpixelbuffer_x11.cpp +++ b/src/opengl/qglpixelbuffer_x11.cpp @@ -93,6 +93,8 @@ static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0; #define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib #define glXMakeContextCurrent qt_glXMakeContextCurrent +extern void* qglx_getProcAddress(const char* procName); // in qgl_x11.cpp + static bool qt_resolve_pbuffer_extensions() { static int resolved = false; @@ -101,31 +103,12 @@ static bool qt_resolve_pbuffer_extensions() else if (resolved) return false; -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - qt_glXChooseFBConfig = (_glXChooseFBConfig) dlsym(handle, "glXChooseFBConfig"); - qt_glXCreateNewContext = (_glXCreateNewContext) dlsym(handle, "glXCreateNewContext"); - qt_glXCreatePbuffer = (_glXCreatePbuffer) dlsym(handle, "glXCreatePbuffer"); - qt_glXDestroyPbuffer = (_glXDestroyPbuffer) dlsym(handle, "glXDestroyPbuffer"); - qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) dlsym(handle, "glXGetFBConfigAttrib"); - qt_glXMakeContextCurrent = (_glXMakeContextCurrent) dlsym(handle, "glXMakeContextCurrent"); - dlclose(handle); - } - if (!qt_glXChooseFBConfig) -#endif - { -#if !defined(QT_NO_LIBRARY) - extern const QString qt_gl_library_name(); - QLibrary gl(qt_gl_library_name()); - qt_glXChooseFBConfig = (_glXChooseFBConfig) gl.resolve("glXChooseFBConfig"); - qt_glXCreateNewContext = (_glXCreateNewContext) gl.resolve("glXCreateNewContext"); - qt_glXCreatePbuffer = (_glXCreatePbuffer) gl.resolve("glXCreatePbuffer"); - qt_glXDestroyPbuffer = (_glXDestroyPbuffer) gl.resolve("glXDestroyPbuffer"); - qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) gl.resolve("glXGetFBConfigAttrib"); - qt_glXMakeContextCurrent = (_glXMakeContextCurrent) gl.resolve("glXMakeContextCurrent"); -#endif - } + qt_glXChooseFBConfig = (_glXChooseFBConfig) qglx_getProcAddress("glXChooseFBConfig"); + qt_glXCreateNewContext = (_glXCreateNewContext) qglx_getProcAddress("glXCreateNewContext"); + qt_glXCreatePbuffer = (_glXCreatePbuffer) qglx_getProcAddress("glXCreatePbuffer"); + qt_glXDestroyPbuffer = (_glXDestroyPbuffer) qglx_getProcAddress("glXDestroyPbuffer"); + qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) qglx_getProcAddress("glXGetFBConfigAttrib"); + qt_glXMakeContextCurrent = (_glXMakeContextCurrent) qglx_getProcAddress("glXMakeContextCurrent"); resolved = qt_glXMakeContextCurrent ? true : false; return resolved; -- cgit v0.12