From 54163e30d0cb02c8a3921a4a5545bcc41131bad3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 11 Dec 2025 20:10:37 -0600 Subject: [PATCH] Disable EGL on Nvidia XWayland environments too It renders a black window, just like native X11. --- app/main.cpp | 2 +- .../video/ffmpeg-renderers/eglvid.cpp | 11 +--------- app/utils.h | 4 ++-- app/wm.cpp | 21 +++++++++++-------- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index 3229dd0a..c8824f18 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -476,7 +476,7 @@ int main(int argc, char *argv[]) #endif } - if (WMUtils::isEGLSafe()) { + if (WMUtils::isX11EGLSafe()) { // Some ARM and RISC-V embedded devices don't have working GLX which can cause // SDL to fail to find a working OpenGL implementation at all. Let's force EGL // on all platforms for both SDL and Qt. This also avoids GLX-EGL interop issues diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index cbf976cf..a74923e7 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -14,15 +14,6 @@ #include // These are extensions, so some platform headers may not provide them -#ifndef EGL_PLATFORM_WAYLAND_KHR -#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 -#endif -#ifndef EGL_PLATFORM_X11_KHR -#define EGL_PLATFORM_X11_KHR 0x31D5 -#endif -#ifndef EGL_PLATFORM_GBM_KHR -#define EGL_PLATFORM_GBM_KHR 0x31D7 -#endif #ifndef GL_UNPACK_ROW_LENGTH_EXT #define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 #endif @@ -437,7 +428,7 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) // If we're using X11 GLX (both in SDL and Qt), don't use this renderer. // Switching between EGL and GLX can cause interoperability issues. - if (!WMUtils::isEGLSafe()) { + if (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0 && !WMUtils::isX11EGLSafe()) { EGL_LOG(Warn, "Disabled due to use of GLX"); return false; } diff --git a/app/utils.h b/app/utils.h index d303444b..d437968f 100644 --- a/app/utils.h +++ b/app/utils.h @@ -7,10 +7,10 @@ namespace WMUtils { bool isRunningX11(); - bool isRunningNvidiaProprietaryDriver(); + bool isRunningNvidiaProprietaryDriverX11(); bool isRunningWayland(); bool isRunningWindowManager(); bool isRunningDesktopEnvironment(); - bool isEGLSafe(); + bool isX11EGLSafe(); QString getDrmCardOverride(); } diff --git a/app/wm.cpp b/app/wm.cpp index 54e3fc3c..5f605392 100644 --- a/app/wm.cpp +++ b/app/wm.cpp @@ -20,6 +20,10 @@ #ifdef HAVE_EGL #include + +#ifndef EGL_PLATFORM_X11_KHR +#define EGL_PLATFORM_X11_KHR 0x31D5 +#endif #endif #define VALUE_SET 0x01 @@ -51,7 +55,7 @@ bool WMUtils::isRunningX11() #endif } -bool WMUtils::isRunningNvidiaProprietaryDriver() +bool WMUtils::isRunningNvidiaProprietaryDriverX11() { #ifdef HAVE_EGL static SDL_atomic_t isRunningOnNvidiaDriver; @@ -61,7 +65,10 @@ bool WMUtils::isRunningNvidiaProprietaryDriver() if (!(val & VALUE_SET)) { bool nvidiaDriver = false; - EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + // Open the default X11 display. This is critical for accurate detection of the + // Nvidia driver under XWayland because eglGetDisplay(EGL_DEFAULT_DISPLAY) will + // return the Wayland display but Qt will use the X11 display. + EGLDisplay display = eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, EGL_DEFAULT_DISPLAY, nullptr); if (display != EGL_NO_DISPLAY && eglInitialize(display, nullptr, nullptr)) { const char* vendorString = eglQueryString(display, EGL_VENDOR); nvidiaDriver = vendorString && strstr(vendorString, "NVIDIA") != NULL; @@ -177,13 +184,9 @@ QString WMUtils::getDrmCardOverride() return QString(); } -bool WMUtils::isEGLSafe() +bool WMUtils::isX11EGLSafe() { - // We can use EGL if: - // a) We're not using X11/Wayland (EGLFS requires it) - // b) We're using Wayland (even XWayland is fine) - // c) We're using X11 but not the Nvidia proprietary driver - // + // Nvidia's driver has broken EGL support on X11 and XWayland // https://github.com/moonlight-stream/moonlight-qt/issues/1751 - return !WMUtils::isRunningWindowManager() || WMUtils::isRunningWayland() || !WMUtils::isRunningNvidiaProprietaryDriver(); + return !WMUtils::isRunningNvidiaProprietaryDriverX11(); }