[mutter] screen-cast: Always wait for an update before sending cursor-only frames



commit b1be1e86e9b4c365ef971b49d984336c8ad94a4d
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Apr 29 16:05:50 2022 +0200

    screen-cast: Always wait for an update before sending cursor-only frames
    
    With the unthrottled input emission, we ended up often getting the
    cursor updates long before any damage had been posted, meaning that if
    you moved around the mouse pointer where the mouse had a high enough
    refresh rate, we'd effectively stall the screen cast stream by only
    sending cursor updates and nothing else.
    
    Fix this by scheduling an update when we get a cursor update, then
    sending a cursor-only frame after any damage and relayout has been
    processed, but only if there is no queued damage that will cause an
    actual repaint.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2393>

 src/backends/meta-screen-cast-area-stream-src.c    | 19 ++++++++++++++-
 src/backends/meta-screen-cast-monitor-stream-src.c | 20 +++++++++++++++-
 src/backends/meta-screen-cast-virtual-stream-src.c | 25 +++++++++++++++++---
 src/backends/meta-screen-cast-window-stream-src.c  | 27 +++++++++++++++++++++-
 4 files changed, 85 insertions(+), 6 deletions(-)
---
diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c
index aa15481010..fe376db05e 100644
--- a/src/backends/meta-screen-cast-area-stream-src.c
+++ b/src/backends/meta-screen-cast-area-stream-src.c
@@ -44,6 +44,7 @@ struct _MetaScreenCastAreaStreamSrc
 
   gulong position_invalidated_handler_id;
   gulong cursor_changed_handler_id;
+  gulong prepare_frame_handler_id;
 
   guint maybe_record_idle_id;
 };
@@ -174,7 +175,9 @@ static void
 pointer_position_invalidated (MetaCursorTracker           *cursor_tracker,
                               MetaScreenCastAreaStreamSrc *area_src)
 {
-  sync_cursor_state (area_src);
+  ClutterStage *stage = get_stage (area_src);
+
+  clutter_stage_schedule_update (stage);
 }
 
 static void
@@ -185,6 +188,14 @@ cursor_changed (MetaCursorTracker           *cursor_tracker,
   sync_cursor_state (area_src);
 }
 
+static void
+on_prepare_frame (ClutterStage                *stage,
+                  ClutterStageView            *stage_view,
+                  MetaScreenCastAreaStreamSrc *area_src)
+{
+  sync_cursor_state (area_src);
+}
+
 static void
 inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
 {
@@ -371,6 +382,10 @@ meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
         g_signal_connect_after (cursor_tracker, "cursor-changed",
                                 G_CALLBACK (cursor_changed),
                                 area_src);
+      area_src->prepare_frame_handler_id =
+        g_signal_connect_after (stage, "prepare-frame",
+                                G_CALLBACK (on_prepare_frame),
+                                area_src);
       meta_cursor_tracker_track_position (cursor_tracker);
       G_GNUC_FALLTHROUGH;
     case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
@@ -420,6 +435,8 @@ meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src)
                           cursor_tracker);
   g_clear_signal_handler (&area_src->cursor_changed_handler_id,
                           cursor_tracker);
+  g_clear_signal_handler (&area_src->prepare_frame_handler_id,
+                          stage);
 
   g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
 
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c 
b/src/backends/meta-screen-cast-monitor-stream-src.c
index 3075009017..f30a52d1d0 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -48,6 +48,7 @@ struct _MetaScreenCastMonitorStreamSrc
 
   gulong position_invalidated_handler_id;
   gulong cursor_changed_handler_id;
+  gulong stage_prepare_frame_handler_id;
 
   guint maybe_record_idle_id;
 };
@@ -269,7 +270,9 @@ static void
 pointer_position_invalidated (MetaCursorTracker              *cursor_tracker,
                               MetaScreenCastMonitorStreamSrc *monitor_src)
 {
-  sync_cursor_state (monitor_src);
+  ClutterStage *stage = get_stage (monitor_src);
+
+  clutter_stage_schedule_update (stage);
 }
 
 static void
