mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-02-16 10:40:59 +00:00
Use EGL_VENDOR instead of NV-CONTROL for Nvidia detection
The latter will still match on a hybrid system when the iGPU's EGL implementation is in use. This scenario works properly with EGL rendering in Qt and SDL, so we want to allow that.
This commit is contained in:
@@ -476,11 +476,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
}
|
||||
|
||||
// Nvidia's proprietary driver has broken EGL support on X11, so don't use it.
|
||||
// This will break the EGLRenderer, but that's fine on Nvidia because they
|
||||
// support both VDPAU and Vulkan renderers instead.
|
||||
// https://github.com/moonlight-stream/moonlight-qt/issues/1751
|
||||
if (!WMUtils::isRunningX11NvidiaProprietaryDriver()) {
|
||||
if (WMUtils::isEGLSafe()) {
|
||||
// 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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "eglvid.h"
|
||||
|
||||
#include "path.h"
|
||||
#include "utils.h"
|
||||
#include "streaming/session.h"
|
||||
#include "streaming/streamutils.h"
|
||||
|
||||
@@ -436,8 +437,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 (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0 &&
|
||||
!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) {
|
||||
if (!WMUtils::isEGLSafe()) {
|
||||
EGL_LOG(Warn, "Disabled due to use of GLX");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
|
||||
namespace WMUtils {
|
||||
bool isRunningX11();
|
||||
bool isRunningX11NvidiaProprietaryDriver();
|
||||
bool isRunningNvidiaProprietaryDriver();
|
||||
bool isRunningWayland();
|
||||
bool isRunningWindowManager();
|
||||
bool isRunningDesktopEnvironment();
|
||||
bool isEGLSafe();
|
||||
QString getDrmCardOverride();
|
||||
}
|
||||
|
||||
51
app/wm.cpp
51
app/wm.cpp
@@ -18,6 +18,10 @@
|
||||
#include <xf86drmMode.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
|
||||
#define VALUE_SET 0x01
|
||||
#define VALUE_TRUE 0x02
|
||||
|
||||
@@ -42,43 +46,39 @@ bool WMUtils::isRunningX11()
|
||||
}
|
||||
|
||||
return !!(val & VALUE_TRUE);
|
||||
#endif
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WMUtils::isRunningX11NvidiaProprietaryDriver()
|
||||
bool WMUtils::isRunningNvidiaProprietaryDriver()
|
||||
{
|
||||
#ifdef HAS_X11
|
||||
static SDL_atomic_t isRunningOnX11NvidiaDriver;
|
||||
#ifdef HAVE_EGL
|
||||
static SDL_atomic_t isRunningOnNvidiaDriver;
|
||||
|
||||
// If the value is not set yet, populate it now.
|
||||
int val = SDL_AtomicGet(&isRunningOnX11NvidiaDriver);
|
||||
int val = SDL_AtomicGet(&isRunningOnNvidiaDriver);
|
||||
if (!(val & VALUE_SET)) {
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
bool nvidiaDriver = false;
|
||||
|
||||
if (display != nullptr) {
|
||||
int opcode, event, error;
|
||||
|
||||
// We use the presence of the NV-CONTROL extension to indicate
|
||||
// that the Nvidia proprietary driver is in use on native X11
|
||||
nvidiaDriver = XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error);
|
||||
|
||||
XCloseDisplay(display);
|
||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (display != EGL_NO_DISPLAY && eglInitialize(display, nullptr, nullptr)) {
|
||||
const char* vendorString = eglQueryString(display, EGL_VENDOR);
|
||||
nvidiaDriver = vendorString && strstr(vendorString, "NVIDIA") != NULL;
|
||||
eglTerminate(display);
|
||||
}
|
||||
|
||||
// Populate the value to return and have for next time.
|
||||
// This can race with another thread populating the same data,
|
||||
// but that's no big deal.
|
||||
val = VALUE_SET | (nvidiaDriver ? VALUE_TRUE : 0);
|
||||
SDL_AtomicSet(&isRunningOnX11NvidiaDriver, val);
|
||||
SDL_AtomicSet(&isRunningOnNvidiaDriver, val);
|
||||
}
|
||||
|
||||
return !!(val & VALUE_TRUE);
|
||||
#endif
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WMUtils::isRunningWayland()
|
||||
@@ -102,9 +102,9 @@ bool WMUtils::isRunningWayland()
|
||||
}
|
||||
|
||||
return !!(val & VALUE_TRUE);
|
||||
#endif
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WMUtils::isRunningWindowManager()
|
||||
@@ -176,3 +176,14 @@ QString WMUtils::getDrmCardOverride()
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool WMUtils::isEGLSafe()
|
||||
{
|
||||
// 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
|
||||
//
|
||||
// https://github.com/moonlight-stream/moonlight-qt/issues/1751
|
||||
return !WMUtils::isRunningWindowManager() || WMUtils::isRunningWayland() || !WMUtils::isRunningNvidiaProprietaryDriver();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user