Force Qt to use GLES if desktop GL is not available

Some platforms like the VisionFive 2 don't have working desktop GL,
so they must use GLES to be able to render at all. Qt doesn't try
to fall back if it fails to find a compatible EGL config, so we must
do so ourselves.
This commit is contained in:
Cameron Gutman
2025-12-21 21:10:13 -06:00
parent 7f54662160
commit 7edbede95d
3 changed files with 43 additions and 1 deletions

View File

@@ -550,7 +550,9 @@ int main(int argc, char *argv[])
#endif
}
if (WMUtils::isRunningNvidiaProprietaryDriverX11() || qEnvironmentVariableIntValue("FORCE_QT_GLES")) {
if (WMUtils::isRunningNvidiaProprietaryDriverX11() ||
!WMUtils::supportsDesktopGLWithEGL() ||
qEnvironmentVariableIntValue("FORCE_QT_GLES")) {
// The Nvidia proprietary driver causes Qt to render a black window when using
// the default Desktop GL profile with EGL. AS a workaround, we default to
// OpenGL ES when running on Nvidia on X11.

View File

@@ -8,6 +8,7 @@
namespace WMUtils {
bool isRunningX11();
bool isRunningNvidiaProprietaryDriverX11();
bool supportsDesktopGLWithEGL();
bool isRunningWayland();
bool isRunningWindowManager();
bool isRunningDesktopEnvironment();

View File

@@ -88,6 +88,45 @@ bool WMUtils::isRunningNvidiaProprietaryDriverX11()
#endif
}
bool WMUtils::supportsDesktopGLWithEGL()
{
#ifdef HAVE_EGL
static SDL_atomic_t supportsDesktopGL;
// If the value is not set yet, populate it now.
int val = SDL_AtomicGet(&supportsDesktopGL);
if (!(val & VALUE_SET)) {
bool desktopGL = false;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display != EGL_NO_DISPLAY && eglInitialize(display, nullptr, nullptr)) {
EGLint matchingConfigs = 0;
EGLint const attribs[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
desktopGL = eglChooseConfig(display, attribs, nullptr, 0, &matchingConfigs) == EGL_TRUE &&
matchingConfigs > 0;
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 | (desktopGL ? VALUE_TRUE : 0);
SDL_AtomicSet(&supportsDesktopGL, val);
}
return !!(val & VALUE_TRUE);
#else
// Assume it does if we can't check ourselves
return true;
#endif
}
bool WMUtils::isRunningWayland()
{
#ifdef HAS_WAYLAND