From 2c26215d7ebc6493f52a502c92205383422215bc Mon Sep 17 00:00:00 2001 From: Eike Hein Date: Thu, 22 Mar 2018 18:20:37 +0900 Subject: [PATCH] Request a high-priority EGL contexts Summary: This patch implements using EGL_IMG_context_priority to request high-priority rendering contexts if the extension is available. EGL_IMG_context_priority is currently used in this fashion by e.g. Android's SurfaceFlinger (RenderEngine.cpp) and libweston (gl-renderer.c) and seems promising given this widespread acceptance. Reviewers: #kwin, graesslin, romangg, davidedmundson Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D11572 --- abstract_opengl_context_attribute_builder.cpp | 3 +- abstract_opengl_context_attribute_builder.h | 9 ++ .../opengl_context_attribute_builder_test.cpp | 121 ++++++++++++++++-- egl_context_attribute_builder.cpp | 8 ++ .../scenes/opengl/abstract_egl_backend.cpp | 33 +++++ plugins/qpa/abstractplatformcontext.cpp | 46 ++++++- 6 files changed, 206 insertions(+), 14 deletions(-) diff --git a/abstract_opengl_context_attribute_builder.cpp b/abstract_opengl_context_attribute_builder.cpp index 74071072a5..c47eb4e824 100644 --- a/abstract_opengl_context_attribute_builder.cpp +++ b/abstract_opengl_context_attribute_builder.cpp @@ -32,7 +32,8 @@ QDebug AbstractOpenGLContextAttributeBuilder::operator<<(QDebug dbg) const dbg.nospace() << "Robust:\t" << isRobust() << "\n"; dbg.nospace() << "Forward compatible:\t" << isForwardCompatible() << "\n"; dbg.nospace() << "Core profile:\t" << isCoreProfile() << "\n"; - dbg.nospace() << "Compatibility profile:\t" << isCompatibilityProfile(); + dbg.nospace() << "Compatibility profile:\t" << isCompatibilityProfile() << "\n"; + dbg.nospace() << "High priority:\t" << isHighPriority(); return dbg; } diff --git a/abstract_opengl_context_attribute_builder.h b/abstract_opengl_context_attribute_builder.h index c698e8471d..0028abc962 100644 --- a/abstract_opengl_context_attribute_builder.h +++ b/abstract_opengl_context_attribute_builder.h @@ -94,6 +94,14 @@ public: return m_resetOnVideoMemoryPurge; } + void setHighPriority(bool highPriority) { + m_highPriority = highPriority; + } + + bool isHighPriority() const { + return m_highPriority; + } + virtual std::vector build() const = 0; QDebug operator<<(QDebug dbg) const; @@ -107,6 +115,7 @@ private: bool m_coreProfile = false; bool m_compatibilityProfile = false; bool m_resetOnVideoMemoryPurge = false; + bool m_highPriority = false; }; inline QDebug operator<<(QDebug dbg, const AbstractOpenGLContextAttributeBuilder *attribs) diff --git a/autotests/opengl_context_attribute_builder_test.cpp b/autotests/opengl_context_attribute_builder_test.cpp index 9ae16552d7..43229ef587 100644 --- a/autotests/opengl_context_attribute_builder_test.cpp +++ b/autotests/opengl_context_attribute_builder_test.cpp @@ -45,6 +45,7 @@ private Q_SLOTS: void testResetOnVideoMemoryPurge(); void testVersionMajor(); void testVersionMajorAndMinor(); + void testHighPriority(); void testEgl_data(); void testEgl(); void testGles_data(); @@ -75,6 +76,7 @@ void OpenGLContextAttributeBuilderTest::testCtor() QCOMPARE(builder.isCoreProfile(), false); QCOMPARE(builder.isCompatibilityProfile(), false); QCOMPARE(builder.isResetOnVideoMemoryPurge(), false); + QCOMPARE(builder.isHighPriority(), false); } void OpenGLContextAttributeBuilderTest::testRobust() @@ -123,6 +125,16 @@ void OpenGLContextAttributeBuilderTest::testResetOnVideoMemoryPurge() QCOMPARE(builder.isResetOnVideoMemoryPurge(), false); } +void OpenGLContextAttributeBuilderTest::testHighPriority() +{ + MockOpenGLContextAttributeBuilder builder; + QCOMPARE(builder.isHighPriority(), false); + builder.setHighPriority(true); + QCOMPARE(builder.isHighPriority(), true); + builder.setHighPriority(false); + QCOMPARE(builder.isHighPriority(), false); +} + void OpenGLContextAttributeBuilderTest::testVersionMajor() { MockOpenGLContextAttributeBuilder builder; @@ -158,54 +170,106 @@ void OpenGLContextAttributeBuilderTest::testEgl_data() QTest::addColumn("forwardCompatible"); QTest::addColumn("coreProfile"); QTest::addColumn("compatibilityProfile"); + QTest::addColumn("highPriority"); QTest::addColumn>("expectedAttribs"); - QTest::newRow("fallback") << false << 0 << 0 << false << false << false << false << std::vector{EGL_NONE}; - QTest::newRow("legacy/robust") << false << 0 << 0 << true << false << false << false << + QTest::newRow("fallback") << false << 0 << 0 << false << false << false << false << false << std::vector{EGL_NONE}; + QTest::newRow("legacy/robust") << false << 0 << 0 << true << false << false << false << false << std::vector{ 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}; - QTest::newRow("core") << true << 3 << 1 << false << false << false << false << + QTest::newRow("legacy/robust/high priority") << false << 0 << 0 << true << false << false << false << true << + std::vector{ + 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_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core") << true << 3 << 1 << false << false << false << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE}; - QTest::newRow("core/robust") << true << 3 << 1 << true << false << false << false << + QTest::newRow("core/high priority") << true << 3 << 1 << false << false << false << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core/robust") << true << 3 << 1 << true << false << false << false << false << std::vector{ 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}; - QTest::newRow("core/robust/forward compatible") << true << 3 << 1 << true << true << false << false << + QTest::newRow("core/robust/high priority") << true << 3 << 1 << true << false << false << false << true << + std::vector{ + 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_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core/robust/forward compatible") << true << 3 << 1 << true << true << false << false << false << std::vector{ 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_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_NONE}; - QTest::newRow("core/forward compatible") << true << 3 << 1 << false << true << false << false << + QTest::newRow("core/robust/forward compatible/high priority") << true << 3 << 1 << true << true << false << false << true << + std::vector{ + 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_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core/forward compatible") << true << 3 << 1 << false << true << false << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_NONE}; - QTest::newRow("core profile/forward compatible") << true << 3 << 2 << false << true << true << false << + QTest::newRow("core/forward compatible/high priority") << true << 3 << 1 << false << true << false << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core profile/forward compatible") << true << 3 << 2 << false << true << true << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, EGL_NONE}; - QTest::newRow("compatibility profile/forward compatible") << true << 3 << 2 << false << true << false << true << + QTest::newRow("core profile/forward compatible/high priority") << true << 3 << 2 << false << true << true << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("compatibility profile/forward compatible") << true << 3 << 2 << false << true << false << true << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE}; - QTest::newRow("core profile/robust/forward compatible") << true << 3 << 2 << true << true << true << false << + QTest::newRow("compatibility profile/forward compatible/high priority") << true << 3 << 2 << false << true << false << true << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core profile/robust/forward compatible") << true << 3 << 2 << true << true << true << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, @@ -213,7 +277,16 @@ void OpenGLContextAttributeBuilderTest::testEgl_data() EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, EGL_NONE}; - QTest::newRow("compatibility profile/robust/forward compatible") << true << 3 << 2 << true << true << false << true << + QTest::newRow("core profile/robust/forward compatible/high priority") << true << 3 << 2 << true << true << true << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + 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, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("compatibility profile/robust/forward compatible") << true << 3 << 2 << true << true << false << true << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, @@ -221,6 +294,15 @@ void OpenGLContextAttributeBuilderTest::testEgl_data() EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE}; + QTest::newRow("compatibility profile/robust/forward compatible/high priority") << true << 3 << 2 << true << true << false << true << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + 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, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; } void OpenGLContextAttributeBuilderTest::testEgl() @@ -232,6 +314,7 @@ void OpenGLContextAttributeBuilderTest::testEgl() QFETCH(bool, forwardCompatible); QFETCH(bool, coreProfile); QFETCH(bool, compatibilityProfile); + QFETCH(bool, highPriority); EglContextAttributeBuilder builder; if (requestVersion) { @@ -241,6 +324,7 @@ void OpenGLContextAttributeBuilderTest::testEgl() builder.setForwardCompatible(forwardCompatible); builder.setCoreProfile(coreProfile); builder.setCompatibilityProfile(compatibilityProfile); + builder.setHighPriority(highPriority); auto attribs = builder.build(); QTEST(attribs, "expectedAttribs"); @@ -249,25 +333,38 @@ void OpenGLContextAttributeBuilderTest::testEgl() void OpenGLContextAttributeBuilderTest::testGles_data() { QTest::addColumn("robust"); + QTest::addColumn("highPriority"); QTest::addColumn>("expectedAttribs"); - QTest::newRow("robust") << true << std::vector{ + QTest::newRow("robust") << true << false << std::vector{ 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}; - QTest::newRow("normal") << false << std::vector{ + QTest::newRow("robust/high priority") << true << true << std::vector{ 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_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("normal") << false << false << std::vector{ + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE}; + QTest::newRow("normal/high priority") << false << true << std::vector{ + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, EGL_NONE}; } void OpenGLContextAttributeBuilderTest::testGles() { QFETCH(bool, robust); + QFETCH(bool, highPriority); EglOpenGLESContextAttributeBuilder builder; builder.setVersion(2); builder.setRobust(robust); + builder.setHighPriority(highPriority); auto attribs = builder.build(); QTEST(attribs, "expectedAttribs"); diff --git a/egl_context_attribute_builder.cpp b/egl_context_attribute_builder.cpp index 87fa20f789..9f3712b5b8 100644 --- a/egl_context_attribute_builder.cpp +++ b/egl_context_attribute_builder.cpp @@ -52,6 +52,10 @@ std::vector EglContextAttributeBuilder::build() const attribs.emplace_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); } } + if (isHighPriority()) { + attribs.emplace_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + attribs.emplace_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + } attribs.emplace_back(EGL_NONE); return attribs; } @@ -67,6 +71,10 @@ std::vector EglOpenGLESContextAttributeBuilder::build() const attribs.emplace_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); attribs.emplace_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); } + if (isHighPriority()) { + attribs.emplace_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + attribs.emplace_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + } attribs.emplace_back(EGL_NONE); return attribs; } diff --git a/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 91729b4804..6af4f72cb5 100644 --- a/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -217,30 +217,63 @@ bool AbstractEglBackend::createContext() { const bool haveRobustness = hasExtension(QByteArrayLiteral("EGL_EXT_create_context_robustness")); const bool haveCreateContext = hasExtension(QByteArrayLiteral("EGL_KHR_create_context")); + const bool haveContextPriority = hasExtension(QByteArrayLiteral("EGL_IMG_context_priority")); std::vector> candidates; if (isOpenGLES()) { + if (haveCreateContext && haveRobustness && haveContextPriority) { + auto glesRobustPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesRobustPriority->setVersion(2); + glesRobustPriority->setRobust(true); + glesRobustPriority->setHighPriority(true); + candidates.push_back(std::move(glesRobustPriority)); + } if (haveCreateContext && haveRobustness) { auto glesRobust = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); glesRobust->setVersion(2); glesRobust->setRobust(true); candidates.push_back(std::move(glesRobust)); } + if (haveContextPriority) { + auto glesPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesPriority->setVersion(2); + glesPriority->setHighPriority(true); + candidates.push_back(std::move(glesPriority)); + } auto gles = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); gles->setVersion(2); candidates.push_back(std::move(gles)); } else { if (options->glCoreProfile() && haveCreateContext) { + if (haveRobustness && haveContextPriority) { + auto robustCorePriority = std::unique_ptr(new EglContextAttributeBuilder); + robustCorePriority->setVersion(3, 1); + robustCorePriority->setRobust(true); + robustCorePriority->setHighPriority(true); + candidates.push_back(std::move(robustCorePriority)); + } if (haveRobustness) { auto robustCore = std::unique_ptr(new EglContextAttributeBuilder); robustCore->setVersion(3, 1); robustCore->setRobust(true); candidates.push_back(std::move(robustCore)); } + if (haveContextPriority) { + auto corePriority = std::unique_ptr(new EglContextAttributeBuilder); + corePriority->setVersion(3, 1); + corePriority->setHighPriority(true); + candidates.push_back(std::move(corePriority)); + } auto core = std::unique_ptr(new EglContextAttributeBuilder); core->setVersion(3, 1); candidates.push_back(std::move(core)); } + if (haveRobustness && haveCreateContext && haveContextPriority) { + auto robustPriority = std::unique_ptr(new EglContextAttributeBuilder); + robustPriority->setRobust(true); + robustPriority->setHighPriority(true); + candidates.push_back(std::move(robustPriority)); + } if (haveRobustness && haveCreateContext) { auto robust = std::unique_ptr(new EglContextAttributeBuilder); robust->setRobust(true); diff --git a/plugins/qpa/abstractplatformcontext.cpp b/plugins/qpa/abstractplatformcontext.cpp index af4d539d27..507a151397 100644 --- a/plugins/qpa/abstractplatformcontext.cpp +++ b/plugins/qpa/abstractplatformcontext.cpp @@ -146,21 +146,48 @@ void AbstractPlatformContext::createContext(EGLContext shareContext) 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")); + const bool haveContextPriority = extensions.contains(QByteArrayLiteral("EGL_IMG_context_priority")); std::vector> candidates; if (isOpenGLES()) { + if (haveCreateContext && haveRobustness && haveContextPriority) { + auto glesRobustPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesRobustPriority->setVersion(2); + glesRobustPriority->setRobust(true); + glesRobustPriority->setHighPriority(true); + candidates.push_back(std::move(glesRobustPriority)); + } if (haveCreateContext && haveRobustness) { auto glesRobust = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); glesRobust->setVersion(2); glesRobust->setRobust(true); candidates.push_back(std::move(glesRobust)); } + if (haveContextPriority) { + auto glesPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesPriority->setVersion(2); + glesPriority->setHighPriority(true); + candidates.push_back(std::move(glesPriority)); + } auto gles = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); gles->setVersion(2); candidates.push_back(std::move(gles)); } else { // Try to create a 3.1 core context if (m_format.majorVersion() >= 3 && haveCreateContext) { + if (haveRobustness && haveContextPriority) { + auto robustCorePriority = std::unique_ptr(new EglContextAttributeBuilder); + robustCorePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); + robustCorePriority->setRobust(true); + robustCorePriority->setForwardCompatible(true); + if (m_format.profile() == QSurfaceFormat::CoreProfile) { + robustCorePriority->setCoreProfile(true); + } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { + robustCorePriority->setCompatibilityProfile(true); + } + robustCorePriority->setHighPriority(true); + candidates.push_back(std::move(robustCorePriority)); + } if (haveRobustness) { auto robustCore = std::unique_ptr(new EglContextAttributeBuilder); robustCore->setVersion(m_format.majorVersion(), m_format.minorVersion()); @@ -173,6 +200,18 @@ void AbstractPlatformContext::createContext(EGLContext shareContext) } candidates.push_back(std::move(robustCore)); } + if (haveContextPriority) { + auto corePriority = std::unique_ptr(new EglContextAttributeBuilder); + corePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); + corePriority->setForwardCompatible(true); + if (m_format.profile() == QSurfaceFormat::CoreProfile) { + corePriority->setCoreProfile(true); + } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { + corePriority->setCompatibilityProfile(true); + } + corePriority->setHighPriority(true); + candidates.push_back(std::move(corePriority)); + } auto core = std::unique_ptr(new EglContextAttributeBuilder); core->setVersion(m_format.majorVersion(), m_format.minorVersion()); core->setForwardCompatible(true); @@ -183,7 +222,12 @@ void AbstractPlatformContext::createContext(EGLContext shareContext) } candidates.push_back(std::move(core)); } - + if (haveRobustness && haveCreateContext && haveContextPriority) { + auto robustPriority = std::unique_ptr(new EglContextAttributeBuilder); + robustPriority->setRobust(true); + robustPriority->setHighPriority(true); + candidates.push_back(std::move(robustPriority)); + } if (haveRobustness && haveCreateContext) { auto robust = std::unique_ptr(new EglContextAttributeBuilder); robust->setRobust(true);