Use display scaling to improve performance on slow GPUs

This dramatically improves performance for lower resolution
streams on slow GPUs when using the GL and Vulkan renderers.
This commit is contained in:
Cameron Gutman
2025-12-30 15:00:47 -06:00
parent f3f1d56e8d
commit ceef792f04
4 changed files with 46 additions and 12 deletions

View File

@@ -109,8 +109,10 @@ void StreamingPreferences::reload()
#ifdef Q_OS_DARWIN
recommendedFullScreenMode = WindowMode::WM_FULLSCREEN_DESKTOP;
#else
// Wayland doesn't support modesetting, so use fullscreen desktop mode.
if (WMUtils::isRunningWayland()) {
// Wayland doesn't support modesetting, so use fullscreen desktop mode
// unless we have a slow GPU (which can take advantage of wp_viewporter
// to reduce GPU load with lower resolution video streams).
if (WMUtils::isRunningWayland() && !WMUtils::isGpuSlow()) {
recommendedFullScreenMode = WindowMode::WM_FULLSCREEN_DESKTOP;
}
else {

View File

@@ -904,6 +904,13 @@ bool Session::initialize(QQuickWindow* qtWindow)
switch (m_Preferences->windowMode)
{
default:
// Normally we'd default to fullscreen desktop when starting in windowed
// mode, but in the case of a slow GPU, we want to use real fullscreen
// to allow the display to assist with the video scaling work.
if (WMUtils::isGpuSlow()) {
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN;
break;
}
case StreamingPreferences::WM_FULLSCREEN_DESKTOP:
// Only use full-screen desktop mode if we're running a desktop environment
if (WMUtils::isRunningDesktopEnvironment()) {
@@ -1422,19 +1429,28 @@ void Session::updateOptimalWindowDisplayMode()
return;
}
// Start with the native desktop resolution and try to find
// the highest refresh rate that our stream FPS evenly divides.
// On devices with slow GPUs, we will try to match the display mode
// to the video stream to offload the scaling work to the display.
bool matchVideo;
if (!Utils::getEnvironmentVariableOverride("MATCH_DISPLAY_MODE_TO_VIDEO", &matchVideo)) {
matchVideo = WMUtils::isGpuSlow();
}
bestMode = desktopMode;
bestMode.refresh_rate = 0;
for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) {
if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) {
if (mode.w == desktopMode.w && mode.h == desktopMode.h &&
if (!matchVideo) {
// Start with the native desktop resolution and try to find
// the highest refresh rate that our stream FPS evenly divides.
for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) {
if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) {
if (mode.w == desktopMode.w && mode.h == desktopMode.h &&
mode.refresh_rate % m_StreamConfig.fps == 0) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Found display mode with desktop resolution: %dx%dx%d",
mode.w, mode.h, mode.refresh_rate);
if (mode.refresh_rate > bestMode.refresh_rate) {
bestMode = mode;
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Found display mode with desktop resolution: %dx%dx%d",
mode.w, mode.h, mode.refresh_rate);
if (mode.refresh_rate > bestMode.refresh_rate) {
bestMode = mode;
}
}
}
}

View File

@@ -13,6 +13,7 @@ namespace WMUtils {
bool isRunningWindowManager();
bool isRunningDesktopEnvironment();
QString getDrmCardOverride();
bool isGpuSlow();
}
namespace Utils {

View File

@@ -205,6 +205,21 @@ bool WMUtils::isRunningDesktopEnvironment()
#endif
}
bool WMUtils::isGpuSlow()
{
bool ret;
if (!Utils::getEnvironmentVariableOverride("GL_IS_SLOW", &ret)) {
#ifdef GL_IS_SLOW
ret = true;
#else
ret = false;
#endif
}
return ret;
}
QString WMUtils::getDrmCardOverride()
{
#ifdef HAVE_DRM