From 394249616cbb4c0861a032d33f846f85e2801677 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 27 Sep 2012 15:24:34 +0100 Subject: [PATCH] OpenGL: Don't request a context version higher than is supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function wglCreateContextAttribsARB will fail if we request a context version higher than is supported. We therefore upper-bound the requested version by the version of the static context. This results in context creation succeeding and having the closest possible match to the requested format. The xcb qpa plugin is modified to operate similarly to the windows plugin in that it now creates a "static" context which is used to limit the versions of contexts requested by the user. Change-Id: I277ad7cc82edfdf7b9d8502ad921c8175feb1a4a Reviewed-by: Samuel Rødal --- src/gui/kernel/qopenglcontext.cpp | 10 +- src/gui/kernel/qplatformopenglcontext.cpp | 10 +- src/gui/kernel/qplatformopenglcontext.h | 2 +- src/opengl/qgl.cpp | 8 + .../platforms/windows/qwindowsglcontext.cpp | 17 +- src/plugins/platforms/xcb/qglxintegration.cpp | 262 ++++++++++++++---- src/plugins/platforms/xcb/qglxintegration.h | 15 +- src/plugins/platforms/xcb/qxcbconnection.cpp | 4 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 27 +- src/plugins/platforms/xcb/qxcbintegration.h | 13 + 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 parts = versionString.split(' '); + if (versionString.startsWith(QByteArrayLiteral("OpenGL ES"))) { if (parts.size() >= 3) { - QStringList versionParts = parts.at(2).split(QLatin1Char('.')); + QList 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 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(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 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 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 + window = createDummyWindow(screen, visualInfo); + XFree(visualInfo); } - // 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); - // 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(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 ¶meters) - : 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 ¶meters) QXcbIntegration::~QXcbIntegration() { + qDeleteAll(m_defaultContextInfos); qDeleteAll(m_connections); } @@ -176,7 +177,14 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont { QXcbScreen *screen = static_cast(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 m_connections; @@ -101,6 +110,10 @@ private: QScopedPointer m_inputContext; QAbstractEventDispatcher *m_eventDispatcher; +#if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX) + mutable QHash m_defaultContextInfos; +#endif + #ifndef QT_NO_ACCESSIBILITY QScopedPointer m_accessibility; #endif