From 9b14def8826dfaf1b5360fa3f5ab7b169bcb26cf Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <5252246+antheas@users.noreply.github.com> Date: Fri, 25 Oct 2024 23:25:20 +0200 Subject: [PATCH] chore: fix steamui vrr disable to work correctly (#1777) --- spec_files/gamescope/handheld.patch | 240 ++++++++++++++-------------- 1 file changed, 123 insertions(+), 117 deletions(-) diff --git a/spec_files/gamescope/handheld.patch b/spec_files/gamescope/handheld.patch index e7be2d01..2ceed6c7 100644 --- a/spec_files/gamescope/handheld.patch +++ b/spec_files/gamescope/handheld.patch @@ -441,10 +441,43 @@ index 84e05a9..2398535 100644 2.47.0 -From 3c617ddad128e10bf7b54a4585cb2b8990b4ab75 Mon Sep 17 00:00:00 2001 +From 14d19b8d86c485fe57e1489de905c908c67fd77e Mon Sep 17 00:00:00 2001 +From: honjow +Date: Wed, 16 Oct 2024 00:23:58 +0800 +Subject: [PATCH v2 07/12] fix(external): fix crash when using external + touchscreens + +--- + src/wlserver.cpp | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/wlserver.cpp b/src/wlserver.cpp +index 99df8aa..5e8f516 100644 +--- a/src/wlserver.cpp ++++ b/src/wlserver.cpp +@@ -2492,8 +2492,12 @@ static void apply_touchscreen_orientation(double *x, double *y ) + double tx = 0; + double ty = 0; + +- // Use internal screen always for orientation purposes. +- switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )->GetCurrentOrientation() ) ++ auto orientation = GAMESCOPE_PANEL_ORIENTATION_AUTO; ++ if ( GetBackend() && GetBackend()->GetCurrentConnector( ) ) ++ { ++ orientation = GetBackend()->GetCurrentConnector()->GetCurrentOrientation(); ++ } ++ switch ( orientation ) + { + default: + case GAMESCOPE_PANEL_ORIENTATION_AUTO: +-- +2.47.0 + + +From 9e4ee4341a7480a0af883cc47d3c6e6ee91de74a Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Fri, 11 Oct 2024 23:47:59 +0200 -Subject: [PATCH v2 07/12] feat(vrr): allow for setting refresh rate if the +Subject: [PATCH v2 08/12] feat(vrr): allow for setting refresh rate if the internal display allows For the Ally, we have a set of VFP that work to set the refresh rate. @@ -518,10 +551,10 @@ index da3115f..69fd348 100644 2.47.0 -From ce28da4b8a658dd6db821dc06d9ff6135e803b1f Mon Sep 17 00:00:00 2001 +From dc2d5db6f62ac4c5a160d200be346100d923b1c3 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Fri, 11 Oct 2024 19:09:05 +0200 -Subject: [PATCH v2 08/12] feat: add external option that now only lies to +Subject: [PATCH v2 09/12] feat: add external option that now only lies to steam Previously, there was a force-panel option that allowed for VRR. @@ -603,7 +636,7 @@ index 9f384c4..30e48e8 100644 extern uint32_t inputCounter; diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 99df8aa..39010ab 100644 +index 5e8f516..1eeaa25 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp @@ -1078,7 +1078,7 @@ static uint32_t get_conn_display_info_flags() @@ -631,10 +664,10 @@ index 0569472..104f7a2 100644 2.47.0 -From 6052b5ec29da422aad5b4041adf4aac06d85d5ac Mon Sep 17 00:00:00 2001 +From b8e8677a811bbebe5f0f743ac22da7a83436d443 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Mon, 14 Oct 2024 22:42:20 +0200 -Subject: [PATCH v2 09/12] fix(display-config): always fill in mutable refresh +Subject: [PATCH v2 10/12] fix(display-config): always fill in mutable refresh rates Assume the user is not lying to us when they fill in dynamic_refresh_rates @@ -663,67 +696,70 @@ index 75c3258..f014be9 100644 2.47.0 -From 61caa612131a2e0d01e5dc25210ea89a5dd56827 Mon Sep 17 00:00:00 2001 +From 2d96bb5b3fc75690d60249a8e8ea29f3c667ef55 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis -Date: Tue, 15 Oct 2024 01:20:47 +0200 -Subject: [PATCH v2 10/12] fix(vrr): allow frame limiter to work with VRR +Date: Fri, 25 Oct 2024 21:22:10 +0200 +Subject: [PATCH v2 11/12] fix(vrr): allow frame limiter to work with VRR enabled Down to 48hz, modeset the correct framerate. Below 48hz, disable VRR and use the classic frame limiter. --- - src/steamcompmgr.cpp | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) + src/steamcompmgr.cpp | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp -index 3dd64f8..19f2c4a 100644 +index 3dd64f8..7dacfe7 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp -@@ -149,6 +149,7 @@ extern int g_nDynamicRefreshHz; - bool g_bForceHDRSupportDebug = false; - bool g_bHackyEnabled = false; - bool g_bVRRModesetting = false; -+bool vrr_requested = false; - extern float g_flInternalDisplayBrightnessNits; - extern float g_flHDRItmSdrNits; - extern float g_flHDRItmTargetNits; -@@ -827,6 +828,25 @@ static void _update_app_target_refresh_cycle() +@@ -165,6 +165,7 @@ uint32_t g_reshade_technique_idx = 0; + + bool g_bSteamIsActiveWindow = false; + bool g_bForceInternal = false; ++bool g_bVRRRequested = false; + + static std::vector< steamcompmgr_win_t* > GetGlobalPossibleFocusWindows(); + static bool +@@ -827,6 +828,28 @@ static void _update_app_target_refresh_cycle() { auto rates = GetBackend()->GetCurrentConnector()->GetValidDynamicRefreshRates(); -+ auto vrr = g_bVRRModesetting && vrr_requested; -+ if (vrr) { -+ // If modeset VRR, go upwards to match the refresh rate 1-1. Refresh -+ // doubling would hurt us here by breaking the frame limiter. -+ for ( auto rate = rates.begin(); rate != rates.end(); rate++ ) -+ { -+ if ((int)*rate == target_fps) ++ if (g_bVRRModesetting) { ++ if (g_bVRRRequested) { ++ // If modeset VRR, go upwards to match the refresh rate 1-1. Refresh ++ // doubling would hurt us here by breaking the frame limiter. ++ for ( auto rate = rates.begin(); rate != rates.end(); rate++ ) + { -+ g_nDynamicRefreshRate[ type ] = *rate; -+ // Enable VRR as we have the correct refresh rate -+ cv_adaptive_sync = vrr_requested; -+ return; ++ if ((int)*rate == target_fps) ++ { ++ g_nDynamicRefreshRate[ type ] = *rate; ++ // Enable VRR as we have the correct refresh rate ++ cv_adaptive_sync = true; ++ return; ++ } + } ++ // Otherwise, disable VRR as we can't match the refresh rate 1-1 ++ // (e.g., below 48hz). ++ cv_adaptive_sync = false; ++ } else { ++ cv_adaptive_sync = false; + } -+ // Otherwise, disable VRR as we can't match the refresh rate 1-1 -+ // (e.g., below 48hz). -+ cv_adaptive_sync = false; + } + // Find highest mode to do refresh doubling with. for ( auto rate = rates.rbegin(); rate != rates.rend(); rate++ ) { -@@ -5522,8 +5542,11 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) +@@ -5522,8 +5545,11 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) } if ( ev->atom == ctx->atoms.gamescopeVRREnabled ) { - bool enabled = !!get_prop( ctx, ctx->root, ctx->atoms.gamescopeVRREnabled, 0 ); - cv_adaptive_sync = enabled; -+ vrr_requested = !!get_prop( ctx, ctx->root, ctx->atoms.gamescopeVRREnabled, 0 ); ++ g_bVRRRequested = !!get_prop( ctx, ctx->root, ctx->atoms.gamescopeVRREnabled, 0 ); + // Try to match refresh rate and have that set the cv_adaptive_sync only if it can + if (g_bVRRModesetting) update_app_target_refresh_cycle(); + // otherwise, fall back to original behavior -+ else cv_adaptive_sync = vrr_requested; ++ else cv_adaptive_sync = g_bVRRRequested; } if ( ev->atom == ctx->atoms.gamescopeDisplayForceInternal ) { @@ -731,18 +767,18 @@ index 3dd64f8..19f2c4a 100644 2.47.0 -From 3397e56f3d77774502c3a98382326b18db281c1b Mon Sep 17 00:00:00 2001 +From 61ea8edafedd5c8cce320bf6415e6151555ce594 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Wed, 23 Oct 2024 23:33:53 +0200 -Subject: [PATCH v2 11/12] fix(battery): run at half hz while at steamUI and +Subject: [PATCH v2 12/12] fix(battery): run at half hz while at steamUI and disable VRR --- - src/steamcompmgr.cpp | 35 +++++++++++++++++++++++++---------- - 1 file changed, 25 insertions(+), 10 deletions(-) + src/steamcompmgr.cpp | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp -index 19f2c4a..c7be2b2 100644 +index 7dacfe7..f4446f0 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -149,6 +149,7 @@ extern int g_nDynamicRefreshHz; @@ -750,33 +786,38 @@ index 19f2c4a..c7be2b2 100644 bool g_bHackyEnabled = false; bool g_bVRRModesetting = false; +bool g_refreshHalve = false; - bool vrr_requested = false; extern float g_flInternalDisplayBrightnessNits; extern float g_flHDRItmSdrNits; -@@ -2264,7 +2265,7 @@ bool ShouldDrawCursor() - } + extern float g_flHDRItmTargetNits; +@@ -166,6 +167,7 @@ uint32_t g_reshade_technique_idx = 0; + bool g_bSteamIsActiveWindow = false; + bool g_bForceInternal = false; + bool g_bVRRRequested = false; ++bool g_bVRRCanEnable = false; - static void --paint_all(bool async) -+paint_all(bool async, bool vrr) - { - gamescope_xwayland_server_t *root_server = wlserver_get_xwayland_server(0); - xwayland_ctx_t *root_ctx = root_server->ctx.get(); -@@ -2313,7 +2314,7 @@ paint_all(bool async) - struct FrameInfo_t frameInfo = {}; - frameInfo.applyOutputColorMgmt = g_ColorMgmt.pending.enabled; - frameInfo.outputEncodingEOTF = g_ColorMgmt.pending.outputEncodingEOTF; -- frameInfo.allowVRR = cv_adaptive_sync; -+ frameInfo.allowVRR = vrr; - frameInfo.bFadingOut = fadingOut; + static std::vector< steamcompmgr_win_t* > GetGlobalPossibleFocusWindows(); + static bool +@@ -838,15 +840,15 @@ static void _update_app_target_refresh_cycle() + { + g_nDynamicRefreshRate[ type ] = *rate; + // Enable VRR as we have the correct refresh rate +- cv_adaptive_sync = true; ++ g_bVRRCanEnable = true; + return; + } + } + // Otherwise, disable VRR as we can't match the refresh rate 1-1 + // (e.g., below 48hz). +- cv_adaptive_sync = false; ++ g_bVRRCanEnable = false; + } else { +- cv_adaptive_sync = false; ++ g_bVRRCanEnable = false; + } + } - // If the window we'd paint as the base layer is the streaming client, -@@ -5099,22 +5100,27 @@ steamcompmgr_flush_frame_done( steamcompmgr_win_t *w ) - - static bool steamcompmgr_should_vblank_window( bool bShouldLimitFPS, uint64_t vblank_idx ) - { -- if ( GetBackend()->IsVRRActive() ) -+ if ( GetBackend()->IsVRRActive() && !g_refreshHalve ) +@@ -5105,19 +5107,24 @@ static bool steamcompmgr_should_vblank_window( bool bShouldLimitFPS, uint64_t vb + if ( GetBackend()->IsVRRActive() ) return true; - bool bSendCallback = true; @@ -805,66 +846,31 @@ index 19f2c4a..c7be2b2 100644 } static bool steamcompmgr_should_vblank_window( steamcompmgr_win_t *w, uint64_t vblank_idx ) -@@ -7626,7 +7632,16 @@ steamcompmgr_main(int argc, char **argv) +@@ -5549,7 +5556,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) + // Try to match refresh rate and have that set the cv_adaptive_sync only if it can + if (g_bVRRModesetting) update_app_target_refresh_cycle(); + // otherwise, fall back to original behavior +- else cv_adaptive_sync = g_bVRRRequested; ++ else g_bVRRCanEnable = g_bVRRRequested; + } + if ( ev->atom == ctx->atoms.gamescopeDisplayForceInternal ) + { +@@ -7628,6 +7635,15 @@ steamcompmgr_main(int argc, char **argv) + // as a question. const bool bIsVBlankFromTimer = vblank; - // We can always vblank if VRR. -- const bool bVRR = GetBackend()->IsVRRActive(); -+ bool bVRR = GetBackend()->IsVRRActive(); -+ + if ( window_is_steam( global_focus.focusWindow ) ) { + // Halve refresh rate and disable vrr on SteamUI -+ bVRR = false; ++ cv_adaptive_sync = false; + g_refreshHalve = true; + } else { ++ cv_adaptive_sync = g_bVRRCanEnable; + g_refreshHalve = false; + } + + // We can always vblank if VRR. + const bool bVRR = GetBackend()->IsVRRActive(); if ( bVRR ) - vblank = true; - -@@ -8033,7 +8048,7 @@ steamcompmgr_main(int argc, char **argv) - - if ( bShouldPaint ) - { -- paint_all( eFlipType == FlipType::Async ); -+ paint_all( eFlipType == FlipType::Async, bVRR ); - - hasRepaint = false; - hasRepaintNonBasePlane = false; --- -2.47.0 - - -From 8cbded10cf984b4580c3e31bb321a30385e7b105 Mon Sep 17 00:00:00 2001 -From: honjow -Date: Wed, 16 Oct 2024 00:23:58 +0800 -Subject: [PATCH v2 12/12] fix(external): fix crash when using external - touchscreens - ---- - src/wlserver.cpp | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 39010ab..1eeaa25 100644 ---- a/src/wlserver.cpp -+++ b/src/wlserver.cpp -@@ -2492,8 +2492,12 @@ static void apply_touchscreen_orientation(double *x, double *y ) - double tx = 0; - double ty = 0; - -- // Use internal screen always for orientation purposes. -- switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )->GetCurrentOrientation() ) -+ auto orientation = GAMESCOPE_PANEL_ORIENTATION_AUTO; -+ if ( GetBackend() && GetBackend()->GetCurrentConnector( ) ) -+ { -+ orientation = GetBackend()->GetCurrentConnector()->GetCurrentOrientation(); -+ } -+ switch ( orientation ) - { - default: - case GAMESCOPE_PANEL_ORIENTATION_AUTO: -- 2.47.0