From c9d8b0b5a9333e075b0f2a9240029188d280579c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 3 Oct 2024 22:36:20 +0200 Subject: [PATCH] screen-cast-stream-src/virtual: Track cursor updates via frame clock When the cursor is captured via metadata, schedule updates when the sprite changes or position moves, so we can gather the cursor change during dispatch. Also use the new skipped-paint stage watch to avoid having to guess whether something will be painted by peeking at the pending damage. Part-of: --- .../meta-screen-cast-virtual-stream-src.c | 108 ++++++++---------- 1 file changed, 49 insertions(+), 59 deletions(-) diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c b/src/backends/meta-screen-cast-virtual-stream-src.c index 8bd1ba1c4..1009d561f 100644 --- a/src/backends/meta-screen-cast-virtual-stream-src.c +++ b/src/backends/meta-screen-cast-virtual-stream-src.c @@ -51,11 +51,11 @@ struct _MetaScreenCastVirtualStreamSrc int y; } last_cursor_matadata; - MetaStageWatch *watch; + MetaStageWatch *paint_watch; + MetaStageWatch *skipped_watch; gulong position_invalidated_handler_id; gulong cursor_changed_handler_id; - gulong prepare_frame_handler_id; gulong monitors_changed_handler_id; }; @@ -103,15 +103,6 @@ stage_from_src (MetaScreenCastStreamSrc *src) return CLUTTER_STAGE (meta_backend_get_stage (backend_from_src (src))); } -static gboolean -is_redraw_queued (MetaScreenCastVirtualStreamSrc *virtual_src) -{ - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src); - - return clutter_stage_is_redraw_queued_on_view (stage_from_src (src), - view_from_src (src)); -} - ClutterStageView * meta_screen_cast_virtual_stream_src_get_view (MetaScreenCastVirtualStreamSrc *virtual_src) { @@ -128,50 +119,22 @@ meta_screen_cast_virtual_stream_src_logical_monitor (MetaScreenCastVirtualStream return meta_monitor_get_logical_monitor (monitor); } -static void -sync_cursor_state (MetaScreenCastVirtualStreamSrc *virtual_src) -{ - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src); - MetaScreenCastPaintPhase paint_phase; - MetaScreenCastRecordFlag flags; - - if (is_redraw_queued (virtual_src)) - return; - - if (meta_screen_cast_stream_src_pending_follow_up_frame (src)) - return; - - flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; - paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, - paint_phase, - NULL); -} - static void pointer_position_invalidated (MetaCursorTracker *cursor_tracker, MetaScreenCastStreamSrc *src) { - ClutterStage *stage = stage_from_src (src); - - clutter_stage_schedule_update (stage); + clutter_stage_view_schedule_update (view_from_src (src)); } static void cursor_changed (MetaCursorTracker *cursor_tracker, MetaScreenCastVirtualStreamSrc *virtual_src) { - virtual_src->cursor_bitmap_invalid = TRUE; - sync_cursor_state (virtual_src); -} + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src); -static void -on_prepare_frame (ClutterStage *stage, - ClutterStageView *stage_view, - ClutterFrame *frame, - MetaScreenCastVirtualStreamSrc *virtual_src) -{ - sync_cursor_state (virtual_src); + virtual_src->cursor_bitmap_invalid = TRUE; + + clutter_stage_view_schedule_update (view_from_src (src)); } static void @@ -192,6 +155,26 @@ on_after_paint (MetaStage *stage, redraw_clip); } +static void +on_skipped_paint (MetaStage *stage, + ClutterStageView *view, + const MtkRegion *redraw_clip, + ClutterFrame *frame, + gpointer user_data) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); + MetaScreenCastRecordFlag flags; + MetaScreenCastPaintPhase paint_phase; + + flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + + meta_screen_cast_stream_src_maybe_record_frame (src, + flags, + paint_phase, + redraw_clip); +} + static void setup_view (MetaScreenCastVirtualStreamSrc *virtual_src, ClutterStageView *view) @@ -200,7 +183,8 @@ setup_view (MetaScreenCastVirtualStreamSrc *virtual_src, MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); MetaStage *meta_stage = META_STAGE (stage_from_src (src)); - g_return_if_fail (!virtual_src->watch); + g_return_if_fail (!virtual_src->paint_watch && + !virtual_src->skipped_watch); switch (meta_screen_cast_stream_get_cursor_mode (stream)) { @@ -212,12 +196,18 @@ setup_view (MetaScreenCastVirtualStreamSrc *virtual_src, break; } - virtual_src->watch = + virtual_src->paint_watch = meta_stage_watch_view (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT, on_after_paint, virtual_src); + virtual_src->skipped_watch = + meta_stage_watch_view (meta_stage, + view, + META_STAGE_WATCH_SKIPPED_PAINT, + on_skipped_paint, + virtual_src); } static void @@ -229,8 +219,10 @@ on_monitors_changed (MetaMonitorManager *monitor_manager, MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); ClutterStageView *view; - meta_stage_remove_watch (stage, virtual_src->watch); - virtual_src->watch = NULL; + meta_stage_remove_watch (stage, virtual_src->paint_watch); + virtual_src->paint_watch = NULL; + meta_stage_remove_watch (stage, virtual_src->skipped_watch); + virtual_src->skipped_watch = NULL; view = view_from_src (src); setup_view (virtual_src, view); @@ -246,7 +238,6 @@ setup_cursor_handling (MetaScreenCastVirtualStreamSrc *virtual_src) MetaBackend *backend = backend_from_src (src); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - ClutterStage *stage = stage_from_src (src); switch (meta_screen_cast_stream_get_cursor_mode (stream)) { @@ -260,10 +251,6 @@ setup_cursor_handling (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); break; case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: meta_cursor_tracker_track_position (cursor_tracker); @@ -313,19 +300,22 @@ meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src) meta_backend_get_monitor_manager (backend); ClutterStage *stage = stage_from_src (src); - if (virtual_src->watch) + if (virtual_src->paint_watch) { - meta_stage_remove_watch (META_STAGE (stage_from_src (src)), - virtual_src->watch); - virtual_src->watch = NULL; + meta_stage_remove_watch (META_STAGE (stage), virtual_src->paint_watch); + virtual_src->paint_watch = NULL; + } + + if (virtual_src->skipped_watch) + { + meta_stage_remove_watch (META_STAGE (stage), virtual_src->skipped_watch); + virtual_src->skipped_watch = NULL; } g_clear_signal_handler (&virtual_src->position_invalidated_handler_id, 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);