mirror of
https://github.com/ublue-os/bazzite.git
synced 2025-01-29 00:32:52 +00:00
1169 lines
43 KiB
Diff
1169 lines
43 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 22 Nov 2024 01:37:48 +0100
|
|
Subject: [NA] add dev script
|
|
|
|
---
|
|
subprojects/edid-decode | 1 +
|
|
sync.sh | 21 +++++++++++++++++++++
|
|
2 files changed, 22 insertions(+)
|
|
create mode 160000 subprojects/edid-decode
|
|
create mode 100755 sync.sh
|
|
|
|
diff --git a/subprojects/edid-decode b/subprojects/edid-decode
|
|
new file mode 160000
|
|
index 0000000..c6b859d
|
|
--- /dev/null
|
|
+++ b/subprojects/edid-decode
|
|
@@ -0,0 +1 @@
|
|
+Subproject commit c6b859d7f0251e2433fb81bd3f67bd2011c2036c
|
|
diff --git a/sync.sh b/sync.sh
|
|
new file mode 100755
|
|
index 0000000..878bf6c
|
|
--- /dev/null
|
|
+++ b/sync.sh
|
|
@@ -0,0 +1,21 @@
|
|
+if [ -z "$1" ]; then
|
|
+ echo "Usage: $0 <host>"
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+HOST=$1
|
|
+RSYNC="rsync -rv --exclude .git --exclude venv --exclude __pycache__'"
|
|
+USER=${USER:-bazzite}
|
|
+
|
|
+set -e
|
|
+
|
|
+meson build/ -Dforce_fallback_for=stb,libdisplay-info,libliftoff,wlroots,vkroots
|
|
+ninja -C build/
|
|
+scp build/src/gamescope ${HOST}:gamescope
|
|
+
|
|
+ssh $HOST /bin/bash << EOF
|
|
+ sudo rpm-ostree usroverlay --hotfix
|
|
+ sudo mv ~/gamescope /usr/bin/gamescope
|
|
+ bazzite-session-select gamescope
|
|
+ # sudo reboot
|
|
+EOF
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Matthew Anderson <ruinairas1992@gmail.com>
|
|
Date: Fri, 17 May 2024 21:56:55 -0500
|
|
Subject: feat: add --custom-refresh-rates option (+ fixes)
|
|
|
|
Commit originally by Matthew, external fixes by Kyle, and new system check
|
|
move by Antheas.
|
|
|
|
Co-authored-by: Kyle Gospodnetich <me@kylegospodneti.ch>
|
|
Co-authored-by: Antheas Kapenekakis <git@antheas.dev>
|
|
---
|
|
src/Backends/DRMBackend.cpp | 5 +++++
|
|
src/main.cpp | 31 +++++++++++++++++++++++++++++++
|
|
src/main.hpp | 2 ++
|
|
3 files changed, 38 insertions(+)
|
|
|
|
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
|
|
index 0b121e8..75c3258 100644
|
|
--- a/src/Backends/DRMBackend.cpp
|
|
+++ b/src/Backends/DRMBackend.cpp
|
|
@@ -2243,6 +2243,11 @@ namespace gamescope
|
|
bHasKnownHDRInfo = true;
|
|
}
|
|
}
|
|
+ else if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) {
|
|
+ // Only apply custom refresh rates as a fallback, allowing a graceful transition to the new system.
|
|
+ m_Mutable.ValidDynamicRefreshRates = g_customRefreshRates;
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
if ( !bHasKnownColorimetry )
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index 9dff5c4..8381889 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -129,6 +129,7 @@ const struct option *gamescope_options = (struct option[]){
|
|
{ "fade-out-duration", required_argument, nullptr, 0 },
|
|
{ "force-orientation", required_argument, nullptr, 0 },
|
|
{ "force-windows-fullscreen", no_argument, nullptr, 0 },
|
|
+ { "custom-refresh-rates", required_argument, nullptr, 0 },
|
|
|
|
{ "disable-color-management", no_argument, nullptr, 0 },
|
|
{ "sdr-gamut-wideness", required_argument, nullptr, 0 },
|
|
@@ -202,6 +203,7 @@ const char usage[] =
|
|
" --hdr-itm-target-nits set the target luminace of the inverse tone mapping process.\n"
|
|
" Default: 1000 nits, Max: 10000 nits\n"
|
|
" --framerate-limit Set a simple framerate limit. Used as a divisor of the refresh rate, rounds down eg 60 / 59 -> 60fps, 60 / 25 -> 30fps. Default: 0, disabled.\n"
|
|
+ " --custom-refresh-rates Set custom refresh rates for the output. eg: 60,90,110-120\n"
|
|
" --mangoapp Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.\n"
|
|
"\n"
|
|
"Nested mode options:\n"
|
|
@@ -425,6 +427,33 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str)
|
|
}
|
|
}
|
|
|
|
+std::vector<uint32_t> g_customRefreshRates;
|
|
+// eg: 60,60,90,110-120
|
|
+static std::vector<uint32_t> parse_custom_refresh_rates( const char *str )
|
|
+{
|
|
+ std::vector<uint32_t> rates;
|
|
+ char *token = strtok( strdup(str), ",");
|
|
+ while (token)
|
|
+ {
|
|
+ char *dash = strchr(token, '-');
|
|
+ if (dash)
|
|
+ {
|
|
+ uint32_t start = atoi(token);
|
|
+ uint32_t end = atoi(dash + 1);
|
|
+ for (uint32_t i = start; i <= end; i++)
|
|
+ {
|
|
+ rates.push_back(i);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ rates.push_back(atoi(token));
|
|
+ }
|
|
+ token = strtok(nullptr, ",");
|
|
+ }
|
|
+ return rates;
|
|
+}
|
|
+
|
|
struct sigaction handle_signal_action = {};
|
|
|
|
void ShutdownGamescope()
|
|
@@ -746,6 +775,8 @@ int main(int argc, char **argv)
|
|
g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg );
|
|
} else if (strcmp(opt_name, "force-orientation") == 0) {
|
|
g_DesiredInternalOrientation = force_orientation( optarg );
|
|
+ } else if (strcmp(opt_name, "custom-refresh-rates") == 0) {
|
|
+ g_customRefreshRates = parse_custom_refresh_rates( optarg );
|
|
} else if (strcmp(opt_name, "sharpness") == 0 ||
|
|
strcmp(opt_name, "fsr-sharpness") == 0) {
|
|
g_upscaleFilterSharpness = atoi( optarg );
|
|
diff --git a/src/main.hpp b/src/main.hpp
|
|
index 2e6fb83..390c04a 100644
|
|
--- a/src/main.hpp
|
|
+++ b/src/main.hpp
|
|
@@ -3,6 +3,7 @@
|
|
#include <getopt.h>
|
|
|
|
#include <atomic>
|
|
+#include <vector>
|
|
|
|
extern const char *gamescope_optstring;
|
|
extern const struct option *gamescope_options;
|
|
@@ -28,6 +29,7 @@ extern bool g_bGrabbed;
|
|
|
|
extern float g_mouseSensitivity;
|
|
extern const char *g_sOutputName;
|
|
+extern std::vector<uint32_t> g_customRefreshRates;
|
|
|
|
enum class GamescopeUpscaleFilter : uint32_t
|
|
{
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alesh Slovak <alesh@playtron.one>
|
|
Date: Thu, 26 Sep 2024 07:13:24 -0400
|
|
Subject: fix(vrr): Revert "steamcompmgr: Move outdatedInteractiveFocus to
|
|
window"
|
|
|
|
This reverts commit 299bc3410dcfd46da5e3c988354b60ed3a356900.
|
|
---
|
|
src/steamcompmgr.cpp | 39 +++++++++++++++++++++++--------------
|
|
src/steamcompmgr_shared.hpp | 1 -
|
|
2 files changed, 24 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 11a7cad..df7616d 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -3299,7 +3299,7 @@ found:;
|
|
if ( window_has_commits( focus ) )
|
|
out->focusWindow = focus;
|
|
else
|
|
- focus->outdatedInteractiveFocus = true;
|
|
+ out->outdatedInteractiveFocus = true;
|
|
|
|
// Always update X's idea of focus, but still dirty
|
|
// the it being outdated so we can resolve that globally later.
|
|
@@ -6044,28 +6044,37 @@ bool handle_done_commit( steamcompmgr_win_t *w, xwayland_ctx_t *ctx, uint64_t co
|
|
// Window just got a new available commit, determine if that's worth a repaint
|
|
|
|
// If this is an overlay that we're presenting, repaint
|
|
- if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
|
|
+ if ( gameFocused )
|
|
{
|
|
- hasRepaintNonBasePlane = true;
|
|
- }
|
|
+ if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
|
|
+ {
|
|
+ hasRepaintNonBasePlane = true;
|
|
+ }
|
|
|
|
- if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
|
|
- {
|
|
- hasRepaintNonBasePlane = true;
|
|
+ if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
|
|
+ {
|
|
+ hasRepaintNonBasePlane = true;
|
|
+ }
|
|
}
|
|
-
|
|
- // If this is an external overlay, repaint
|
|
- if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
|
|
+ if ( ctx )
|
|
{
|
|
- hasRepaintNonBasePlane = true;
|
|
+ if ( ctx->focus.outdatedInteractiveFocus )
|
|
+ {
|
|
+ MakeFocusDirty();
|
|
+ ctx->focus.outdatedInteractiveFocus = false;
|
|
+ }
|
|
}
|
|
-
|
|
- if ( w->outdatedInteractiveFocus )
|
|
+ if ( global_focus.outdatedInteractiveFocus )
|
|
{
|
|
MakeFocusDirty();
|
|
- w->outdatedInteractiveFocus = false;
|
|
- }
|
|
+ global_focus.outdatedInteractiveFocus = false;
|
|
|
|
+ // If this is an external overlay, repaint
|
|
+ if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
|
|
+ {
|
|
+ hasRepaintNonBasePlane = true;
|
|
+ }
|
|
+ }
|
|
// If this is the main plane, repaint
|
|
if ( w == global_focus.focusWindow && !w->isSteamStreamingClient )
|
|
{
|
|
diff --git a/src/steamcompmgr_shared.hpp b/src/steamcompmgr_shared.hpp
|
|
index 095694e..e41fad9 100644
|
|
--- a/src/steamcompmgr_shared.hpp
|
|
+++ b/src/steamcompmgr_shared.hpp
|
|
@@ -125,7 +125,6 @@ struct steamcompmgr_win_t {
|
|
unsigned int requestedHeight = 0;
|
|
bool is_dialog = false;
|
|
bool maybe_a_dropdown = false;
|
|
- bool outdatedInteractiveFocus = false;
|
|
|
|
bool hasHwndStyle = false;
|
|
uint32_t hwndStyle = 0;
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Renn <8340896+AkazaRenn@users.noreply.github.com>
|
|
Date: Fri, 11 Oct 2024 17:48:26 +0200
|
|
Subject: fix(deck): Use super + 1/2 for Overlay/QAM
|
|
|
|
Replaces the patch for CTRL + 1/2 for Overlay/QAM with Super + 1/2 and
|
|
allows for CTRL for a smooth transition.
|
|
|
|
Suggested-by: Antheas Kapenekakis <git@antheas.dev>
|
|
---
|
|
src/wlserver.cpp | 19 ++++++++++++++++++-
|
|
1 file changed, 18 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
|
|
index 78a86ee..99df8aa 100644
|
|
--- a/src/wlserver.cpp
|
|
+++ b/src/wlserver.cpp
|
|
@@ -290,6 +290,9 @@ static void wlserver_handle_modifiers(struct wl_listener *listener, void *data)
|
|
bump_input_counter();
|
|
}
|
|
|
|
+// false if GS_ENABLE_CTRL_12 exists and is 0, true otherwise
|
|
+bool env_gs_enable_ctrl_12 = getenv("GS_ENABLE_CTRL_12") ? (getenv("GS_ENABLE_CTRL_12")[0] != '0') : true;
|
|
+
|
|
static void wlserver_handle_key(struct wl_listener *listener, void *data)
|
|
{
|
|
struct wlserver_keyboard *keyboard = wl_container_of( listener, keyboard, key );
|
|
@@ -310,7 +313,14 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
|
|
keysym == XKB_KEY_XF86AudioLowerVolume ||
|
|
keysym == XKB_KEY_XF86AudioRaiseVolume ||
|
|
keysym == XKB_KEY_XF86PowerOff;
|
|
- if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && forbidden_key )
|
|
+
|
|
+ // Check for steam overlay key (ctrl/super + 1/2)
|
|
+ bool is_steamshortcut =
|
|
+ ((env_gs_enable_ctrl_12 && (keyboard->wlr->modifiers.depressed & WLR_MODIFIER_CTRL)) ||
|
|
+ (keyboard->wlr->modifiers.depressed & WLR_MODIFIER_LOGO)) &&
|
|
+ (keysym == XKB_KEY_1 || keysym == XKB_KEY_2);
|
|
+
|
|
+ if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && (forbidden_key || is_steamshortcut) )
|
|
{
|
|
// Always send volume+/- to root server only, to avoid it reaching the game.
|
|
struct wlr_surface *old_kb_surf = wlserver.kb_focus_surface;
|
|
@@ -319,6 +329,13 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
|
|
{
|
|
wlserver_keyboardfocus( new_kb_surf, false );
|
|
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
|
|
+ if (is_steamshortcut)
|
|
+ {
|
|
+ // send ctrl down modifier to trigger the overlay
|
|
+ wlr_keyboard_modifiers ctrl_down_modifier;
|
|
+ ctrl_down_modifier.depressed = WLR_MODIFIER_CTRL;
|
|
+ wlr_seat_keyboard_notify_modifiers(wlserver.wlr.seat, &ctrl_down_modifier);
|
|
+ }
|
|
wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );
|
|
wlserver_keyboardfocus( old_kb_surf, false );
|
|
return;
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 11 Oct 2024 17:52:48 +0200
|
|
Subject: fix: allow for disabling touch atom click
|
|
|
|
Causes issues in certain devices (or not anymore?).
|
|
|
|
Parameter option by Kyle.
|
|
|
|
Co-authored-by: Kyle Gospodnetich <me@kylegospodneti.ch>
|
|
---
|
|
src/main.cpp | 2 ++
|
|
src/steamcompmgr.cpp | 5 ++++-
|
|
2 files changed, 6 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index 8381889..a76b51b 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -128,6 +128,7 @@ const struct option *gamescope_options = (struct option[]){
|
|
{ "disable-xres", no_argument, nullptr, 'x' },
|
|
{ "fade-out-duration", required_argument, nullptr, 0 },
|
|
{ "force-orientation", required_argument, nullptr, 0 },
|
|
+ { "disable-touch-click", no_argument, nullptr, 0 },
|
|
{ "force-windows-fullscreen", no_argument, nullptr, 0 },
|
|
{ "custom-refresh-rates", required_argument, nullptr, 0 },
|
|
|
|
@@ -188,6 +189,7 @@ const char usage[] =
|
|
" -T, --stats-path write statistics to path\n"
|
|
" -C, --hide-cursor-delay hide cursor image after delay\n"
|
|
" -e, --steam enable Steam integration\n"
|
|
+ " --disable-touch-click disable touchscreen tap acting as a click\n"
|
|
" --xwayland-count create N xwayland servers\n"
|
|
" --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
|
|
" --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index df7616d..4a17499 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -197,6 +197,7 @@ update_runtime_info();
|
|
gamescope::ConVar<bool> cv_adaptive_sync( "adaptive_sync", false, "Whether or not adaptive sync is enabled if available." );
|
|
gamescope::ConVar<bool> cv_adaptive_sync_ignore_overlay( "adaptive_sync_ignore_overlay", false, "Whether or not to ignore overlay planes for pushing commits with adaptive sync." );
|
|
gamescope::ConVar<int> cv_adaptive_sync_overlay_cycles( "adaptive_sync_overlay_cycles", 1, "Number of vblank cycles to ignore overlay repaints before forcing a commit with adaptive sync." );
|
|
+gamescope::ConVar<bool> cv_disable_touch_click{ "disable_touch_click", false, "Prevents touchscreen taps acting as clicks" };
|
|
|
|
uint64_t g_SteamCompMgrLimitedAppRefreshCycle = 16'666'666;
|
|
uint64_t g_SteamCompMgrAppRefreshCycle = 16'666'666;
|
|
@@ -5185,7 +5186,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|
MakeFocusDirty();
|
|
}
|
|
}
|
|
- if (ev->atom == ctx->atoms.steamTouchClickModeAtom )
|
|
+ if (ev->atom == ctx->atoms.steamTouchClickModeAtom && !cv_disable_touch_click )
|
|
{
|
|
gamescope::cv_touch_click_mode = (gamescope::TouchClickMode) get_prop(ctx, ctx->root, ctx->atoms.steamTouchClickModeAtom, 0u );
|
|
}
|
|
@@ -7476,6 +7477,8 @@ steamcompmgr_main(int argc, char **argv)
|
|
g_reshade_technique_idx = atoi(optarg);
|
|
} else if (strcmp(opt_name, "mura-map") == 0) {
|
|
set_mura_overlay(optarg);
|
|
+ } else if (strcmp(opt_name, "disable-touch-click") == 0) {
|
|
+ cv_disable_touch_click = true;
|
|
}
|
|
break;
|
|
case '?':
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 11 Oct 2024 21:56:54 +0200
|
|
Subject: fix(intel-gpu): allow for (enabling) hacky texture
|
|
|
|
Disabling hacky texture will use more hardware planes, causing some devices to composite yielding lower fps. Required for intel to work
|
|
---
|
|
src/main.cpp | 2 ++
|
|
src/steamcompmgr.cpp | 5 ++++-
|
|
2 files changed, 6 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index a76b51b..84e05a9 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -128,6 +128,7 @@ const struct option *gamescope_options = (struct option[]){
|
|
{ "disable-xres", no_argument, nullptr, 'x' },
|
|
{ "fade-out-duration", required_argument, nullptr, 0 },
|
|
{ "force-orientation", required_argument, nullptr, 0 },
|
|
+ { "enable-hacky-texture", no_argument, nullptr, 0 },
|
|
{ "disable-touch-click", no_argument, nullptr, 0 },
|
|
{ "force-windows-fullscreen", no_argument, nullptr, 0 },
|
|
{ "custom-refresh-rates", required_argument, nullptr, 0 },
|
|
@@ -189,6 +190,7 @@ const char usage[] =
|
|
" -T, --stats-path write statistics to path\n"
|
|
" -C, --hide-cursor-delay hide cursor image after delay\n"
|
|
" -e, --steam enable Steam integration\n"
|
|
+ " --enable-hacky-texture enable hacky texture on hw that support it\n"
|
|
" --disable-touch-click disable touchscreen tap acting as a click\n"
|
|
" --xwayland-count create N xwayland servers\n"
|
|
" --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 4a17499..da3115f 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -147,6 +147,7 @@ static lut3d_t g_tmpLut3d;
|
|
extern int g_nDynamicRefreshHz;
|
|
|
|
bool g_bForceHDRSupportDebug = false;
|
|
+bool g_bHackyEnabled = false;
|
|
extern float g_flInternalDisplayBrightnessNits;
|
|
extern float g_flHDRItmSdrNits;
|
|
extern float g_flHDRItmTargetNits;
|
|
@@ -2412,7 +2413,7 @@ paint_all(bool async)
|
|
if ( overlay == global_focus.inputFocusWindow )
|
|
update_touch_scaling( &frameInfo );
|
|
}
|
|
- else if ( !GetBackend()->UsesVulkanSwapchain() && GetBackend()->IsSessionBased() )
|
|
+ else if ( g_bHackyEnabled && !GetBackend()->UsesVulkanSwapchain() && GetBackend()->IsSessionBased() )
|
|
{
|
|
auto tex = vulkan_get_hacky_blank_texture();
|
|
if ( tex != nullptr )
|
|
@@ -7479,6 +7480,8 @@ steamcompmgr_main(int argc, char **argv)
|
|
set_mura_overlay(optarg);
|
|
} else if (strcmp(opt_name, "disable-touch-click") == 0) {
|
|
cv_disable_touch_click = true;
|
|
+ } else if (strcmp(opt_name, "enable-hacky-texture") == 0) {
|
|
+ g_bHackyEnabled = true;
|
|
}
|
|
break;
|
|
case '?':
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 11 Oct 2024 23:01:13 +0200
|
|
Subject: fix: re-add external orientation options to not break current
|
|
sessions (incl. applying ext. orientation)
|
|
|
|
---
|
|
src/main.cpp | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index 84e05a9..2398535 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -129,6 +129,8 @@ const struct option *gamescope_options = (struct option[]){
|
|
{ "fade-out-duration", required_argument, nullptr, 0 },
|
|
{ "force-orientation", required_argument, nullptr, 0 },
|
|
{ "enable-hacky-texture", no_argument, nullptr, 0 },
|
|
+ { "force-panel-type", required_argument, nullptr, 0 },
|
|
+ { "force-external-orientation", required_argument, nullptr, 0 },
|
|
{ "disable-touch-click", no_argument, nullptr, 0 },
|
|
{ "force-windows-fullscreen", no_argument, nullptr, 0 },
|
|
{ "custom-refresh-rates", required_argument, nullptr, 0 },
|
|
@@ -777,7 +779,7 @@ int main(int argc, char **argv)
|
|
gamescope::cv_touch_click_mode = (gamescope::TouchClickMode) atoi( optarg );
|
|
} else if (strcmp(opt_name, "generate-drm-mode") == 0) {
|
|
g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg );
|
|
- } else if (strcmp(opt_name, "force-orientation") == 0) {
|
|
+ } else if (strcmp(opt_name, "force-orientation") == 0 || strcmp(opt_name, "force-external-orientation") == 0) {
|
|
g_DesiredInternalOrientation = force_orientation( optarg );
|
|
} else if (strcmp(opt_name, "custom-refresh-rates") == 0) {
|
|
g_customRefreshRates = parse_custom_refresh_rates( optarg );
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: honjow <honjow311@gmail.com>
|
|
Date: Wed, 16 Oct 2024 00:23:58 +0800
|
|
Subject: 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 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 11 Oct 2024 23:47:59 +0200
|
|
Subject: 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.
|
|
They can also be used for VRR but gamescope does not currently allow for
|
|
it. Therefore, bypass some checks to allow it to work just for this usecase.
|
|
---
|
|
src/main.cpp | 2 ++
|
|
src/steamcompmgr.cpp | 7 +++++--
|
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index 2398535..0621c65 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -132,6 +132,7 @@ const struct option *gamescope_options = (struct option[]){
|
|
{ "force-panel-type", required_argument, nullptr, 0 },
|
|
{ "force-external-orientation", required_argument, nullptr, 0 },
|
|
{ "disable-touch-click", no_argument, nullptr, 0 },
|
|
+ { "enable-vrr-modesetting", no_argument, nullptr, 0 },
|
|
{ "force-windows-fullscreen", no_argument, nullptr, 0 },
|
|
{ "custom-refresh-rates", required_argument, nullptr, 0 },
|
|
|
|
@@ -194,6 +195,7 @@ const char usage[] =
|
|
" -e, --steam enable Steam integration\n"
|
|
" --enable-hacky-texture enable hacky texture on hw that support it\n"
|
|
" --disable-touch-click disable touchscreen tap acting as a click\n"
|
|
+ " --enable-vrr-modesetting enable setting framerate while VRR is on in the internal display\n"
|
|
" --xwayland-count create N xwayland servers\n"
|
|
" --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
|
|
" --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index da3115f..69fd348 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -148,6 +148,7 @@ extern int g_nDynamicRefreshHz;
|
|
|
|
bool g_bForceHDRSupportDebug = false;
|
|
bool g_bHackyEnabled = false;
|
|
+bool g_bVRRModesetting = false;
|
|
extern float g_flInternalDisplayBrightnessNits;
|
|
extern float g_flHDRItmSdrNits;
|
|
extern float g_flHDRItmTargetNits;
|
|
@@ -899,7 +900,7 @@ bool g_bChangeDynamicRefreshBasedOnGameOpenRatherThanActive = false;
|
|
bool steamcompmgr_window_should_limit_fps( steamcompmgr_win_t *w )
|
|
{
|
|
// VRR + FPS Limit needs another approach.
|
|
- if ( GetBackend()->IsVRRActive() )
|
|
+ if ( GetBackend()->IsVRRActive() && !(g_bVRRModesetting && GetBackend()->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL) )
|
|
return false;
|
|
|
|
return w && !window_is_steam( w ) && !w->isOverlay && !w->isExternalOverlay;
|
|
@@ -923,7 +924,7 @@ steamcompmgr_user_has_any_game_open()
|
|
|
|
bool steamcompmgr_window_should_refresh_switch( steamcompmgr_win_t *w )
|
|
{
|
|
- if ( GetBackend()->IsVRRActive() )
|
|
+ if ( GetBackend()->IsVRRActive() && !(g_bVRRModesetting && GetBackend()->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL))
|
|
return false;
|
|
|
|
if ( g_bChangeDynamicRefreshBasedOnGameOpenRatherThanActive )
|
|
@@ -7480,6 +7481,8 @@ steamcompmgr_main(int argc, char **argv)
|
|
set_mura_overlay(optarg);
|
|
} else if (strcmp(opt_name, "disable-touch-click") == 0) {
|
|
cv_disable_touch_click = true;
|
|
+ } else if (strcmp(opt_name, "enable-vrr-modesetting") == 0) {
|
|
+ g_bVRRModesetting = true;
|
|
} else if (strcmp(opt_name, "enable-hacky-texture") == 0) {
|
|
g_bHackyEnabled = true;
|
|
}
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 11 Oct 2024 19:09:05 +0200
|
|
Subject: feat: add external option that now only lies to steam
|
|
|
|
Previously, there was a force-panel option that allowed for VRR.
|
|
However, this is no longer the case and VRR works fine.
|
|
This option still allows for scaling the display though. So, create a
|
|
variant of the patch that only does that.
|
|
---
|
|
src/main.cpp | 16 ++++++++++++++++
|
|
src/steamcompmgr.cpp | 2 +-
|
|
src/steamcompmgr.hpp | 1 +
|
|
src/wlserver.cpp | 2 +-
|
|
src/wlserver.hpp | 1 +
|
|
5 files changed, 20 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/main.cpp b/src/main.cpp
|
|
index 0621c65..056e1c1 100644
|
|
--- a/src/main.cpp
|
|
+++ b/src/main.cpp
|
|
@@ -199,6 +199,7 @@ const char usage[] =
|
|
" --xwayland-count create N xwayland servers\n"
|
|
" --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
|
|
" --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
|
|
+ " --force-panel-type lie to steam that the screen is external\n"
|
|
" --force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)\n"
|
|
" --cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.\n"
|
|
" --hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n"
|
|
@@ -373,6 +374,19 @@ static GamescopePanelOrientation force_orientation(const char *str)
|
|
}
|
|
}
|
|
|
|
+bool g_FakeExternal = false;
|
|
+static bool force_panel_type_external(const char *str)
|
|
+{
|
|
+ if (strcmp(str, "internal") == 0) {
|
|
+ return false;
|
|
+ } else if (strcmp(str, "external") == 0) {
|
|
+ return true;
|
|
+ } else {
|
|
+ fprintf( stderr, "gamescope: invalid value for --force-panel-type\n" );
|
|
+ exit(1);
|
|
+ }
|
|
+}
|
|
+
|
|
static enum GamescopeUpscaleScaler parse_upscaler_scaler(const char *str)
|
|
{
|
|
if (strcmp(str, "auto") == 0) {
|
|
@@ -783,6 +797,8 @@ int main(int argc, char **argv)
|
|
g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg );
|
|
} else if (strcmp(opt_name, "force-orientation") == 0 || strcmp(opt_name, "force-external-orientation") == 0) {
|
|
g_DesiredInternalOrientation = force_orientation( optarg );
|
|
+ } else if (strcmp(opt_name, "force-panel-type") == 0) {
|
|
+ g_FakeExternal = force_panel_type_external( optarg );
|
|
} else if (strcmp(opt_name, "custom-refresh-rates") == 0) {
|
|
g_customRefreshRates = parse_custom_refresh_rates( optarg );
|
|
} else if (strcmp(opt_name, "sharpness") == 0 ||
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 69fd348..3dd64f8 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -7192,7 +7192,7 @@ void update_mode_atoms(xwayland_ctx_t *root_ctx, bool* needs_flush = nullptr)
|
|
if (needs_flush)
|
|
*needs_flush = true;
|
|
|
|
- if ( GetBackend()->GetCurrentConnector() && GetBackend()->GetCurrentConnector()->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )
|
|
+ if ( !g_FakeExternal && GetBackend()->GetCurrentConnector() && GetBackend()->GetCurrentConnector()->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )
|
|
{
|
|
XDeleteProperty(root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeDisplayModeListExternal);
|
|
|
|
diff --git a/src/steamcompmgr.hpp b/src/steamcompmgr.hpp
|
|
index 9f384c4..30e48e8 100644
|
|
--- a/src/steamcompmgr.hpp
|
|
+++ b/src/steamcompmgr.hpp
|
|
@@ -127,6 +127,7 @@ extern float focusedWindowScaleY;
|
|
extern float focusedWindowOffsetX;
|
|
extern float focusedWindowOffsetY;
|
|
|
|
+extern bool g_FakeExternal;
|
|
extern bool g_bFSRActive;
|
|
|
|
extern uint32_t inputCounter;
|
|
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
|
|
index 5e8f516..1eeaa25 100644
|
|
--- a/src/wlserver.cpp
|
|
+++ b/src/wlserver.cpp
|
|
@@ -1078,7 +1078,7 @@ static uint32_t get_conn_display_info_flags()
|
|
return 0;
|
|
|
|
uint32_t flags = 0;
|
|
- if ( pConn->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )
|
|
+ if ( pConn->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL && !g_FakeExternal )
|
|
flags |= GAMESCOPE_CONTROL_DISPLAY_FLAG_INTERNAL_DISPLAY;
|
|
if ( pConn->SupportsVRR() )
|
|
flags |= GAMESCOPE_CONTROL_DISPLAY_FLAG_SUPPORTS_VRR;
|
|
diff --git a/src/wlserver.hpp b/src/wlserver.hpp
|
|
index 0569472..104f7a2 100644
|
|
--- a/src/wlserver.hpp
|
|
+++ b/src/wlserver.hpp
|
|
@@ -190,6 +190,7 @@ struct wlserver_t {
|
|
};
|
|
|
|
extern struct wlserver_t wlserver;
|
|
+extern bool g_FakeExternal;
|
|
|
|
std::vector<ResListEntry_t> wlserver_xdg_commit_queue();
|
|
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Mon, 14 Oct 2024 22:42:20 +0200
|
|
Subject: fix(display-config): always fill in mutable refresh rates
|
|
|
|
Assume the user is not lying to us when they fill in dynamic_refresh_rates
|
|
and that gamescope will work with e.g., CVT, so accept it even if no
|
|
custom modeline generation has been provided.
|
|
---
|
|
src/Backends/DRMBackend.cpp | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
|
|
index 75c3258..f014be9 100644
|
|
--- a/src/Backends/DRMBackend.cpp
|
|
+++ b/src/Backends/DRMBackend.cpp
|
|
@@ -2161,7 +2161,9 @@ namespace gamescope
|
|
sol::optional<sol::table> otDynamicRefreshRates = tTable["dynamic_refresh_rates"];
|
|
sol::optional<sol::function> ofnDynamicModegen = tTable["dynamic_modegen"];
|
|
|
|
- if ( otDynamicRefreshRates && ofnDynamicModegen )
|
|
+ if ( otDynamicRefreshRates && !ofnDynamicModegen )
|
|
+ m_Mutable.ValidDynamicRefreshRates = TableToVector<uint32_t>( *otDynamicRefreshRates );
|
|
+ else if ( otDynamicRefreshRates && ofnDynamicModegen )
|
|
{
|
|
m_Mutable.ValidDynamicRefreshRates = TableToVector<uint32_t>( *otDynamicRefreshRates );
|
|
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 25 Oct 2024 21:22:10 +0200
|
|
Subject: 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 | 30 ++++++++++++++++++++++++++++--
|
|
1 file changed, 28 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 3dd64f8..7dacfe7 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -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();
|
|
|
|
+ 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++ )
|
|
+ {
|
|
+ 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;
|
|
+ }
|
|
+ }
|
|
+
|
|
// Find highest mode to do refresh doubling with.
|
|
for ( auto rate = rates.rbegin(); rate != rates.rend(); rate++ )
|
|
{
|
|
@@ -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;
|
|
+ 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 = g_bVRRRequested;
|
|
}
|
|
if ( ev->atom == ctx->atoms.gamescopeDisplayForceInternal )
|
|
{
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Wed, 30 Oct 2024 00:39:03 +0100
|
|
Subject: fix(battery): run at half hz while at steamUI and disable VRR V2 +
|
|
param
|
|
|
|
---
|
|
src/steamcompmgr.cpp | 43 ++++++++++++++++++++++++++++++++-----------
|
|
1 file changed, 32 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 7dacfe7..4098c44 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -166,6 +166,9 @@ uint32_t g_reshade_technique_idx = 0;
|
|
bool g_bSteamIsActiveWindow = false;
|
|
bool g_bForceInternal = false;
|
|
bool g_bVRRRequested = false;
|
|
+bool g_bVRRCanEnable = false;
|
|
+bool b_bForceFrameLimit = false;
|
|
+bool g_bRefreshHalveEnable = false;
|
|
|
|
static std::vector< steamcompmgr_win_t* > GetGlobalPossibleFocusWindows();
|
|
static bool
|
|
@@ -793,6 +796,7 @@ uint64_t g_uCurrentBasePlaneCommitID = 0;
|
|
bool g_bCurrentBasePlaneIsFifo = false;
|
|
|
|
static int g_nSteamCompMgrTargetFPS = 0;
|
|
+static int g_nSteamCompMgrTargetFPSreq = 0;
|
|
static uint64_t g_uDynamicRefreshEqualityTime = 0;
|
|
static int g_nDynamicRefreshRate[gamescope::GAMESCOPE_SCREEN_TYPE_COUNT] = { 0, 0 };
|
|
// Delay to stop modes flickering back and forth.
|
|
@@ -812,7 +816,7 @@ static void _update_app_target_refresh_cycle()
|
|
int target_fps = g_nCombinedAppRefreshCycleOverride[type];
|
|
|
|
g_nDynamicRefreshRate[ type ] = 0;
|
|
- g_nSteamCompMgrTargetFPS = 0;
|
|
+ g_nSteamCompMgrTargetFPSreq = 0;
|
|
|
|
if ( !target_fps )
|
|
{
|
|
@@ -821,7 +825,7 @@ static void _update_app_target_refresh_cycle()
|
|
|
|
if ( g_nCombinedAppRefreshCycleChangeFPS[ type ] )
|
|
{
|
|
- g_nSteamCompMgrTargetFPS = target_fps;
|
|
+ g_nSteamCompMgrTargetFPSreq = target_fps;
|
|
}
|
|
|
|
if ( g_nCombinedAppRefreshCycleChangeRefresh[ type ] )
|
|
@@ -838,15 +842,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;
|
|
}
|
|
}
|
|
|
|
@@ -864,9 +868,9 @@ static void _update_app_target_refresh_cycle()
|
|
|
|
static void update_app_target_refresh_cycle()
|
|
{
|
|
- int nPrevFPSLimit = g_nSteamCompMgrTargetFPS;
|
|
+ int nPrevFPSLimit = g_nSteamCompMgrTargetFPSreq;
|
|
_update_app_target_refresh_cycle();
|
|
- if ( !!g_nSteamCompMgrTargetFPS != !!nPrevFPSLimit )
|
|
+ if ( !!g_nSteamCompMgrTargetFPSreq != !!nPrevFPSLimit )
|
|
update_runtime_info();
|
|
}
|
|
|
|
@@ -5052,7 +5056,7 @@ update_runtime_info()
|
|
if ( g_nRuntimeInfoFd < 0 )
|
|
return;
|
|
|
|
- uint32_t limiter_enabled = g_nSteamCompMgrTargetFPS != 0 ? 1 : 0;
|
|
+ uint32_t limiter_enabled = g_nSteamCompMgrTargetFPSreq != 0 ? 1 : 0;
|
|
pwrite( g_nRuntimeInfoFd, &limiter_enabled, sizeof( limiter_enabled ), 0 );
|
|
}
|
|
|
|
@@ -5109,7 +5113,7 @@ static bool steamcompmgr_should_vblank_window( bool bShouldLimitFPS, uint64_t vb
|
|
|
|
int nRefreshHz = gamescope::ConvertmHzToHz( g_nNestedRefresh ? g_nNestedRefresh : g_nOutputRefresh );
|
|
int nTargetFPS = g_nSteamCompMgrTargetFPS;
|
|
- if ( g_nSteamCompMgrTargetFPS && bShouldLimitFPS && nRefreshHz > nTargetFPS )
|
|
+ if ( g_nSteamCompMgrTargetFPS && (bShouldLimitFPS || b_bForceFrameLimit) && nRefreshHz > nTargetFPS )
|
|
{
|
|
int nVblankDivisor = nRefreshHz / nTargetFPS;
|
|
|
|
@@ -5485,7 +5489,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|
}
|
|
if ( ev->atom == ctx->atoms.gamescopeFPSLimit )
|
|
{
|
|
- g_nSteamCompMgrTargetFPS = get_prop( ctx, ctx->root, ctx->atoms.gamescopeFPSLimit, 0 );
|
|
+ g_nSteamCompMgrTargetFPSreq = get_prop( ctx, ctx->root, ctx->atoms.gamescopeFPSLimit, 0 );
|
|
update_runtime_info();
|
|
}
|
|
for (int i = 0; i < gamescope::GAMESCOPE_SCREEN_TYPE_COUNT; i++)
|
|
@@ -5549,7 +5553,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 +7632,23 @@ steamcompmgr_main(int argc, char **argv)
|
|
// as a question.
|
|
const bool bIsVBlankFromTimer = vblank;
|
|
|
|
+ if ( g_bRefreshHalveEnable && window_is_steam( global_focus.focusWindow ) ) {
|
|
+ // Halve refresh rate and disable vrr on SteamUI
|
|
+ cv_adaptive_sync = false;
|
|
+ int nRealRefreshHz = gamescope::ConvertmHzToHz( g_nNestedRefresh ? g_nNestedRefresh : g_nOutputRefresh );
|
|
+ if (nRealRefreshHz > 100 && g_nSteamCompMgrTargetFPSreq > 34) {
|
|
+ g_nSteamCompMgrTargetFPS = nRealRefreshHz / 2;
|
|
+ b_bForceFrameLimit = true;
|
|
+ } else {
|
|
+ g_nSteamCompMgrTargetFPS = g_nSteamCompMgrTargetFPSreq;
|
|
+ b_bForceFrameLimit = false;
|
|
+ }
|
|
+ } else {
|
|
+ cv_adaptive_sync = g_bVRRCanEnable;
|
|
+ g_nSteamCompMgrTargetFPS = g_nSteamCompMgrTargetFPSreq;
|
|
+ b_bForceFrameLimit = false;
|
|
+ }
|
|
+
|
|
// We can always vblank if VRR.
|
|
const bool bVRR = GetBackend()->IsVRRActive();
|
|
if ( bVRR )
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Fri, 1 Nov 2024 17:27:54 +0100
|
|
Subject: feat(battery): add atom for controlling frame halving
|
|
|
|
---
|
|
src/steamcompmgr.cpp | 6 ++++++
|
|
src/xwayland_ctx.hpp | 2 ++
|
|
2 files changed, 8 insertions(+)
|
|
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 4098c44..6c8ce74 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -5919,6 +5919,10 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|
MakeFocusDirty();
|
|
}
|
|
}
|
|
+ if ( ev->atom == ctx->atoms.gamescopeFrameHalveAtom )
|
|
+ {
|
|
+ g_bRefreshHalveEnable = !!get_prop( ctx, ctx->root, ctx->atoms.gamescopeFrameHalveAtom, 0 );
|
|
+ }
|
|
}
|
|
|
|
static int
|
|
@@ -7089,6 +7093,8 @@ void init_xwayland_ctx(uint32_t serverId, gamescope_xwayland_server_t *xwayland_
|
|
ctx->atoms.primarySelection = XInternAtom(ctx->dpy, "PRIMARY", false);
|
|
ctx->atoms.targets = XInternAtom(ctx->dpy, "TARGETS", false);
|
|
|
|
+ ctx->atoms.gamescopeFrameHalveAtom = XInternAtom( ctx->dpy, "GAMESCOPE_STEAMUI_HALFHZ", false );;
|
|
+
|
|
ctx->root_width = DisplayWidth(ctx->dpy, ctx->scr);
|
|
ctx->root_height = DisplayHeight(ctx->dpy, ctx->scr);
|
|
|
|
diff --git a/src/xwayland_ctx.hpp b/src/xwayland_ctx.hpp
|
|
index df2af70..e4eec9f 100644
|
|
--- a/src/xwayland_ctx.hpp
|
|
+++ b/src/xwayland_ctx.hpp
|
|
@@ -246,6 +246,8 @@ struct xwayland_ctx_t final : public gamescope::IWaitable
|
|
Atom clipboard;
|
|
Atom primarySelection;
|
|
Atom targets;
|
|
+
|
|
+ Atom gamescopeFrameHalveAtom;
|
|
} atoms;
|
|
|
|
bool HasQueuedEvents();
|
|
--
|
|
2.47.0
|
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Antheas Kapenekakis <git@antheas.dev>
|
|
Date: Wed, 13 Nov 2024 17:22:05 +0100
|
|
Subject: feat: add DPMS support through an Atom
|
|
|
|
---
|
|
src/Backends/DRMBackend.cpp | 16 +++++++++++++---
|
|
src/rendervulkan.hpp | 2 ++
|
|
src/steamcompmgr.cpp | 15 ++++++++++++---
|
|
src/xwayland_ctx.hpp | 1 +
|
|
4 files changed, 28 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
|
|
index f014be9..6bb0b88 100644
|
|
--- a/src/Backends/DRMBackend.cpp
|
|
+++ b/src/Backends/DRMBackend.cpp
|
|
@@ -2669,6 +2669,9 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|
drm->needs_modeset = true;
|
|
}
|
|
|
|
+ if (drm->pCRTC && drm->pCRTC->GetProperties().ACTIVE->GetCurrentValue() != !frameInfo->dpms)
|
|
+ drm->needs_modeset = true;
|
|
+
|
|
drm_colorspace uColorimetry = DRM_MODE_COLORIMETRY_DEFAULT;
|
|
|
|
const bool bWantsHDR10 = g_bOutputHDREnabled && frameInfo->outputEncodingEOTF == EOTF_PQ;
|
|
@@ -2724,7 +2727,7 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
|
|
|
|
// We do internal refcounting with these events
|
|
- if ( drm->pCRTC != nullptr )
|
|
+ if ( !frameInfo->dpms && drm->pCRTC != nullptr)
|
|
flags |= DRM_MODE_PAGE_FLIP_EVENT;
|
|
|
|
if ( async || g_bForceAsyncFlips )
|
|
@@ -2797,7 +2800,13 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|
|
|
if ( drm->pCRTC )
|
|
{
|
|
- drm->pCRTC->GetProperties().ACTIVE->SetPendingValue( drm->req, 1u, true );
|
|
+ if ( frameInfo->dpms ) {
|
|
+ // We can't disable a CRTC if it's already disabled
|
|
+ if (drm->pCRTC->GetProperties().ACTIVE->GetCurrentValue() != 0)
|
|
+ drm->pCRTC->GetProperties().ACTIVE->SetPendingValue(drm->req, 0, true);
|
|
+ }
|
|
+ else
|
|
+ drm->pCRTC->GetProperties().ACTIVE->SetPendingValue( drm->req, 1u, true );
|
|
drm->pCRTC->GetProperties().MODE_ID->SetPendingValue( drm->req, drm->pending.mode_id ? drm->pending.mode_id->GetBlobValue() : 0lu, true );
|
|
|
|
if ( drm->pCRTC->GetProperties().VRR_ENABLED )
|
|
@@ -2828,7 +2837,7 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|
drm->flags = flags;
|
|
|
|
int ret;
|
|
- if ( drm->pCRTC == nullptr ) {
|
|
+ if (frameInfo->dpms || drm->pCRTC == nullptr ) {
|
|
ret = 0;
|
|
} else if ( drm->bUseLiftoff ) {
|
|
ret = drm_prepare_liftoff( drm, frameInfo, needs_modeset );
|
|
@@ -3391,6 +3400,7 @@ namespace gamescope
|
|
|
|
FrameInfo_t presentCompFrameInfo = {};
|
|
presentCompFrameInfo.allowVRR = pFrameInfo->allowVRR;
|
|
+ presentCompFrameInfo.dpms = pFrameInfo->dpms;
|
|
presentCompFrameInfo.outputEncodingEOTF = pFrameInfo->outputEncodingEOTF;
|
|
|
|
if ( bNeedsFullComposite )
|
|
diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp
|
|
index b537170..ccabd88 100644
|
|
--- a/src/rendervulkan.hpp
|
|
+++ b/src/rendervulkan.hpp
|
|
@@ -281,6 +281,8 @@ struct FrameInfo_t
|
|
bool applyOutputColorMgmt; // drm only
|
|
EOTF outputEncodingEOTF;
|
|
|
|
+ bool dpms;
|
|
+
|
|
int layerCount;
|
|
struct Layer_t
|
|
{
|
|
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
|
index 6c8ce74..dfee904 100644
|
|
--- a/src/steamcompmgr.cpp
|
|
+++ b/src/steamcompmgr.cpp
|
|
@@ -169,6 +169,8 @@ bool g_bVRRRequested = false;
|
|
bool g_bVRRCanEnable = false;
|
|
bool b_bForceFrameLimit = false;
|
|
bool g_bRefreshHalveEnable = false;
|
|
+bool g_bDPMS = false;
|
|
+bool g_bDPMS_set = false;
|
|
|
|
static std::vector< steamcompmgr_win_t* > GetGlobalPossibleFocusWindows();
|
|
static bool
|
|
@@ -2271,7 +2273,7 @@ bool ShouldDrawCursor()
|
|
}
|
|
|
|
static void
|
|
-paint_all(bool async)
|
|
+paint_all(bool async, bool dpms)
|
|
{
|
|
gamescope_xwayland_server_t *root_server = wlserver_get_xwayland_server(0);
|
|
xwayland_ctx_t *root_ctx = root_server->ctx.get();
|
|
@@ -2322,6 +2324,7 @@ paint_all(bool async)
|
|
frameInfo.outputEncodingEOTF = g_ColorMgmt.pending.outputEncodingEOTF;
|
|
frameInfo.allowVRR = cv_adaptive_sync;
|
|
frameInfo.bFadingOut = fadingOut;
|
|
+ frameInfo.dpms = dpms;
|
|
|
|
// If the window we'd paint as the base layer is the streaming client,
|
|
// find the video underlay and put it up first in the scenegraph
|
|
@@ -5923,6 +5926,10 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|
{
|
|
g_bRefreshHalveEnable = !!get_prop( ctx, ctx->root, ctx->atoms.gamescopeFrameHalveAtom, 0 );
|
|
}
|
|
+ if (ev->atom == ctx->atoms.gamescopeDPMS)
|
|
+ {
|
|
+ g_bDPMS = !!get_prop(ctx, ctx->root, ctx->atoms.gamescopeDPMS, 0);
|
|
+ }
|
|
}
|
|
|
|
static int
|
|
@@ -7094,6 +7101,7 @@ void init_xwayland_ctx(uint32_t serverId, gamescope_xwayland_server_t *xwayland_
|
|
ctx->atoms.targets = XInternAtom(ctx->dpy, "TARGETS", false);
|
|
|
|
ctx->atoms.gamescopeFrameHalveAtom = XInternAtom( ctx->dpy, "GAMESCOPE_STEAMUI_HALFHZ", false );;
|
|
+ ctx->atoms.gamescopeDPMS = XInternAtom(ctx->dpy, "GAMESCOPE_DPMS", false);
|
|
|
|
ctx->root_width = DisplayWidth(ctx->dpy, ctx->scr);
|
|
ctx->root_height = DisplayHeight(ctx->dpy, ctx->scr);
|
|
@@ -8061,9 +8069,10 @@ steamcompmgr_main(int argc, char **argv)
|
|
bShouldPaint = false;
|
|
}
|
|
|
|
- if ( bShouldPaint )
|
|
+ if (bShouldPaint || (g_bDPMS != g_bDPMS_set && vblank))
|
|
{
|
|
- paint_all( eFlipType == FlipType::Async );
|
|
+ g_bDPMS_set = g_bDPMS;
|
|
+ paint_all( eFlipType == FlipType::Async, g_bDPMS );
|
|
|
|
hasRepaint = false;
|
|
hasRepaintNonBasePlane = false;
|
|
diff --git a/src/xwayland_ctx.hpp b/src/xwayland_ctx.hpp
|
|
index e4eec9f..2347cbb 100644
|
|
--- a/src/xwayland_ctx.hpp
|
|
+++ b/src/xwayland_ctx.hpp
|
|
@@ -248,6 +248,7 @@ struct xwayland_ctx_t final : public gamescope::IWaitable
|
|
Atom targets;
|
|
|
|
Atom gamescopeFrameHalveAtom;
|
|
+ Atom gamescopeDPMS;
|
|
} atoms;
|
|
|
|
bool HasQueuedEvents();
|
|
--
|
|
2.47.0
|
|
|