diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-12-06 12:55:41 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-07 11:15:28 +0100 |
commit | bab5329437e6e80da7e9f30d6422ac53f4f33f6d (patch) | |
tree | 4003aab018d087c5c7862ba1c6f6e831bf0b4435 /src | |
parent | 77fb1c71bf9bb576cfb3d7f5bf887325841ebd75 (diff) |
Better handling of GLX / EGL errors.
If context creation fails, try again without a shared context. Added
QPlatformOpenGLContext::isSharing() and
QPlatformOpenGLContext::isValid() to propagate whether the platform
context was successfully created with or without sharing.
Change-Id: I37080b645f531fd207946441057be6d3f6be3f6e
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 10 | ||||
-rw-r--r-- | src/gui/kernel/qplatformopenglcontext_qpa.h | 3 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformcontext.cpp | 11 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformcontext_p.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.cpp | 26 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 7 |
7 files changed, 48 insertions, 15 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 3549f647b5..6a9cb43028 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -164,6 +164,8 @@ bool QOpenGLContext::create() Q_D(QOpenGLContext); d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); d->platformGLContext->setContext(this); + if (!d->platformGLContext->isSharing()) + d->shareContext = 0; d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup; d->shareGroup->d_func()->addContext(this); return d->platformGLContext; @@ -197,7 +199,7 @@ QOpenGLContext::~QOpenGLContext() bool QOpenGLContext::isValid() const { Q_D(const QOpenGLContext); - return d->platformGLContext != 0; + return d->platformGLContext && d->platformGLContext->isValid(); } /*! @@ -225,7 +227,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const bool QOpenGLContext::makeCurrent(QSurface *surface) { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return false; if (thread() != QThread::currentThread()) @@ -257,7 +259,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) void QOpenGLContext::doneCurrent() { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return; if (QOpenGLContext::currentContext() == this) @@ -282,7 +284,7 @@ QSurface *QOpenGLContext::surface() const void QOpenGLContext::swapBuffers(QSurface *surface) { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return; if (!surface) { diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.h b/src/gui/kernel/qplatformopenglcontext_qpa.h index fc1b404b91..1b3bfc9a34 100644 --- a/src/gui/kernel/qplatformopenglcontext_qpa.h +++ b/src/gui/kernel/qplatformopenglcontext_qpa.h @@ -68,6 +68,9 @@ public: virtual bool makeCurrent(QPlatformSurface *surface) = 0; virtual void doneCurrent() = 0; + virtual bool isSharing() const { return false; } + virtual bool isValid() const { return true; } + virtual QFunctionPointer getProcAddress(const QByteArray &procName) = 0; QOpenGLContext *context() const; diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index dfa0bacd35..1f1f215494 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -56,7 +56,7 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform EGLConfig config = q_configFromGLFormat(display, format, true); m_format = q_glFormatFromConfig(display, config); - EGLContext shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; + m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; QVector<EGLint> contextAttrs; contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); @@ -64,11 +64,10 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform contextAttrs.append(EGL_NONE); eglBindAPI(m_eglApi); - m_eglContext = eglCreateContext(m_eglDisplay, config, shareContext, contextAttrs.constData()); - if (m_eglContext == EGL_NO_CONTEXT) { - qWarning("Could not create the egl context\n"); - eglTerminate(m_eglDisplay); - qFatal("EGL error"); + m_eglContext = eglCreateContext(m_eglDisplay, config, m_shareContext, contextAttrs.constData()); + if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) { + m_shareContext = 0; + m_eglContext = eglCreateContext(m_eglDisplay, config, 0, contextAttrs.constData()); } } diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index c38af1dfda..7002c8b9c2 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -59,6 +59,8 @@ public: void (*getProcAddress(const QByteArray &procName)) (); QSurfaceFormat format() const; + bool isSharing() const { return m_shareContext != EGL_NO_CONTEXT; } + bool isValid() const { return m_eglContext != EGL_NO_CONTEXT; } EGLContext eglContext() const; @@ -67,6 +69,7 @@ protected: private: EGLContext m_eglContext; + EGLContext m_shareContext; EGLDisplay m_eglDisplay; EGLenum m_eglApi; diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 550a5e4184..de41f862bd 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -65,13 +65,21 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat , m_screen(screen) , m_context(0) { - GLXContext shareGlxContext = 0; + m_shareContext = 0; if (share) - shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext(); + m_shareContext = static_cast<const QGLXContext*>(share)->glxContext(); GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); - m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); - m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + + m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, m_shareContext, TRUE); + if (!m_context && m_shareContext) { + // re-try without a shared glx context + m_shareContext = 0; + m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, TRUE); + } + + if (m_context) + m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); } QGLXContext::~QGLXContext() @@ -137,4 +145,14 @@ QSurfaceFormat QGLXContext::format() const return m_format; } +bool QGLXContext::isSharing() const +{ + return m_shareContext != 0; +} + +bool QGLXContext::isValid() const +{ + return m_context != 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 2c8fea5874..211a654c03 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -66,12 +66,15 @@ public: void (*getProcAddress(const QByteArray &procName)) (); QSurfaceFormat format() const; + bool isSharing() const; + bool isValid() const; GLXContext glxContext() const { return m_context; } private: QXcbScreen *m_screen; GLXContext m_context; + GLXContext m_shareContext; QSurfaceFormat m_format; }; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index a5b8aa9a35..6969124b2a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -86,6 +86,11 @@ extern "C" { QT_BEGIN_NAMESPACE +static int nullErrorHandler(Display *, XErrorEvent *) +{ + return 0; +} + QXcbConnection::QXcbConnection(const char *displayName) : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) #ifdef XCB_USE_XINPUT2_MAEMO @@ -106,6 +111,7 @@ QXcbConnection::QXcbConnection(const char *displayName) m_primaryScreen = DefaultScreen(dpy); m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); + XSetErrorHandler(nullErrorHandler); m_xlib_display = dpy; #ifdef XCB_USE_EGL EGLDisplay eglDisplay = eglGetDisplay(dpy); @@ -1002,7 +1008,6 @@ void QXcbConnection::initializeXFixes() xfixes_first_event = 0; } free(xfixes_query); - } void QXcbConnection::initializeXRender() |