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>
This commit is contained in:
parent
c5410b61d2
commit
b1be1e86e9
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user