@@ -280,6 +283,14 @@ cursor_changed (MetaCursorTracker              *cursor_tracker,
   sync_cursor_state (monitor_src);
 }
 
+static void
+on_prepare_frame (ClutterStage                   *stage,
+                  ClutterStageView               *stage_view,
+                  MetaScreenCastMonitorStreamSrc *monitor_src)
+{
+  sync_cursor_state (monitor_src);
+}
+
 static void
 inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
 {
@@ -402,6 +413,7 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
+  ClutterStage *stage = get_stage (monitor_src);
   MetaScreenCastStream *stream;
 
   stream = meta_screen_cast_stream_src_get_stream (src);
@@ -417,6 +429,10 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
         g_signal_connect_after (cursor_tracker, "cursor-changed",
                                 G_CALLBACK (cursor_changed),
                                 monitor_src);
+      monitor_src->stage_prepare_frame_handler_id =
+        g_signal_connect_after (stage, "prepare-frame",
+                                G_CALLBACK (on_prepare_frame),
+                                monitor_src);
       meta_cursor_tracker_track_position (cursor_tracker);
       break;
     case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
@@ -465,6 +481,8 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
                           cursor_tracker);
   g_clear_signal_handler (&monitor_src->cursor_changed_handler_id,
                           cursor_tracker);
+  g_clear_signal_handler (&monitor_src->stage_prepare_frame_handler_id,
+                          stage);
 
   g_clear_handle_id (&monitor_src->maybe_record_idle_id, g_source_remove);
 
diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c 
b/src/backends/meta-screen-cast-virtual-stream-src.c
index 3341aedd9b..56f9bfaa2a 100644
--- a/src/backends/meta-screen-cast-virtual-stream-src.c
+++ b/src/backends/meta-screen-cast-virtual-stream-src.c
@@ -42,6 +42,7 @@ struct _MetaScreenCastVirtualStreamSrc
 
   gulong position_invalidated_handler_id;
   gulong cursor_changed_handler_id;
+  gulong prepare_frame_handler_id;
 
   gulong monitors_changed_handler_id;
 };
@@ -126,10 +127,12 @@ sync_cursor_state (MetaScreenCastVirtualStreamSrc *virtual_src)
 }
 
 static void
-pointer_position_invalidated (MetaCursorTracker              *cursor_tracker,
-                              MetaScreenCastVirtualStreamSrc *virtual_src)
+pointer_position_invalidated (MetaCursorTracker       *cursor_tracker,
+                              MetaScreenCastStreamSrc *src)
 {
-  sync_cursor_state (virtual_src);
+  ClutterStage *stage = stage_from_src (src);
+
+  clutter_stage_schedule_update (stage);
 }
 
 static void
@@ -140,6 +143,14 @@ cursor_changed (MetaCursorTracker              *cursor_tracker,
   sync_cursor_state (virtual_src);
 }
 
+static void
+on_prepare_frame (ClutterStage                   *stage,
+                  ClutterStageView               *stage_view,
+                  MetaScreenCastVirtualStreamSrc *virtual_src)
+{
+  sync_cursor_state (virtual_src);
+}
+
 static void
 inhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
 {
@@ -220,6 +231,7 @@ init_record_callbacks (MetaScreenCastVirtualStreamSrc *virtual_src)
     meta_backend_get_monitor_manager (backend);
   MetaCursorTracker *cursor_tracker =
     meta_backend_get_cursor_tracker (backend);
+  ClutterStage *stage = stage_from_src (src);
 
   switch (meta_screen_cast_stream_get_cursor_mode (stream))
     {
@@ -232,6 +244,10 @@ init_record_callbacks (MetaScreenCastVirtualStreamSrc *virtual_src)
         g_signal_connect_after (cursor_tracker, "cursor-changed",
                                 G_CALLBACK (cursor_changed),
                                 virtual_src);
+      virtual_src->prepare_frame_handler_id =
+        g_signal_connect_after (stage, "prepare-frame",
+                                G_CALLBACK (on_prepare_frame),
+                                virtual_src);
       G_GNUC_FALLTHROUGH;
     case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
     case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
@@ -284,6 +300,7 @@ meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src)
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
+  ClutterStage *stage = stage_from_src (src);
 
   if (virtual_src->hw_cursor_inhibited)
     uninhibit_hw_cursor (virtual_src);
@@ -299,6 +316,8 @@ meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src)
                           cursor_tracker);
   g_clear_signal_handler (&virtual_src->cursor_changed_handler_id,
                           cursor_tracker);
