From 8de0771aad02cce7f69e27d37a4922583010c07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Jun 2021 12:54:46 +0200 Subject: [PATCH] screen-cast/area-src: Add before-paint watch to catch scanouts Scanouts are taken away after painting. However, when we're streaming, what we actually want is to capture whatever is going to end up on screen - and that includes the scanout if there's any. Add a before-paint watch that only records new frames if a scanout is set. Inspired by (and commit log mostly copied from) e6a13e5d5774 ("monitor-stream-src: Add before-paint watch to catch scanouts"). v2: * Do not call stage_painted from before_stage_painted (Georges Basile Stavracas Neto) Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1707 Part-of: --- .../meta-screen-cast-area-stream-src.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index 96953fe7f..aa1548101 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -231,6 +231,25 @@ maybe_record_frame_on_idle (gpointer user_data) return G_SOURCE_REMOVE; } +static void +before_stage_painted (MetaStage *stage, + ClutterStageView *view, + ClutterPaintContext *paint_context, + gpointer user_data) +{ + MetaScreenCastAreaStreamSrc *area_src = + META_SCREEN_CAST_AREA_STREAM_SRC (user_data); + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); + + if (area_src->maybe_record_idle_id) + return; + + if (!clutter_stage_view_peek_scanout (view)) + return; + + area_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, src); +} + static void stage_painted (MetaStage *stage, ClutterStageView *view, @@ -293,6 +312,14 @@ add_view_painted_watches (MetaScreenCastAreaStreamSrc *area_src) { MetaStageWatch *watch; + watch = meta_stage_watch_view (meta_stage, + CLUTTER_STAGE_VIEW (view), + META_STAGE_WATCH_BEFORE_PAINT, + before_stage_painted, + area_src); + + area_src->watches = g_list_prepend (area_src->watches, watch); + watch = meta_stage_watch_view (meta_stage, CLUTTER_STAGE_VIEW (view), META_STAGE_WATCH_AFTER_ACTOR_PAINT,