[mutter/gnome-40] screen-cast/monitor-src: Use clutter_stage_paint_to_buffer
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gnome-40] screen-cast/monitor-src: Use clutter_stage_paint_to_buffer
- Date: Tue, 21 Sep 2021 15:17:26 +0000 (UTC)
commit ea9375dd5484c366410400facbc0abc6f5ab0cb4
Author: Michel Dänzer <mdaenzer redhat com>
Date: Fri Jun 25 18:33:28 2021 +0200
screen-cast/monitor-src: Use clutter_stage_paint_to_buffer
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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1914>
(cherry picked from commit 6c818cd8d5d29a21288d64fcbb13eae6a69d65df)
src/backends/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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]