summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-12-06 12:55:41 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-07 11:15:28 +0100
commitbab5329437e6e80da7e9f30d6422ac53f4f33f6d (patch)
tree4003aab018d087c5c7862ba1c6f6e831bf0b4435 /src
parent77fb1c71bf9bb576cfb3d7f5bf887325841ebd75 (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.cpp10
-rw-r--r--src/gui/kernel/qplatformopenglcontext_qpa.h3
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp11
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h3
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp26
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp7
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()