From 10d1de2bdf559de77b5fc89c6338f8606e63aaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Jun 2021 18:29:06 +0200 Subject: [PATCH 1/4] screen-cast/monitor-src: Always set before-paint watch We weren't setting it for META_SCREEN_CAST_CURSOR_MODE_EMBEDDED, so that case didn't work correctly with scanouts. Suggested by Georges Basile Stavracas Neto. Part-of: --- src/backends/meta-screen-cast-monitor-stream-src.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index b85c44fe12..ac6be6730f 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -340,13 +340,14 @@ reattach_watches (MetaScreenCastMonitorStreamSrc *monitor_src) meta_stage_remove_watch (META_STAGE (stage), l->data); g_clear_pointer (&monitor_src->watches, g_list_free); + add_view_watches (monitor_src, + META_STAGE_WATCH_BEFORE_PAINT, + before_stage_painted); + switch (meta_screen_cast_stream_get_cursor_mode (stream)) { case META_SCREEN_CAST_CURSOR_MODE_METADATA: case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: - add_view_watches (monitor_src, - META_STAGE_WATCH_BEFORE_PAINT, - before_stage_painted); add_view_watches (monitor_src, META_STAGE_WATCH_AFTER_ACTOR_PAINT, stage_painted); -- GitLab From 6c818cd8d5d29a21288d64fcbb13eae6a69d65df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Jun 2021 18:33:28 +0200 Subject: [PATCH 2/4] screen-cast/monitor-src: Use clutter_stage_paint_to_buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It works correctly with scanouts, in contrast to clutter_stage_capture_into. Inspired by meta_screen_cast_area_stream_src_record_to_buffer. maybe_paint_cursor_sprite is now unused and thus removed. v2: * clutter_stage_paint_to_buffer requires switching to recording from an idle callback as well. (Jonas Ã…dahl) v3: * Set human readable name for idle source. (Ivan Molodetskikh) Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1940 Part-of: --- .../meta-screen-cast-monitor-stream-src.c | 139 +++++++----------- 1 file changed, 57 insertions(+), 82 deletions(-) diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index ac6be6730f..82d3862c9a 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -48,6 +48,8 @@ struct _MetaScreenCastMonitorStreamSrc gulong position_invalidated_handler_id; gulong cursor_changed_handler_id; + + guint maybe_record_idle_id; }; static void @@ -116,17 +118,39 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src, return TRUE; } +static gboolean +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); + 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); + + return G_SOURCE_REMOVE; +} + static void stage_painted (MetaStage *stage, ClutterStageView *view, ClutterPaintContext *paint_context, gpointer user_data) { - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); - MetaScreenCastRecordFlag flags; + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); - flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags); + if (monitor_src->maybe_record_idle_id) + return; + + monitor_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, + src); + g_source_set_name_by_id (monitor_src->maybe_record_idle_id, + "[mutter] maybe_record_frame_on_idle [monitor-src]"); } static void @@ -135,17 +159,20 @@ before_stage_painted (MetaStage *stage, ClutterPaintContext *paint_context, gpointer user_data) { - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); - CoglScanout *scanout; + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); - scanout = clutter_stage_view_peek_scanout (view); - if (scanout) - { - MetaScreenCastRecordFlag flags; + if (monitor_src->maybe_record_idle_id) + return; - flags = META_SCREEN_CAST_RECORD_FLAG_NONE; - meta_screen_cast_stream_src_maybe_record_frame (src, flags); - } + if (!clutter_stage_view_peek_scanout (view)) + return; + + monitor_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, + src); + g_source_set_name_by_id (monitor_src->maybe_record_idle_id, + "[mutter] maybe_record_frame_on_idle [monitor-src]"); } static MetaBackend * @@ -440,6 +467,8 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) g_clear_signal_handler (&monitor_src->cursor_changed_handler_id, cursor_tracker); + g_clear_handle_id (&monitor_src->maybe_record_idle_id, g_source_remove); + switch (meta_screen_cast_stream_get_cursor_mode (stream)) { case META_SCREEN_CAST_CURSOR_MODE_METADATA: @@ -451,70 +480,6 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) } } -static void -maybe_paint_cursor_sprite (MetaScreenCastMonitorStreamSrc *monitor_src, - int width, - int height, - int stride, - uint8_t *data) -{ - MetaBackend *backend = get_backend (monitor_src); - MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (backend); - MetaCursorSprite *cursor_sprite; - CoglTexture *sprite_texture; - int sprite_width, sprite_height, sprite_stride; - float sprite_scale; - uint8_t *sprite_data; - cairo_surface_t *sprite_surface; - graphene_rect_t sprite_rect; - cairo_surface_t *surface; - cairo_t *cr; - - if (!is_cursor_in_stream (monitor_src)) - return; - - cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); - if (!cursor_sprite) - return; - - if (meta_cursor_renderer_is_overlay_visible (cursor_renderer)) - return; - - sprite_rect = meta_cursor_renderer_calculate_rect (cursor_renderer, - cursor_sprite); - sprite_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); - sprite_width = cogl_texture_get_width (sprite_texture); - sprite_height = cogl_texture_get_height (sprite_texture); - sprite_stride = sprite_width * 4; - sprite_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); - sprite_data = g_new0 (uint8_t, sprite_stride * sprite_height); - cogl_texture_get_data (sprite_texture, - CLUTTER_CAIRO_FORMAT_ARGB32, - sprite_stride, - sprite_data); - sprite_surface = cairo_image_surface_create_for_data (sprite_data, - CAIRO_FORMAT_ARGB32, - sprite_width, - sprite_height, - sprite_stride); - cairo_surface_set_device_scale (sprite_surface, sprite_scale, sprite_scale); - - surface = cairo_image_surface_create_for_data (data, - CAIRO_FORMAT_ARGB32, - width, height, stride); - - cr = cairo_create (surface); - cairo_set_source_surface (cr, sprite_surface, - sprite_rect.origin.x, - sprite_rect.origin.y); - cairo_paint (cr); - cairo_destroy (cr); - cairo_surface_destroy (sprite_surface); - cairo_surface_destroy (surface); - g_free (sprite_data); -} - static gboolean meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, int width, @@ -530,6 +495,7 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc * MetaMonitor *monitor; MetaLogicalMonitor *logical_monitor; float scale; + ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_CLEAR; monitor = get_monitor (monitor_src); logical_monitor = meta_monitor_get_logical_monitor (monitor); @@ -540,18 +506,25 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc * else scale = 1.0; - clutter_stage_capture_into (stage, &logical_monitor->rect, scale, data, stride); - switch (meta_screen_cast_stream_get_cursor_mode (stream)) { - case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: - maybe_paint_cursor_sprite (monitor_src, width, height, stride, data); - break; case META_SCREEN_CAST_CURSOR_MODE_METADATA: case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS; + break; + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + paint_flags |= CLUTTER_PAINT_FLAG_FORCE_CURSORS; break; } + if (!clutter_stage_paint_to_buffer (stage, &logical_monitor->rect, scale, + data, + stride, + CLUTTER_CAIRO_FORMAT_ARGB32, + paint_flags, + error)) + return FALSE; + return TRUE; } @@ -636,6 +609,8 @@ meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src) MetaRectangle logical_monitor_layout; GList *l; + g_clear_handle_id (&monitor_src->maybe_record_idle_id, g_source_remove); + monitor = get_monitor (monitor_src); logical_monitor = meta_monitor_get_logical_monitor (monitor); logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); -- GitLab From 62cdf8de5ead1672980e864ab7a1929452817ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Jun 2021 18:43:39 +0200 Subject: [PATCH 3/4] clutter/stage: Remove clutter_stage_capture_into Not used anymore. Part-of: --- clutter/clutter/clutter-mutter.h | 7 ------ clutter/clutter/clutter-stage.c | 38 -------------------------------- 2 files changed, 45 deletions(-) diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index 95011aadde..818a48bb91 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -51,13 +51,6 @@ void clutter_set_custom_backend_func (ClutterBackend *(* func) (void)); CLUTTER_EXPORT int64_t clutter_stage_get_frame_counter (ClutterStage *stage); -CLUTTER_EXPORT -void clutter_stage_capture_into (ClutterStage *stage, - cairo_rectangle_int_t *rect, - float scale, - uint8_t *data, - int stride); - CLUTTER_EXPORT void clutter_stage_capture_view_into (ClutterStage *stage, ClutterStageView *view, diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 658a3156a5..b784a45023 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -3370,44 +3370,6 @@ clutter_stage_capture_view_into (ClutterStage *stage, cogl_object_unref (bitmap); } -void -clutter_stage_capture_into (ClutterStage *stage, - cairo_rectangle_int_t *rect, - float scale, - uint8_t *data, - int stride) -{ - ClutterStagePrivate *priv = stage->priv; - GList *l; - int bpp = 4; - - for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) - { - ClutterStageView *view = l->data; - cairo_rectangle_int_t view_layout; - cairo_region_t *region; - cairo_rectangle_int_t capture_rect; - int x_offset, y_offset; - - clutter_stage_view_get_layout (view, &view_layout); - region = cairo_region_create_rectangle (&view_layout); - cairo_region_intersect_rectangle (region, rect); - - cairo_region_get_extents (region, &capture_rect); - cairo_region_destroy (region); - - x_offset = roundf ((capture_rect.x - rect->x) * scale); - y_offset = roundf ((capture_rect.y - rect->y) * scale); - - clutter_stage_capture_view_into (stage, view, - &capture_rect, - (data + - (x_offset * bpp) + - (y_offset * stride)), - stride); - } -} - /** * clutter_stage_peek_stage_views: (skip) */ -- GitLab From 3059d3ffc881e8fbe133238a401492313d75ae8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Jun 2021 18:47:46 +0200 Subject: [PATCH 4/4] cursor-renderer: Remove meta_cursor_renderer_is_overlay_visible Not used anymore. Part-of: --- src/backends/meta-cursor-renderer.c | 12 ------------ src/backends/meta-cursor-renderer.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 3353b17d3d..5ed0fb8fcd 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -470,18 +470,6 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer) return priv->overlay_cursor; } -gboolean -meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer) -{ - MetaCursorRendererPrivate *priv = - meta_cursor_renderer_get_instance_private (renderer); - - if (!priv->stage_overlay) - return FALSE; - - return meta_overlay_is_visible (priv->stage_overlay); -} - ClutterInputDevice * meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer) { diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index f6de01bfbc..89a73aef11 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -66,8 +66,6 @@ void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer); -gboolean meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer); - graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); -- GitLab