Quellcode durchsuchen

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. :^)
Andreas Kling vor 5 Jahren
Ursprung
Commit
5326eebb1b

+ 8 - 1
Libraries/LibGUI/WindowServerConnection.cpp

@@ -342,7 +342,14 @@ void WindowServerConnection::handle(const Messages::WindowClient::WindowStateCha
 
 
 void WindowServerConnection::handle(const Messages::WindowClient::DisplayLinkNotification&)
 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;
+    });
 }
 }
 
 
 }
 }

+ 2 - 0
Libraries/LibGUI/WindowServerConnection.h

@@ -75,6 +75,8 @@ private:
     virtual void handle(const Messages::WindowClient::UpdateSystemTheme&) override;
     virtual void handle(const Messages::WindowClient::UpdateSystemTheme&) override;
     virtual void handle(const Messages::WindowClient::WindowStateChanged&) override;
     virtual void handle(const Messages::WindowClient::WindowStateChanged&) override;
     virtual void handle(const Messages::WindowClient::DisplayLinkNotification&) override;
     virtual void handle(const Messages::WindowClient::DisplayLinkNotification&) override;
+
+    bool m_display_link_notification_pending { false };
 };
 };
 
 
 }
 }

+ 9 - 0
Servers/WindowServer/ClientConnection.cpp

@@ -88,6 +88,9 @@ ClientConnection::ClientConnection(Core::LocalSocket& client_socket, int client_
 
 
 ClientConnection::~ClientConnection()
 ClientConnection::~ClientConnection()
 {
 {
+    if (m_has_display_link)
+        Compositor::the().decrement_display_link_count({});
+
     MenuManager::the().close_all_menus_from_client({}, *this);
     MenuManager::the().close_all_menus_from_client({}, *this);
     auto windows = move(m_windows);
     auto windows = move(m_windows);
     for (auto& window : windows) {
     for (auto& window : windows) {
@@ -772,12 +775,18 @@ OwnPtr<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrementResponse> Client
 
 
 void ClientConnection::handle(const Messages::WindowServer::EnableDisplayLink&)
 void ClientConnection::handle(const Messages::WindowServer::EnableDisplayLink&)
 {
 {
+    if (m_has_display_link)
+        return;
     m_has_display_link = true;
     m_has_display_link = true;
+    Compositor::the().increment_display_link_count({});
 }
 }
 
 
 void ClientConnection::handle(const Messages::WindowServer::DisableDisplayLink&)
 void ClientConnection::handle(const Messages::WindowServer::DisableDisplayLink&)
 {
 {
+    if (!m_has_display_link)
+        return;
     m_has_display_link = false;
     m_has_display_link = false;
+    Compositor::the().decrement_display_link_count({});
 }
 }
 
 
 void ClientConnection::notify_display_link(Badge<Compositor>)
 void ClientConnection::notify_display_link(Badge<Compositor>)

+ 21 - 1
Servers/WindowServer/Compositor.cpp

@@ -60,10 +60,15 @@ WallpaperMode mode_to_enum(const String& name)
 
 
 Compositor::Compositor()
 Compositor::Compositor()
 {
 {
+    m_display_link_notify_timer = add<Core::Timer>(
+        1000 / 60, [this] {
+            notify_display_links();
+        });
+    m_display_link_notify_timer->stop();
+
     m_compose_timer = Core::Timer::create_single_shot(
     m_compose_timer = Core::Timer::create_single_shot(
         1000 / 60,
         1000 / 60,
         [this] {
         [this] {
-            notify_display_links();
             compose();
             compose();
         },
         },
         this);
         this);
@@ -488,4 +493,19 @@ void Compositor::notify_display_links()
     });
     });
 }
 }
 
 
+void Compositor::increment_display_link_count(Badge<ClientConnection>)
+{
+    ++m_display_link_count;
+    if (m_display_link_count == 1)
+        m_display_link_notify_timer->start();
+}
+
+void Compositor::decrement_display_link_count(Badge<ClientConnection>)
+{
+    ASSERT(m_display_link_count);
+    --m_display_link_count;
+    if (!m_display_link_count)
+        m_display_link_notify_timer->stop();
+}
+
 }
 }

+ 7 - 0
Servers/WindowServer/Compositor.h

@@ -34,6 +34,7 @@
 
 
 namespace WindowServer {
 namespace WindowServer {
 
 
+class ClientConnection;
 class Cursor;
 class Cursor;
 
 
 enum class WallpaperMode {
 enum class WallpaperMode {
@@ -65,6 +66,9 @@ public:
     void invalidate_cursor();
     void invalidate_cursor();
     Gfx::Rect current_cursor_rect() const;
     Gfx::Rect current_cursor_rect() const;
 
 
+    void increment_display_link_count(Badge<ClientConnection>);
+    void decrement_display_link_count(Badge<ClientConnection>);
+
 private:
 private:
     Compositor();
     Compositor();
     void init_bitmaps();
     void init_bitmaps();
@@ -96,6 +100,9 @@ private:
     String m_wallpaper_path;
     String m_wallpaper_path;
     WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked };
     WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked };
     RefPtr<Gfx::Bitmap> m_wallpaper;
     RefPtr<Gfx::Bitmap> m_wallpaper;
+
+    RefPtr<Core::Timer> m_display_link_notify_timer;
+    size_t m_display_link_count { 0 };
 };
 };
 
 
 }
 }