From 5326eebb1b18627a75c7a6b03b8b988a347ab86c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 22 Apr 2020 00:07:48 +0200 Subject: [PATCH] WindowServer+LibGUI: Notify DisplayLinks at 60 fps no matter what The original implementation only sent out notifications when there was something being drawn on screen. If nothing was going on, we'd get too lazy and just not notify display links. This obviously break requestAnimationFrame(), so now we just drive the DisplayLinks at 60 fps no matter what. :^) --- Libraries/LibGUI/WindowServerConnection.cpp | 9 ++++++++- Libraries/LibGUI/WindowServerConnection.h | 2 ++ Servers/WindowServer/ClientConnection.cpp | 9 +++++++++ Servers/WindowServer/Compositor.cpp | 22 ++++++++++++++++++++- Servers/WindowServer/Compositor.h | 7 +++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp index 7a0abb23e3..90623e18dd 100644 --- a/Libraries/LibGUI/WindowServerConnection.cpp +++ b/Libraries/LibGUI/WindowServerConnection.cpp @@ -342,7 +342,14 @@ void WindowServerConnection::handle(const Messages::WindowClient::WindowStateCha void WindowServerConnection::handle(const Messages::WindowClient::DisplayLinkNotification&) { - DisplayLink::notify({}); + if (m_display_link_notification_pending) + return; + + m_display_link_notification_pending = true; + deferred_invoke([this](auto&) { + DisplayLink::notify({}); + m_display_link_notification_pending = false; + }); } } diff --git a/Libraries/LibGUI/WindowServerConnection.h b/Libraries/LibGUI/WindowServerConnection.h index e50223a34d..9ae71a9795 100644 --- a/Libraries/LibGUI/WindowServerConnection.h +++ b/Libraries/LibGUI/WindowServerConnection.h @@ -75,6 +75,8 @@ private: virtual void handle(const Messages::WindowClient::UpdateSystemTheme&) override; virtual void handle(const Messages::WindowClient::WindowStateChanged&) override; virtual void handle(const Messages::WindowClient::DisplayLinkNotification&) override; + + bool m_display_link_notification_pending { false }; }; } diff --git a/Servers/WindowServer/ClientConnection.cpp b/Servers/WindowServer/ClientConnection.cpp index 8a4d61bf41..cd272d3a79 100644 --- a/Servers/WindowServer/ClientConnection.cpp +++ b/Servers/WindowServer/ClientConnection.cpp @@ -88,6 +88,9 @@ ClientConnection::ClientConnection(Core::LocalSocket& client_socket, int client_ ClientConnection::~ClientConnection() { + if (m_has_display_link) + Compositor::the().decrement_display_link_count({}); + MenuManager::the().close_all_menus_from_client({}, *this); auto windows = move(m_windows); for (auto& window : windows) { @@ -772,12 +775,18 @@ OwnPtr Client void ClientConnection::handle(const Messages::WindowServer::EnableDisplayLink&) { + if (m_has_display_link) + return; m_has_display_link = true; + Compositor::the().increment_display_link_count({}); } void ClientConnection::handle(const Messages::WindowServer::DisableDisplayLink&) { + if (!m_has_display_link) + return; m_has_display_link = false; + Compositor::the().decrement_display_link_count({}); } void ClientConnection::notify_display_link(Badge) diff --git a/Servers/WindowServer/Compositor.cpp b/Servers/WindowServer/Compositor.cpp index caaede8a6f..e1622093fc 100644 --- a/Servers/WindowServer/Compositor.cpp +++ b/Servers/WindowServer/Compositor.cpp @@ -60,10 +60,15 @@ WallpaperMode mode_to_enum(const String& name) Compositor::Compositor() { + m_display_link_notify_timer = add( + 1000 / 60, [this] { + notify_display_links(); + }); + m_display_link_notify_timer->stop(); + m_compose_timer = Core::Timer::create_single_shot( 1000 / 60, [this] { - notify_display_links(); compose(); }, this); @@ -488,4 +493,19 @@ void Compositor::notify_display_links() }); } +void Compositor::increment_display_link_count(Badge) +{ + ++m_display_link_count; + if (m_display_link_count == 1) + m_display_link_notify_timer->start(); +} + +void Compositor::decrement_display_link_count(Badge) +{ + ASSERT(m_display_link_count); + --m_display_link_count; + if (!m_display_link_count) + m_display_link_notify_timer->stop(); +} + } diff --git a/Servers/WindowServer/Compositor.h b/Servers/WindowServer/Compositor.h index a1f654de01..fa86276405 100644 --- a/Servers/WindowServer/Compositor.h +++ b/Servers/WindowServer/Compositor.h @@ -34,6 +34,7 @@ namespace WindowServer { +class ClientConnection; class Cursor; enum class WallpaperMode { @@ -65,6 +66,9 @@ public: void invalidate_cursor(); Gfx::Rect current_cursor_rect() const; + void increment_display_link_count(Badge); + void decrement_display_link_count(Badge); + private: Compositor(); void init_bitmaps(); @@ -96,6 +100,9 @@ private: String m_wallpaper_path; WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked }; RefPtr m_wallpaper; + + RefPtr m_display_link_notify_timer; + size_t m_display_link_count { 0 }; }; }