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>bb10
parent
77fb1c71bf
commit
bab5329437
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue