From abbf82bdfcf0a233553cceb73d4cff56b6cd273d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 29 Jul 2015 15:39:28 +0200 Subject: Make EGL context init work when msaa is requested but there's no surfaceless To query back certain things, like the actual OpenGL version from the created context, the eglconvenience code makes the new context current either without a surface (in case EGL_KHR_surfaceless_context is supported) or with a pbuffer (or other platform specific equivalent). There is no problem with the former. The latter can however fail when samples are requested for the context and there are no matching pbuffer configs. The result is a pbuffer without multisampling, which could lead to a BAD_MATCH. This is visible on GLES 2.0 devices like the Beaglebone. The solution is to fall back to creating a new, temporary context with a config matching the pbuffer's whenever the makeCurrent attempt fails. Change-Id: Icd9f3383f2cad36dd5b60dead655328b7b9af658 Reviewed-by: Andy Nichols --- .../eglconvenience/qeglplatformcontext.cpp | 17 +++++++++++++++-- .../eglconvenience/qeglplatformcontext_p.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 6d9f9e4ae0..8929a038e0 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -154,6 +154,7 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont } } contextAttrs.append(EGL_NONE); + m_contextAttrs = contextAttrs; switch (m_format.renderableType()) { case QSurfaceFormat::OpenVG: @@ -243,6 +244,8 @@ void QEGLPlatformContext::initialize() updateFormatFromGL(); } +// Base implementation for pbuffers. Subclasses will handle the specialized cases for +// platforms without pbuffers. EGLSurface QEGLPlatformContext::createTemporaryOffscreenSurface() { // Make the context current to ensure the GL version query works. This needs a surface too. @@ -282,10 +285,18 @@ void QEGLPlatformContext::updateFormatFromGL() // avoid creating an extra pbuffer surface which is apparently troublesome with some // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; + EGLContext tempContext = EGL_NO_CONTEXT; if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); - if (eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext)) { + EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext); + if (!ok) { + EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT); + tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData()); + if (tempContext != EGL_NO_CONTEXT) + ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext); + } + if (ok) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { const GLubyte *s = glGetString(GL_VERSION); @@ -323,10 +334,12 @@ void QEGLPlatformContext::updateFormatFromGL() } eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } else { - qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated"); + qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated (%x)", eglGetError()); } if (tempSurface != EGL_NO_SURFACE) destroyTemporaryOffscreenSurface(tempSurface); + if (tempContext != EGL_NO_CONTEXT) + eglDestroyContext(m_eglDisplay, tempContext); #endif // QT_NO_OPENGL } diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 50c264e1dc..2ab7ad28d0 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -94,6 +94,7 @@ private: bool m_swapIntervalEnvChecked; int m_swapIntervalFromEnv; bool m_ownsContext; + QVector m_contextAttrs; }; QT_END_NAMESPACE -- cgit v1.2.3