summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qopenglcontext.cpp10
-rw-r--r--src/gui/kernel/qplatformopenglcontext.cpp10
-rw-r--r--src/gui/kernel/qplatformopenglcontext.h2
-rw-r--r--src/opengl/qgl.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp17
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp262
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h15
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp27
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h13
10 files changed, 300 insertions, 68 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 3106b4cd91..6c006ab8b3 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -297,10 +297,18 @@ void QOpenGLContext::setScreen(QScreen *screen)
The current configuration includes the format, the share context, and the
screen.
+ If the OpenGL implementation on your system does not support the requested
+ version of OpenGL context, then QOpenGLContext will try to create the closest
+ matching version. The actual created context properties can be queried
+ using the QSurfaceFormat returned by the format() function. For example, if
+ you request a context that supports OpenGL 4.3 Core profile but the driver
+ and/or hardware only supports version 3.2 Core profile contexts then you will
+ get a 3.2 Core profile context.
+
Returns true if the native context was successfully created and is ready to
be used with makeCurrent(), swapBuffers(), etc.
- \sa makeCurrent(), destroy()
+ \sa makeCurrent(), destroy(), format()
*/
bool QOpenGLContext::create()
{
diff --git a/src/gui/kernel/qplatformopenglcontext.cpp b/src/gui/kernel/qplatformopenglcontext.cpp
index 8e6a9da562..f2d6f6199c 100644
--- a/src/gui/kernel/qplatformopenglcontext.cpp
+++ b/src/gui/kernel/qplatformopenglcontext.cpp
@@ -118,14 +118,14 @@ void QPlatformOpenGLContext::setContext(QOpenGLContext *context)
d->context = context;
}
-bool QPlatformOpenGLContext::parseOpenGLVersion(const QString& versionString, int &major, int &minor)
+bool QPlatformOpenGLContext::parseOpenGLVersion(const QByteArray &versionString, int &major, int &minor)
{
bool majorOk = false;
bool minorOk = false;
- QStringList parts = versionString.split(QLatin1Char(' '));
- if (versionString.startsWith(QLatin1String("OpenGL ES"))) {
+ QList<QByteArray> parts = versionString.split(' ');
+ if (versionString.startsWith(QByteArrayLiteral("OpenGL ES"))) {
if (parts.size() >= 3) {
- QStringList versionParts = parts.at(2).split(QLatin1Char('.'));
+ QList<QByteArray> versionParts = parts.at(2).split('.');
if (versionParts.size() >= 2) {
major = versionParts.at(0).toInt(&majorOk);
minor = versionParts.at(1).toInt(&minorOk);
@@ -138,7 +138,7 @@ bool QPlatformOpenGLContext::parseOpenGLVersion(const QString& versionString, in
}
} else {
// Not OpenGL ES, but regular OpenGL, the version numbers are first in the string
- QStringList versionParts = parts.at(0).split(QLatin1Char('.'));
+ QList<QByteArray> versionParts = parts.at(0).split('.');
if (versionParts.size() >= 2) {
major = versionParts.at(0).toInt(&majorOk);
minor = versionParts.at(1).toInt(&minorOk);
diff --git a/src/gui/kernel/qplatformopenglcontext.h b/src/gui/kernel/qplatformopenglcontext.h
index bed83b0913..e64dad64c2 100644
--- a/src/gui/kernel/qplatformopenglcontext.h
+++ b/src/gui/kernel/qplatformopenglcontext.h
@@ -88,7 +88,7 @@ public:
QOpenGLContext *context() const;
- static bool parseOpenGLVersion(const QString& versionString, int &major, int &minor);
+ static bool parseOpenGLVersion(const QByteArray &versionString, int &major, int &minor);
private:
friend class QOpenGLContext;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 147a823431..9b456f6a64 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -3002,6 +3002,14 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
specified in the constructor; otherwise returns false (i.e. the
context is invalid).
+ If the OpenGL implementation on your system does not support the requested
+ version of OpenGL context, then QGLContext will try to create the closest
+ matching version. The actual created context properties can be queried
+ using the QGLFormat returned by the format() function. For example, if
+ you request a context that supports OpenGL 4.3 Core profile but the driver
+ and/or hardware only supports version 3.2 Core profile contexts then you will
+ get a 3.2 Core profile context.
+
After successful creation, format() returns the set of features of
the created GL rendering context.
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 45e344416d..1c9a7d36f5 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -562,12 +562,21 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
int attributes[attribSize];
int attribIndex = 0;
qFill(attributes, attributes + attribSize, int(0));
- const int requestedVersion = (format.majorVersion() << 8) + format.minorVersion();
+
+ // We limit the requested version by the version of the static context as
+ // wglCreateContextAttribsARB fails and returns NULL if the requested context
+ // version is not supported. This means that we will get the closest supported
+ // context format that that which was requested and is supported by the driver
+ const int requestedVersion = qMin((format.majorVersion() << 8) + format.minorVersion(),
+ staticContext.defaultFormat.version);
+ const int majorVersion = requestedVersion >> 8;
+ const int minorVersion = requestedVersion & 0xFF;
+
if (requestedVersion > 0x0101) {
attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
- attributes[attribIndex++] = format.majorVersion();
+ attributes[attribIndex++] = majorVersion;
attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
- attributes[attribIndex++] = format.minorVersion();
+ attributes[attribIndex++] = minorVersion;
}
if (requestedVersion >= 0x0300) {
attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
@@ -594,7 +603,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
}
if (QWindowsContext::verboseGL)
qDebug("%s: Creating context version %d.%d with %d attributes",
- __FUNCTION__, format.majorVersion(), format.minorVersion(), attribIndex / 2);
+ __FUNCTION__, majorVersion, minorVersion, attribIndex / 2);
const HGLRC result =
staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index 089bca8a63..8c300d6c19 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -74,7 +74,197 @@ typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXC
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#endif
-QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+static Window createDummyWindow(QXcbScreen *screen, XVisualInfo *visualInfo)
+{
+ Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(screen), screen->root(), visualInfo->visual, AllocNone);
+ XSetWindowAttributes a;
+ a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
+ a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
+ a.colormap = cmap;
+
+ Window window = XCreateWindow(DISPLAY_FROM_XCB(screen), screen->root(),
+ 0, 0, 100, 100,
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a);
+ return window;
+}
+
+static Window createDummyWindow(QXcbScreen *screen, GLXFBConfig config)
+{
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config);
+ if (!visualInfo)
+ qFatal("Could not initialize GLX");
+ Window window = createDummyWindow(screen, visualInfo);
+ XFree(visualInfo);
+ return window;
+}
+
+// Per-window data for active OpenGL contexts.
+struct QOpenGLContextData
+{
+ QOpenGLContextData(Display *display, Window window, GLXContext context)
+ : m_display(display),
+ m_window(window),
+ m_context(context)
+ {}
+
+ QOpenGLContextData()
+ : m_display(0),
+ m_window(0),
+ m_context(0)
+ {}
+
+ Display *m_display;
+ Window m_window;
+ GLXContext m_context;
+};
+
+static inline QOpenGLContextData currentOpenGLContextData()
+{
+ QOpenGLContextData result;
+ result.m_display = glXGetCurrentDisplay();
+ result.m_window = glXGetCurrentDrawable();
+ result.m_context = glXGetCurrentContext();
+ return result;
+}
+
+static inline QOpenGLContextData createDummyWindowOpenGLContextData(QXcbScreen *screen)
+{
+ QOpenGLContextData result;
+ result.m_display = DISPLAY_FROM_XCB(screen);
+
+ QSurfaceFormat format;
+ GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen), screen->screenNumber(), format);
+ if (config) {
+ result.m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, true);
+ result.m_window = createDummyWindow(screen, config);
+ } else {
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &format);
+ if (!visualInfo)
+ qFatal("Could not initialize GLX");
+ result.m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, 0, true);
+ result.m_window = createDummyWindow(screen, visualInfo);
+ XFree(visualInfo);
+ }
+
+ return result;
+}
+
+static inline QByteArray getGlString(GLenum param)
+{
+ if (const GLubyte *s = glGetString(param))
+ return QByteArray(reinterpret_cast<const char*>(s));
+ return QByteArray();
+}
+
+static void updateFormatFromContext(QSurfaceFormat &format)
+{
+ // Update the version, profile, and context bit of the format
+ int major = 0, minor = 0;
+ QByteArray versionString(getGlString(GL_VERSION));
+ if (QPlatformOpenGLContext::parseOpenGLVersion(versionString, major, minor)) {
+ format.setMajorVersion(major);
+ format.setMinorVersion(minor);
+ }
+
+ const int version = (major << 8) + minor;
+ if (version < 0x0300) {
+ format.setProfile(QSurfaceFormat::NoProfile);
+ format.setOption(QSurfaceFormat::DeprecatedFunctions);
+ return;
+ }
+
+ // Version 3.0 onwards - check if it includes deprecated functionality or is
+ // a debug context
+ GLint value = 0;
+ glGetIntegerv(GL_CONTEXT_FLAGS, &value);
+ if (value & ~GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
+ format.setOption(QSurfaceFormat::DeprecatedFunctions);
+ if (value & GLX_CONTEXT_DEBUG_BIT_ARB)
+ format.setOption(QSurfaceFormat::DebugContext);
+ if (version < 0x0302)
+ return;
+
+ // Version 3.2 and newer have a profile
+ value = 0;
+ glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ switch (value) {
+ case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ break;
+ case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ format.setProfile(QSurfaceFormat::CompatibilityProfile);
+ break;
+ default:
+ format.setProfile(QSurfaceFormat::NoProfile);
+ break;
+ }
+}
+
+/*!
+ \class QOpenGLTemporaryContext
+ \brief A temporary context that can be instantiated on the stack.
+
+ Functions like glGetString() only work if there is a current GL context.
+
+ \internal
+ \ingroup qt-lighthouse-xcb
+*/
+class QOpenGLTemporaryContext
+{
+ Q_DISABLE_COPY(QOpenGLTemporaryContext)
+public:
+ QOpenGLTemporaryContext(QXcbScreen *screen);
+ ~QOpenGLTemporaryContext();
+
+private:
+ const QOpenGLContextData m_previous;
+ const QOpenGLContextData m_current;
+};
+
+QOpenGLTemporaryContext::QOpenGLTemporaryContext(QXcbScreen *screen)
+ : m_previous(currentOpenGLContextData()),
+ m_current(createDummyWindowOpenGLContextData(screen))
+{
+ // Make our temporary context current on our temporary window
+ glXMakeCurrent(m_current.m_display, m_current.m_window, m_current.m_context);
+}
+
+QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
+{
+ // Restore the previous context if possible, otherwise just release our temporary context
+ if (m_previous.m_display)
+ glXMakeCurrent(m_previous.m_display, m_previous.m_window, m_previous.m_context);
+ else
+ glXMakeCurrent(m_current.m_display, 0, 0);
+
+ // Destroy our temporary window
+ XDestroyWindow(m_current.m_display, m_current.m_window);
+
+ // Finally destroy our temporary context itself
+ glXDestroyContext(m_current.m_display, m_current.m_context);
+}
+
+QOpenGLDefaultContextInfo::QOpenGLDefaultContextInfo()
+ : vendor(getGlString(GL_VENDOR)),
+ renderer(getGlString(GL_RENDERER))
+{
+ updateFormatFromContext(format);
+}
+
+QOpenGLDefaultContextInfo *QOpenGLDefaultContextInfo::create(QXcbScreen *screen)
+{
+ // We need a current context for getGLString() to work. To have
+ // the QOpenGLDefaultContextInfo contain the latest supported
+ // context version, we rely upon the QOpenGLTemporaryContext to
+ // correctly obtain a context with the latest version
+ QScopedPointer<QOpenGLTemporaryContext> temporaryContext(new QOpenGLTemporaryContext(screen));
+ QOpenGLDefaultContextInfo *result = new QOpenGLDefaultContextInfo;
+ return result;
+}
+
+
+QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share, QOpenGLDefaultContextInfo *defaultContextInfo)
: QPlatformOpenGLContext()
, m_screen(screen)
, m_context(0)
@@ -95,10 +285,20 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
// Use glXCreateContextAttribsARB if is available
if (glXCreateContextAttribsARB != 0) {
+ // We limit the requested version by the version of the static context as
+ // glXCreateContextAttribsARB fails and returns NULL if the requested context
+ // version is not supported. This means that we will get the closest supported
+ // context format that that which was requested and is supported by the driver
+ const int maxSupportedVersion = (defaultContextInfo->format.majorVersion() << 8)
+ + defaultContextInfo->format.minorVersion();
+ const int requestedVersion = qMin((format.majorVersion() << 8) + format.minorVersion(),
+ maxSupportedVersion);
+ const int majorVersion = requestedVersion >> 8;
+ const int minorVersion = requestedVersion & 0xFF;
QVector<int> contextAttributes;
- contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << m_format.majorVersion()
- << GLX_CONTEXT_MINOR_VERSION_ARB << m_format.minorVersion();
+ contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << majorVersion
+ << GLX_CONTEXT_MINOR_VERSION_ARB << minorVersion;
// If asking for OpenGL 3.2 or newer we should also specify a profile
if (m_format.majorVersion() > 3 || (m_format.majorVersion() == 3 && m_format.minorVersion() > 1)) {
@@ -136,10 +336,8 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
if (m_context)
m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
- // Used for creating the temporary window
- visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config);
- if (!visualInfo)
- qFatal("Could not initialize GLX");
+ // Create a temporary window so that we can make the new context current
+ window = createDummyWindow(screen, config);
} else {
// Note that m_format gets updated with the used surface format
visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &m_format);
@@ -151,56 +349,16 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
m_shareContext = 0;
m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, 0, true);
}
- }
-
- // Create a temporary window so that we can make the new context current
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(screen), screen->root(), visualInfo->visual, AllocNone);
- XSetWindowAttributes a;
- a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
- a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
- a.colormap = cmap;
- window = XCreateWindow(DISPLAY_FROM_XCB(screen), screen->root(),
- 0, 0, 100, 100,
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- XFree(visualInfo);
+ // Create a temporary window so that we can make the new context current
+ window = createDummyWindow(screen, visualInfo);
+ XFree(visualInfo);
+ }
// Query the OpenGL version and profile
if (m_context && window) {
glXMakeCurrent(DISPLAY_FROM_XCB(screen), window, m_context);
-
- int major = 0, minor = 0;
- QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
- if (parseOpenGLVersion(versionString, major, minor)) {
- m_format.setMajorVersion(major);
- m_format.setMinorVersion(minor);
- }
-
- // If we have OpenGL 3.2 or newer we also need to query the profile in use
- if (m_format.majorVersion() > 3 || (m_format.majorVersion() == 3 && m_format.minorVersion() > 1)) {
- // nVidia drivers have a bug where querying GL_CONTEXT_PROFILE_MASK always returns 0.
- // In this case let's assume that we got the profile that we asked for since nvidia implements
- // both Core and Compatibility profiles
- if (versionString.contains(QStringLiteral("NVIDIA"))) {
- m_format.setProfile(format.profile());
- } else {
- GLint profileMask;
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask);
- switch (profileMask) {
- case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
- m_format.setProfile(QSurfaceFormat::CoreProfile);
- break;
-
- case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
- default:
- m_format.setProfile(QSurfaceFormat::CompatibilityProfile);
- }
- }
- } else {
- m_format.setProfile(QSurfaceFormat::NoProfile);
- }
+ updateFormatFromContext(m_format);
// Make our context non-current
glXMakeCurrent(DISPLAY_FROM_XCB(screen), 0, 0);
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index f8afb2db77..b8285c965a 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -54,10 +54,23 @@
QT_BEGIN_NAMESPACE
+class QOpenGLDefaultContextInfo
+{
+ Q_DISABLE_COPY(QOpenGLDefaultContextInfo)
+ QOpenGLDefaultContextInfo();
+public:
+ static QOpenGLDefaultContextInfo *create(QXcbScreen *screen);
+
+ const QByteArray vendor;
+ const QByteArray renderer;
+ QSurfaceFormat format;
+};
+
+
class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+ QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share, QOpenGLDefaultContextInfo *defaultContextInfo);
~QGLXContext();
bool makeCurrent(QPlatformSurface *surface);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 76534cf5c4..401739f7d5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -224,11 +224,13 @@ void QXcbConnection::updateScreens()
// Now activeScreens is the complete set of screens which are active at this time.
// Delete any existing screens which are not in activeScreens
- for (int i = m_screens.count() - 1; i >= 0; --i)
+ for (int i = m_screens.count() - 1; i >= 0; --i) {
if (!activeScreens.contains(m_screens[i])) {
+ ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->removeDefaultOpenGLContextInfo(m_screens[i]);
delete m_screens[i];
m_screens.removeAt(i);
}
+ }
// Add any new screens, and make sure the primary screen comes first
// since it is used by QGuiApplication::primaryScreen()
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 8784046560..029a6de17f 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -90,8 +90,8 @@
QT_BEGIN_NAMESPACE
QXcbIntegration::QXcbIntegration(const QStringList &parameters)
- : m_eventDispatcher(createUnixEventDispatcher()),
- m_services(new QGenericUnixServices)
+ : m_eventDispatcher(createUnixEventDispatcher())
+ , m_services(new QGenericUnixServices)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@@ -119,6 +119,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
QXcbIntegration::~QXcbIntegration()
{
+ qDeleteAll(m_defaultContextInfos);
qDeleteAll(m_connections);
}
@@ -176,7 +177,14 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
{
QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
#if defined(XCB_USE_GLX)
- return new QGLXContext(screen, context->format(), context->shareHandle());
+ QOpenGLDefaultContextInfo *defaultContextInfo;
+ if (m_defaultContextInfos.contains(screen)) {
+ defaultContextInfo = m_defaultContextInfos.value(screen);
+ } else {
+ defaultContextInfo = QOpenGLDefaultContextInfo::create(screen);
+ m_defaultContextInfos.insert(screen, defaultContextInfo);
+ }
+ return new QGLXContext(screen, context->format(), context->shareHandle(), defaultContextInfo);
#elif defined(XCB_USE_EGL)
return new QEGLXcbPlatformContext(context->format(), context->shareHandle(),
screen->connection()->egl_display(), screen->connection());
@@ -274,4 +282,17 @@ QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const
return QGenericUnixTheme::createUnixTheme(name);
}
+/*!
+ Called by QXcbConnection prior to a QQnxScreen being deleted.
+
+ Destroys and cleans up any default OpenGL context info for this screen.
+*/
+void QXcbIntegration::removeDefaultOpenGLContextInfo(QXcbScreen *screen)
+{
+ if (!m_defaultContextInfos.contains(screen))
+ return;
+ QOpenGLDefaultContextInfo* info = m_defaultContextInfos.take(screen);
+ delete info;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 7f7c52372c..669a0d00f6 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -51,6 +51,11 @@ class QXcbConnection;
class QAbstractEventDispatcher;
class QXcbNativeInterface;
+#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX)
+class QOpenGLDefaultContextInfo;
+class QXcbScreen;
+#endif
+
class QXcbIntegration : public QPlatformIntegration
{
public:
@@ -92,6 +97,10 @@ public:
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
+#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX)
+ void removeDefaultOpenGLContextInfo(QXcbScreen *screen);
+#endif
+
private:
QList<QXcbConnection *> m_connections;
@@ -101,6 +110,10 @@ private:
QScopedPointer<QPlatformInputContext> m_inputContext;
QAbstractEventDispatcher *m_eventDispatcher;
+#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX)
+ mutable QHash<QXcbScreen *, QOpenGLDefaultContextInfo *> m_defaultContextInfos;
+#endif
+
#ifndef QT_NO_ACCESSIBILITY
QScopedPointer<QPlatformAccessibility> m_accessibility;
#endif