summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp117
1 files changed, 43 insertions, 74 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 741885e321..476de6d1e5 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -38,9 +38,6 @@
****************************************************************************/
#include <QDebug>
-#if QT_CONFIG(library)
-#include <QLibrary>
-#endif
#include "qxcbwindow.h"
#include "qxcbscreen.h"
@@ -51,6 +48,9 @@
#undef register
#include <GL/glx.h>
+#if QT_CONFIG(regularexpression)
+# include <QtCore/QRegularExpression>
+#endif
#include <QtGui/QOpenGLContext>
#include <QtGui/QOffscreenSurface>
@@ -60,10 +60,6 @@
#include "qxcbglintegration.h"
-#if !defined(QT_STATIC) && QT_CONFIG(dlopen)
-#include <dlfcn.h>
-#endif
-
QT_BEGIN_NAMESPACE
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
@@ -626,43 +622,7 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface)
QFunctionPointer QGLXContext::getProcAddress(const char *procName)
{
-#ifdef QT_STATIC
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName));
-#else
- typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
- static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
- static bool resolved = false;
-
- if (resolved && !glXGetProcAddressARB)
- return 0;
- if (!glXGetProcAddressARB) {
- QList<QByteArray> glxExt = QByteArray(glXGetClientString(m_display, GLX_EXTENSIONS)).split(' ');
- if (glxExt.contains("GLX_ARB_get_proc_address")) {
-#if QT_CONFIG(dlopen)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
- dlclose(handle);
- }
- if (!glXGetProcAddressARB)
-#endif
- {
-#if QT_CONFIG(library)
- extern const QString qt_gl_library_name();
-// QLibrary lib(qt_gl_library_name());
- QLibrary lib(QLatin1String("GL"));
- if (!lib.load())
- lib.setFileNameAndVersion(QLatin1String("GL"), 1);
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
-#endif
- }
- }
- resolved = true;
- }
- if (!glXGetProcAddressARB)
- return 0;
- return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName));
-#endif
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName));
}
QSurfaceFormat QGLXContext::format() const
@@ -692,30 +652,10 @@ static const char *qglx_threadedgl_blacklist_renderer[] = {
0
};
-// This disables threaded rendering on anything using mesa, e.g.
-// - nvidia/nouveau
-// - amd/gallium
-// - intel
-// - some software opengl implementations
-//
-// The client glx vendor string is used to identify those setups as that seems to show the least
-// variance between the bad configurations. It's always "Mesa Project and SGI". There are some
-// configurations which don't use mesa and which can do threaded rendering (amd and nvidia chips
-// with their own proprietary drivers).
-//
-// This, of course, is very broad and disables threaded rendering on a lot of devices which would
-// be able to use it. However, the bugs listed below don't follow any easily recognizable pattern
-// and we should rather be safe.
-//
-// http://cgit.freedesktop.org/xcb/libxcb/commit/?id=be0fe56c3bcad5124dcc6c47a2fad01acd16f71a will
-// fix some of the issues. Basically, the proprietary drivers seem to have a way of working around
-// a fundamental flaw with multithreaded access to xcb, but mesa doesn't. The blacklist should be
-// reevaluated once that patch is released in some version of xcb.
static const char *qglx_threadedgl_blacklist_vendor[] = {
- "Mesa Project and SGI", // QTCREATORBUG-10875 (crash in creator)
- // QTBUG-34492 (flickering in fullscreen)
- // QTBUG-38221
- 0
+ "llvmpipe", // QTCREATORBUG-10666
+ "nouveau", // https://bugs.freedesktop.org/show_bug.cgi?id=91632
+ nullptr
};
void QGLXContext::queryDummyContext()
@@ -776,21 +716,50 @@ void QGLXContext::queryDummyContext()
}
}
}
-
- if (glxvendor) {
+ if (const char *vendor = (const char *) glGetString(GL_VENDOR)) {
for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) {
- if (strstr(glxvendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
+ if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: "
- "blacklisted vendor \""
- << qglx_threadedgl_blacklist_vendor[i]
- << "\"";
-
+ "blacklisted vendor \""
+ << qglx_threadedgl_blacklist_vendor[i]
+ << "\"";
m_supportsThreading = false;
break;
}
}
}
+ if (glxvendor && m_supportsThreading) {
+ // Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator),
+ // QTBUG-34492 (flickering in fullscreen) and QTBUG-38221
+ const char *mesaVersionStr = nullptr;
+ if (strstr(glxvendor, "Mesa Project") != 0) {
+ mesaVersionStr = (const char *) glGetString(GL_VERSION);
+ m_supportsThreading = false;
+ }
+
+ if (mesaVersionStr) {
+ // The issue was fixed in Xcb 1.11, but we can't check for that
+ // at runtime, so instead assume it fixed with recent Mesa versions
+ // released several years after the Xcb fix.
+#if QT_CONFIG(regularexpression)
+ QRegularExpression versionTest(QStringLiteral("Mesa (\\d+)"));
+ QRegularExpressionMatch result = versionTest.match(QString::fromLatin1(mesaVersionStr));
+ int versionNr = 0;
+ if (result.hasMatch())
+ versionNr = result.captured(1).toInt();
+ if (versionNr >= 17) {
+ // White-listed
+ m_supportsThreading = true;
+ }
+#endif
+ }
+ if (!m_supportsThreading) {
+ qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: "
+ "blacklisted vendor \"Mesa Project\"";
+ }
+ }
+
context.doneCurrent();
if (oldContext && oldSurface)
oldContext->makeCurrent(oldSurface);