set EGL_NV_robustness_video_memory_purge where applicable

This enables kwin to get notified when a memory has been lost in the
system, allowing the driver to purge all the memory and have kwin create
new contexts.

This matches what we do on GLX.
This commit is contained in:
David Edmundson 2021-11-22 12:21:19 +00:00
parent 8febb1f343
commit 190a92bc3f
3 changed files with 27 additions and 0 deletions

View file

@ -19,6 +19,7 @@ QDebug AbstractOpenGLContextAttributeBuilder::operator<<(QDebug dbg) const
dbg.nospace() << "Version:\t" << majorVersion() << "." << minorVersion() << "\n";
}
dbg.nospace() << "Robust:\t" << isRobust() << "\n";
dbg.nospace() << "Reset on video memory purge:\t" << isResetOnVideoMemoryPurge() << "\n";
dbg.nospace() << "Forward compatible:\t" << isForwardCompatible() << "\n";
dbg.nospace() << "Core profile:\t" << isCoreProfile() << "\n";
dbg.nospace() << "Compatibility profile:\t" << isCompatibilityProfile() << "\n";

View file

@ -25,6 +25,10 @@ std::vector<int> EglContextAttributeBuilder::build() const
attribs.emplace_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
attribs.emplace_back(EGL_LOSE_CONTEXT_ON_RESET_KHR);
contextFlags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
if (isResetOnVideoMemoryPurge()) {
attribs.emplace_back(EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV);
attribs.emplace_back(GL_TRUE);
}
}
if (isForwardCompatible()) {
contextFlags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
@ -59,6 +63,10 @@ std::vector<int> EglOpenGLESContextAttributeBuilder::build() const
attribs.emplace_back(EGL_TRUE);
attribs.emplace_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
attribs.emplace_back(EGL_LOSE_CONTEXT_ON_RESET_EXT);
if (isResetOnVideoMemoryPurge()) {
attribs.emplace_back(EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV);
attribs.emplace_back(GL_TRUE);
}
}
if (isHighPriority()) {
attribs.emplace_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);

View file

@ -261,9 +261,19 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
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"));
const bool haveResetOnVideoMemoryPurge = hasExtension(QByteArrayLiteral("EGL_NV_robustness_video_memory_purge"));
std::vector<std::unique_ptr<AbstractOpenGLContextAttributeBuilder>> candidates;
if (isOpenGLES()) {
if (haveCreateContext && haveRobustness && haveContextPriority && haveResetOnVideoMemoryPurge) {
auto glesRobustPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
glesRobustPriority->setResetOnVideoMemoryPurge(true);
glesRobustPriority->setVersion(2);
glesRobustPriority->setRobust(true);
glesRobustPriority->setHighPriority(true);
candidates.push_back(std::move(glesRobustPriority));
}
if (haveCreateContext && haveRobustness && haveContextPriority) {
auto glesRobustPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
glesRobustPriority->setVersion(2);
@ -288,6 +298,14 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
candidates.push_back(std::move(gles));
} else {
if (haveCreateContext) {
if (haveRobustness && haveContextPriority && haveResetOnVideoMemoryPurge) {
auto robustCorePriority = std::make_unique<EglContextAttributeBuilder>();
robustCorePriority->setResetOnVideoMemoryPurge(true);
robustCorePriority->setVersion(3, 1);
robustCorePriority->setRobust(true);
robustCorePriority->setHighPriority(true);
candidates.push_back(std::move(robustCorePriority));
}
if (haveRobustness && haveContextPriority) {
auto robustCorePriority = std::make_unique<EglContextAttributeBuilder>();
robustCorePriority->setVersion(3, 1);