summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd/wayland/display_server_wayland.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-02-17 00:23:04 +0100
committerRémi Verschelde <rverschelde@gmail.com>2024-02-17 00:23:04 +0100
commit5c482754e4e8fe1736cf7ac1ca1b63ae8f07b087 (patch)
tree7b4b613767f0ef5f9c459f47a4db7c59db1efc42 /platform/linuxbsd/wayland/display_server_wayland.cpp
parentebf00b86ed0a2b959051013f8a16e0c8d03366cd (diff)
parent2e07dcf1e7776fa9c068a690bfc51e385ff7501b (diff)
downloadredot-engine-5c482754e4e8fe1736cf7ac1ca1b63ae8f07b087.tar.gz
Merge pull request #87750 from Riteo/wayland-timeout-loop
Wayland: Suspend window after frame timeout or suspend state
Diffstat (limited to 'platform/linuxbsd/wayland/display_server_wayland.cpp')
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp31
1 files changed, 28 insertions, 3 deletions
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index 85bbfe546a..c957dea32d 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -867,11 +867,11 @@ bool DisplayServerWayland::window_is_focused(WindowID p_window_id) const {
}
bool DisplayServerWayland::window_can_draw(DisplayServer::WindowID p_window_id) const {
- return frame;
+ return !suspended;
}
bool DisplayServerWayland::can_any_window_draw() const {
- return frame;
+ return !suspended;
}
void DisplayServerWayland::window_set_ime_active(const bool p_active, DisplayServer::WindowID p_window_id) {
@@ -1143,7 +1143,32 @@ void DisplayServerWayland::process_events() {
wayland_thread.keyboard_echo_keys();
- frame = wayland_thread.get_reset_frame();
+ if (!suspended) {
+ if (emulate_vsync) {
+ // Due to various reasons, we manually handle display synchronization by
+ // waiting for a frame event (request to draw) or, if available, the actual
+ // window's suspend status. When a window is suspended, we can avoid drawing
+ // altogether, either because the compositor told us that we don't need to or
+ // because the pace of the frame events became unreliable.
+ bool frame = wayland_thread.wait_frame_suspend_ms(1000);
+ if (!frame) {
+ suspended = true;
+ }
+ } else {
+ if (wayland_thread.is_suspended()) {
+ suspended = true;
+ }
+ }
+
+ if (suspended) {
+ DEBUG_LOG_WAYLAND("Window suspended.");
+ }
+ } else {
+ if (wayland_thread.get_reset_frame()) {
+ // At last, a sign of life! We're no longer suspended.
+ suspended = false;
+ }
+ }
wayland_thread.mutex.unlock();