+  g_clear_signal_handler (&virtual_src->prepare_frame_handler_id,
+                          stage);
 
   g_clear_signal_handler (&virtual_src->monitors_changed_handler_id,
                           monitor_manager);
diff --git a/src/backends/meta-screen-cast-window-stream-src.c 
b/src/backends/meta-screen-cast-window-stream-src.c
index 9e77db021e..b353a76df7 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -39,6 +39,7 @@ struct _MetaScreenCastWindowStreamSrc
   gulong screen_cast_window_destroyed_handler_id;
   gulong position_invalidated_handler_id;
   gulong cursor_changed_handler_id;
+  gulong prepare_frame_handler_id;
 
   gboolean cursor_bitmap_invalid;
 };
@@ -59,6 +60,12 @@ get_backend (MetaScreenCastWindowStreamSrc *window_src)
   return meta_screen_cast_get_backend (screen_cast);
 }
 
+static ClutterStage *
+get_stage (MetaScreenCastWindowStreamSrc *window_src)
+{
+  return CLUTTER_STAGE (meta_backend_get_stage (get_backend (window_src)));
+}
+
 static MetaScreenCastWindowStream *
 get_window_stream (MetaScreenCastWindowStreamSrc *window_src)
 {
@@ -320,6 +327,7 @@ meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_s
   MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
   MetaBackend *backend = get_backend (window_src);
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
+  ClutterStage *stage = get_stage (window_src);
 
   if (!window_src->screen_cast_window)
     return;
@@ -332,6 +340,8 @@ meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_s
                           cursor_tracker);
   g_clear_signal_handler (&window_src->cursor_changed_handler_id,
                           cursor_tracker);
+  g_clear_signal_handler (&window_src->prepare_frame_handler_id,
+                          stage);
 
   switch (meta_screen_cast_stream_get_cursor_mode (stream))
     {
@@ -380,7 +390,9 @@ static void
 pointer_position_invalidated (MetaCursorTracker             *cursor_tracker,
                               MetaScreenCastWindowStreamSrc *window_src)
 {
-  sync_cursor_state (window_src);
+  ClutterStage *stage = get_stage (window_src);
+
+  clutter_stage_schedule_update (stage);
 }
 
 static void
@@ -391,12 +403,21 @@ cursor_changed (MetaCursorTracker             *cursor_tracker,
   sync_cursor_state (window_src);
 }
 
+static void
+on_prepare_frame (ClutterStage                  *stage,
+                  ClutterStageView              *stage_view,
+                  MetaScreenCastWindowStreamSrc *window_src)
+{
+  sync_cursor_state (window_src);
+}
+
 static void
 meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
 {
   MetaScreenCastWindowStreamSrc *window_src =
     META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
   MetaBackend *backend = get_backend (window_src);
+  ClutterStage *stage = get_stage (window_src);
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
   MetaWindowActor *window_actor;
   MetaScreenCastStream *stream;
@@ -433,6 +454,10 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
         g_signal_connect_after (cursor_tracker, "cursor-changed",
                                 G_CALLBACK (cursor_changed),
                                 window_src);
+      window_src->prepare_frame_handler_id =
+        g_signal_connect_after (stage, "prepare_frame",
+                                G_CALLBACK (on_prepare_frame),
+                                window_src);
       meta_cursor_tracker_track_position (cursor_tracker);
       break;
     case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]