diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index 0e499dab7..5d8f5e290 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -161,13 +161,17 @@ static void sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; if (is_redraw_queued (area_src)) return; flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -232,12 +236,16 @@ maybe_record_frame_on_idle (gpointer user_data) MetaScreenCastAreaStreamSrc *area_src = META_SCREEN_CAST_AREA_STREAM_SRC (user_data); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; area_src->maybe_record_idle_id = 0; flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); return G_SOURCE_REMOVE; } @@ -452,12 +460,13 @@ meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src) } static gboolean -meta_screen_cast_area_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, - int width, - int height, - int stride, - uint8_t *data, - GError **error) +meta_screen_cast_area_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + int width, + int height, + int stride, + uint8_t *data, + GError **error) { MetaScreenCastAreaStreamSrc *area_src = META_SCREEN_CAST_AREA_STREAM_SRC (src); @@ -495,9 +504,10 @@ meta_screen_cast_area_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src } static gboolean -meta_screen_cast_area_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error) +meta_screen_cast_area_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error) { MetaScreenCastAreaStreamSrc *area_src = META_SCREEN_CAST_AREA_STREAM_SRC (src); @@ -537,12 +547,16 @@ meta_screen_cast_area_stream_record_follow_up (MetaScreenCastStreamSrc *src) { MetaScreenCastAreaStreamSrc *area_src = META_SCREEN_CAST_AREA_STREAM_SRC (src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove); flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index fa7f6b292..28d112a2f 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -136,12 +136,14 @@ maybe_record_frame_on_idle (gpointer user_data) MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; monitor_src->maybe_record_idle_id = 0; flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, paint_phase, NULL); return G_SOURCE_REMOVE; } @@ -169,10 +171,13 @@ stage_painted (MetaStage *stage, if (meta_screen_cast_stream_src_uses_dma_bufs (src)) { MetaScreenCastRecordFlag flags = META_SCREEN_CAST_RECORD_FLAG_NONE; + MetaScreenCastPaintPhase paint_phase = + META_SCREEN_CAST_PAINT_PHASE_PRE_SWAP_BUFFER; record_result = meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (src, flags, + paint_phase, NULL, presentation_time_us); } @@ -196,6 +201,7 @@ before_stage_painted (MetaStage *stage, MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; int64_t presentation_time_us; @@ -212,8 +218,10 @@ before_stage_painted (MetaStage *stage, presentation_time_us = g_get_monotonic_time (); flags = META_SCREEN_CAST_RECORD_FLAG_NONE; + paint_phase = META_SCREEN_CAST_PAINT_PHASE_PRE_PAINT; meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (src, flags, + paint_phase, NULL, presentation_time_us); } @@ -285,6 +293,7 @@ static void sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; if (is_redraw_queued (monitor_src)) @@ -294,7 +303,10 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) return; flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -530,12 +542,13 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) } static gboolean -meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, - int width, - int height, - int stride, - uint8_t *data, - GError **error) +meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + int width, + int height, + int stride, + uint8_t *data, + GError **error) { MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (src); @@ -579,9 +592,10 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc * } static gboolean -meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error) +meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error) { MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (src); diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index 45c39ea36..6b4c63ee8 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -252,28 +252,31 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src, } static gboolean -meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, - int width, - int height, - int stride, - uint8_t *data, - GError **error) +meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + int width, + int height, + int stride, + uint8_t *data, + GError **error) { MetaScreenCastStreamSrcClass *klass = META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); - return klass->record_to_buffer (src, width, height, stride, data, error); + return klass->record_to_buffer (src, paint_phase, + width, height, stride, data, error); } static gboolean -meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error) +meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error) { MetaScreenCastStreamSrcClass *klass = META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); - return klass->record_to_framebuffer (src, framebuffer, error); + return klass->record_to_framebuffer (src, paint_phase, framebuffer, error); } static void @@ -582,6 +585,7 @@ meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src, static gboolean do_record_frame (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags, + MetaScreenCastPaintPhase paint_phase, struct spa_buffer *spa_buffer, GError **error) { @@ -596,6 +600,7 @@ do_record_frame (MetaScreenCastStreamSrc *src, int stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); return meta_screen_cast_stream_src_record_to_buffer (src, + paint_phase, width, height, stride, @@ -611,6 +616,7 @@ do_record_frame (MetaScreenCastStreamSrc *src, cogl_dma_buf_handle_get_framebuffer (dmabuf_handle); return meta_screen_cast_stream_src_record_to_framebuffer (src, + paint_phase, dmabuf_fbo, error); } @@ -730,12 +736,14 @@ maybe_add_damaged_regions_metadata (MetaScreenCastStreamSrc *src, MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags, + MetaScreenCastPaintPhase paint_phase, const MtkRegion *redraw_clip) { int64_t now_us = g_get_monotonic_time (); return meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (src, flags, + paint_phase, redraw_clip, now_us); } @@ -743,6 +751,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags, + MetaScreenCastPaintPhase paint_phase, const MtkRegion *redraw_clip, int64_t frame_timestamp_us) { @@ -842,7 +851,7 @@ meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStr g_autoptr (GError) error = NULL; g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove); - if (do_record_frame (src, flags, spa_buffer, &error)) + if (do_record_frame (src, flags, paint_phase, spa_buffer, &error)) { maybe_add_damaged_regions_metadata (src, spa_buffer); struct spa_meta_region *spa_meta_video_crop; diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h index 7d7a44ca9..672715df7 100644 --- a/src/backends/meta-screen-cast-stream-src.h +++ b/src/backends/meta-screen-cast-stream-src.h @@ -47,6 +47,13 @@ typedef enum _MetaScreenCastRecordResult META_SCREEN_CAST_RECORD_RESULT_RECORDED_CURSOR = 1 << 1, } MetaScreenCastRecordResult; +typedef enum _MetaScreenCastPaintPhase +{ + META_SCREEN_CAST_PAINT_PHASE_DETACHED, + META_SCREEN_CAST_PAINT_PHASE_PRE_PAINT, + META_SCREEN_CAST_PAINT_PHASE_PRE_SWAP_BUFFER, +} MetaScreenCastPaintPhase; + #define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ()) G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc, meta_screen_cast_stream_src, @@ -64,14 +71,16 @@ struct _MetaScreenCastStreamSrcClass void (* enable) (MetaScreenCastStreamSrc *src); void (* disable) (MetaScreenCastStreamSrc *src); gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, int width, int height, int stride, uint8_t *data, GError **error); - gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error); + gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error); void (* record_follow_up) (MetaScreenCastStreamSrc *src); gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src, @@ -91,10 +100,12 @@ gboolean meta_screen_cast_stream_src_is_enabled (MetaScreenCastStreamSrc *src); MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags, + MetaScreenCastPaintPhase paint_phase, const MtkRegion *redraw_clip); MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStreamSrc *src, MetaScreenCastRecordFlag flags, + MetaScreenCastPaintPhase paint_phase, const MtkRegion *redraw_clip, int64_t frame_timestamp_us); diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c b/src/backends/meta-screen-cast-virtual-stream-src.c index 160ab7acd..94fa5987c 100644 --- a/src/backends/meta-screen-cast-virtual-stream-src.c +++ b/src/backends/meta-screen-cast-virtual-stream-src.c @@ -125,6 +125,7 @@ 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)) @@ -134,7 +135,10 @@ sync_cursor_state (MetaScreenCastVirtualStreamSrc *virtual_src) return; flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -201,10 +205,14 @@ actors_painted (MetaStage *stage, gpointer user_data) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, redraw_clip); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_PRE_SWAP_BUFFER; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + redraw_clip); } static void @@ -366,12 +374,13 @@ meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src) } static gboolean -meta_screen_cast_virtual_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, - int width, - int height, - int stride, - uint8_t *data, - GError **error) +meta_screen_cast_virtual_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + int width, + int height, + int stride, + uint8_t *data, + GError **error) { MetaScreenCastStream *stream; ClutterPaintFlag paint_flags; @@ -410,9 +419,10 @@ meta_screen_cast_virtual_stream_src_record_to_buffer (MetaScreenCastStreamSrc * } static gboolean -meta_screen_cast_virtual_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error) +meta_screen_cast_virtual_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error) { ClutterStageView *view; CoglFramebuffer *view_framebuffer; diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c index 16a0c5aa1..71dc13d71 100644 --- a/src/backends/meta-screen-cast-window-stream-src.c +++ b/src/backends/meta-screen-cast-window-stream-src.c @@ -368,10 +368,14 @@ screen_cast_window_damaged (MetaWindowActor *actor, MetaScreenCastWindowStreamSrc *window_src) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -386,13 +390,17 @@ static void sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; if (meta_screen_cast_window_has_damage (window_src->screen_cast_window)) return; flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -429,6 +437,7 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src) MetaBackend *backend = get_backend (window_src); ClutterStage *stage = get_stage (window_src); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + MetaScreenCastPaintPhase paint_phase; MetaWindowActor *window_actor; MetaScreenCastStream *stream; MetaScreenCastRecordFlag flags; @@ -475,7 +484,10 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src) } flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void @@ -488,12 +500,13 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src) } static gboolean -meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, - int width, - int height, - int stride, - uint8_t *data, - GError **error) +meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + int width, + int height, + int stride, + uint8_t *data, + GError **error) { MetaScreenCastWindowStreamSrc *window_src = META_SCREEN_CAST_WINDOW_STREAM_SRC (src); @@ -504,9 +517,10 @@ meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *s } static gboolean -meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, - CoglFramebuffer *framebuffer, - GError **error) +meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + MetaScreenCastPaintPhase paint_phase, + CoglFramebuffer *framebuffer, + GError **error) { MetaScreenCastWindowStreamSrc *window_src = META_SCREEN_CAST_WINDOW_STREAM_SRC (src); @@ -546,10 +560,14 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr static void meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src) { + MetaScreenCastPaintPhase paint_phase; MetaScreenCastRecordFlag flags; flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags, NULL); + paint_phase = META_SCREEN_CAST_PAINT_PHASE_DETACHED; + meta_screen_cast_stream_src_maybe_record_frame (src, flags, + paint_phase, + NULL); } static void