core: recreate rendering context when monitors are empty on nvidia (#845)

This is a workaround for nvidia that can hopefully be removed at some point.
This commit is contained in:
Maximilian Seidler 2025-09-04 07:04:54 +00:00 committed by GitHub
parent cedbb24472
commit 04cfdc4e5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 5 deletions

View file

@ -38,8 +38,9 @@ CEGL::CEGL(wl_display* display) {
if (eglCreatePlatformWindowSurfaceEXT == nullptr)
throw std::runtime_error("Failed to get eglCreatePlatformWindowSurfaceEXT");
eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, display, nullptr);
EGLint matched = 0;
const char* vendorString = nullptr;
eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, display, nullptr);
EGLint matched = 0;
if (eglDisplay == EGL_NO_DISPLAY) {
Debug::log(CRIT, "Failed to create EGL display");
goto error;
@ -65,6 +66,9 @@ CEGL::CEGL(wl_display* display) {
goto error;
}
vendorString = eglQueryString(eglDisplay, EGL_VENDOR);
m_isNvidia = (vendorString) ? std::string{vendorString}.contains("NVIDIA") : false;
return;
error:

View file

@ -17,6 +17,8 @@ class CEGL {
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT;
void makeCurrent(EGLSurface surf);
bool m_isNvidia = false;
};
inline UP<CEGL> g_pEGL;

View file

@ -1,5 +1,4 @@
#include "hyprlock.hpp"
#include "AnimationManager.hpp"
#include "../helpers/Log.hpp"
#include "../config/ConfigManager.hpp"
#include "../renderer/Renderer.hpp"
@ -18,8 +17,6 @@
#include <cassert>
#include <cstring>
#include <xf86drm.h>
#include <filesystem>
#include <fstream>
#include <algorithm>
#include <sdbus-c++/sdbus-c++.h>
#include <hyprutils/os/Process.hpp>
@ -308,6 +305,18 @@ void CHyprlock::run() {
g_pRenderer->removeWidgetsFor((*outputIt)->m_ID);
m_vOutputs.erase(outputIt);
}
// TODO: Recreating the rendering context like this fixes an issue with nvidia graphics when reconnecting monitors.
// It only happens when there are no monitors left.
// This is either an nvidia bug (probably egl-wayland) or it is a hyprlock bug. In any case, the goal is to remove this at some point!
if (g_pEGL->m_isNvidia && m_vOutputs.empty()) {
Debug::log(LOG, "NVIDIA Workaround: destroying rendering context to avoid crash on reconnect!");
g_pEGL.reset();
g_pRenderer.reset();
g_pEGL = makeUnique<CEGL>(m_sWaylandState.display);
g_pRenderer = makeUnique<CRenderer>();
}
});
wl_display_roundtrip(m_sWaylandState.display);