From 4de740c7a3f1161d734a244036f584d86a7d8674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 3 Feb 2022 11:45:18 +0100 Subject: [PATCH] screen-cast/virtual-src: Don't recreate the virtual monitor on resizes Keep the virtual monitor around if it's being resized. This reduces the number of unnecessary object rebuilding that happen during monitor rebuilding. This changes finalize() vfunc into a dispose() vfunc in the abstract stream source object implementation, as it needs the abstract stream source object to close the stream early, so that various signal listeners get disconnected early. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1904 Part-of: --- src/backends/meta-screen-cast-stream-src.c | 12 ++++---- .../meta-screen-cast-virtual-stream-src.c | 28 +++++++++++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index e801324f0..e86f9a2b7 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -1213,7 +1213,8 @@ create_pipewire_source (MetaScreenCastStreamSrc *src) G_IO_IN | G_IO_ERR); pw_loop_enter (pipewire_source->pipewire_loop); - g_source_attach (&pipewire_source->base, NULL); + g_source_attach (source, NULL); + g_source_unref (source); return pipewire_source; } @@ -1285,7 +1286,7 @@ meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src) } static void -meta_screen_cast_stream_src_finalize (GObject *object) +meta_screen_cast_stream_src_dispose (GObject *object) { MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (object); MetaScreenCastStreamSrcPrivate *priv = @@ -1298,10 +1299,9 @@ meta_screen_cast_stream_src_finalize (GObject *object) g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy); g_clear_pointer (&priv->pipewire_core, pw_core_disconnect); g_clear_pointer (&priv->pipewire_context, pw_context_destroy); - g_source_destroy (&priv->pipewire_source->base); - g_source_unref (&priv->pipewire_source->base); + g_clear_pointer ((GSource **) &priv->pipewire_source, g_source_destroy); - G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->finalize (object); + G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->dispose (object); } static void @@ -1360,7 +1360,7 @@ meta_screen_cast_stream_src_class_init (MetaScreenCastStreamSrcClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = meta_screen_cast_stream_src_finalize; + object_class->dispose = meta_screen_cast_stream_src_dispose; object_class->set_property = meta_screen_cast_stream_src_set_property; object_class->get_property = meta_screen_cast_stream_src_get_property; diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c b/src/backends/meta-screen-cast-virtual-stream-src.c index 47a917da9..3341aedd9 100644 --- a/src/backends/meta-screen-cast-virtual-stream-src.c +++ b/src/backends/meta-screen-cast-virtual-stream-src.c @@ -312,8 +312,6 @@ meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src) case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: break; } - - g_clear_object (&virtual_src->virtual_monitor); } static gboolean @@ -526,12 +524,20 @@ ensure_virtual_monitor (MetaScreenCastVirtualStreamSrc *virtual_src, MetaCrtcMode *crtc_mode = meta_virtual_monitor_get_crtc_mode (virtual_monitor); const MetaCrtcModeInfo *mode_info = meta_crtc_mode_get_info (crtc_mode); + float refresh_rate; if (mode_info->width == video_format->size.width && mode_info->height == video_format->size.height) return; - g_clear_object (&virtual_src->virtual_monitor); + refresh_rate = ((float) video_format->max_framerate.num / + video_format->max_framerate.denom); + meta_virtual_monitor_set_mode (virtual_monitor, + video_format->size.width, + video_format->size.height, + refresh_rate); + meta_monitor_manager_reload (monitor_manager); + return; } virtual_monitor = create_virtual_monitor (virtual_src, video_format, &error); @@ -585,6 +591,19 @@ hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface) meta_screen_cast_virtual_stream_src_is_cursor_inhibited; } +static void +meta_screen_cast_virtual_stream_src_dispose (GObject *object) +{ + MetaScreenCastVirtualStreamSrc *virtual_src = + META_SCREEN_CAST_VIRTUAL_STREAM_SRC (object); + GObjectClass *parent_class = + G_OBJECT_CLASS (meta_screen_cast_virtual_stream_src_parent_class); + + parent_class->dispose (object); + + g_clear_object (&virtual_src->virtual_monitor); +} + static void meta_screen_cast_virtual_stream_src_init (MetaScreenCastVirtualStreamSrc *virtual_src) { @@ -593,9 +612,12 @@ meta_screen_cast_virtual_stream_src_init (MetaScreenCastVirtualStreamSrc *virtua static void meta_screen_cast_virtual_stream_src_class_init (MetaScreenCastVirtualStreamSrcClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); MetaScreenCastStreamSrcClass *src_class = META_SCREEN_CAST_STREAM_SRC_CLASS (klass); + object_class->dispose = meta_screen_cast_virtual_stream_src_dispose; + src_class->get_specs = meta_screen_cast_virtual_stream_src_get_specs; src_class->enable = meta_screen_cast_virtual_stream_src_enable; src_class->disable = meta_screen_cast_virtual_stream_src_disable;