From b383db2e2e6747d3beb881c4b948e2fe2403efde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 13 Nov 2015 09:45:11 +0100 Subject: [PATCH] Create robust egl context if possible --- abstract_egl_backend.cpp | 79 +++++++++++++++++------- plugins/qpa/abstractplatformcontext.cpp | 81 +++++++++++++++++-------- 2 files changed, 114 insertions(+), 46 deletions(-) diff --git a/abstract_egl_backend.cpp b/abstract_egl_backend.cpp index e8701e8d09..d5a469b5cf 100644 --- a/abstract_egl_backend.cpp +++ b/abstract_egl_backend.cpp @@ -184,34 +184,69 @@ bool AbstractEglBackend::isOpenGLES() const bool AbstractEglBackend::createContext() { + const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS); + const QList extensions = eglExtensions.split(' '); + const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness")); + const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context")); + EGLContext ctx = EGL_NO_CONTEXT; if (isOpenGLES()) { - const EGLint context_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; + if (haveCreateContext && haveRobustness) { + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT, + EGL_NONE + }; + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs); + } + if (ctx == EGL_NO_CONTEXT) { + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; - ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs); + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs); + } } else { - const EGLint context_attribs_31_core[] = { - EGL_CONTEXT_MAJOR_VERSION_KHR, 3, - EGL_CONTEXT_MINOR_VERSION_KHR, 1, - EGL_NONE - }; - - const EGLint context_attribs_legacy[] = { - EGL_NONE - }; - - const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS); - const QList extensions = eglExtensions.split(' '); - // Try to create a 3.1 core context - if (options->glCoreProfile() && extensions.contains("EGL_KHR_create_context")) - ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs_31_core); + if (options->glCoreProfile() && haveCreateContext) { + if (haveRobustness) { + const int attribs[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_NONE + }; + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs); + } + if (ctx == EGL_NO_CONTEXT) { + // try without robustness + const EGLint attribs[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_NONE + }; + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs); + } + } - if (ctx == EGL_NO_CONTEXT) - ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs_legacy); + if (ctx == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) { + const int attribs[] = { + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_NONE + }; + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs); + } + if (ctx == EGL_NO_CONTEXT) { + // and last but not least: try without robustness + const EGLint attribs[] = { + EGL_NONE + }; + ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs); + } } if (ctx == EGL_NO_CONTEXT) { diff --git a/plugins/qpa/abstractplatformcontext.cpp b/plugins/qpa/abstractplatformcontext.cpp index 3ddca9c4e2..278669e910 100644 --- a/plugins/qpa/abstractplatformcontext.cpp +++ b/plugins/qpa/abstractplatformcontext.cpp @@ -135,38 +135,71 @@ bool AbstractPlatformContext::bindApi() void AbstractPlatformContext::createContext(EGLContext shareContext) { + const QByteArray eglExtensions = eglQueryString(eglDisplay(), EGL_EXTENSIONS); + const QList extensions = eglExtensions.split(' '); + const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness")); + const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context")); + EGLContext context = EGL_NO_CONTEXT; if (isOpenGLES()) { - const EGLint context_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; + if (haveCreateContext && haveRobustness) { + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT, + EGL_NONE + }; + context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); + } + if (context == EGL_NO_CONTEXT) { + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; - context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); + context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); + } } else { - const EGLint context_attribs_31_core[] = { - EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(), - EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(), - EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, - EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, - EGL_NONE - }; - - const EGLint context_attribs_legacy[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - const char* eglExtensionsCString = eglQueryString(eglDisplay(), EGL_EXTENSIONS); - const QList extensions = QByteArray::fromRawData(eglExtensionsCString, qstrlen(eglExtensionsCString)).split(' '); - // Try to create a 3.1 core context - if (m_format.majorVersion() >= 3 && extensions.contains(QByteArrayLiteral("EGL_KHR_create_context"))) { - context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs_31_core); + if (m_format.majorVersion() >= 3 && haveCreateContext) { + if (haveRobustness) { + const int attribs[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(), + EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(), + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_NONE + }; + context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); + } + if (context == EGL_NO_CONTEXT) { + // try without robustness + const EGLint attribs[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(), + EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(), + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_NONE + }; + context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); + } } + if (context == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) { + const int attribs[] = { + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_NONE + }; + context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); + } if (context == EGL_NO_CONTEXT) { - context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs_legacy); + // and last but not least: try without robustness + const EGLint attribs[] = { + EGL_NONE + }; + context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); } }