From 45bda2d969f22b1028a1c0062e7f8554e475b23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 22 Feb 2023 10:10:06 +0100 Subject: [PATCH] renderer/native: Detach old onscreens when rebuilding views With detach meaning having the onscreen stop listening on configuration changes on the corresponding backing mode setting objects. We need to do this as there is a time between rebuilding the views, and that the new mode sets are called, where the old onscreen is kept alive, but the stage view is gone. At this point in time, if privacy screen or gamma configuration changes, e.g. by the night light temperature changing, the onscreen would attempt to schedule an update on the now gone stage view. This commit also renames the "keep onscreen alive" to "detached onscreens" to more clearly communicate that it's detached onscreens from their corresponding mode setting objects. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2621 Part-of: --- src/backends/native/meta-onscreen-native.c | 34 ++++++++++++++++++---- src/backends/native/meta-onscreen-native.h | 2 ++ src/backends/native/meta-renderer-native.c | 23 ++++++++------- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index b3f53b4aa..0df66372a 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -108,6 +108,9 @@ struct _MetaOnscreenNative gboolean is_gamma_lut_invalid; gboolean is_privacy_screen_invalid; + + gulong gamma_lut_changed_handler_id; + gulong privacy_screen_changed_handler_id; }; G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, @@ -2207,22 +2210,33 @@ meta_onscreen_native_new (MetaRendererNative *renderer_native, if (meta_crtc_get_gamma_lut_size (crtc) > 0) { onscreen_native->is_gamma_lut_invalid = TRUE; - g_signal_connect_object (crtc, "gamma-lut-changed", - G_CALLBACK (on_gamma_lut_changed), - onscreen_native, G_CONNECT_DEFAULT); + onscreen_native->gamma_lut_changed_handler_id = + g_signal_connect (crtc, "gamma-lut-changed", + G_CALLBACK (on_gamma_lut_changed), + onscreen_native); } if (meta_output_is_privacy_screen_supported (output)) { onscreen_native->is_privacy_screen_invalid = TRUE; - g_signal_connect_object (output, "notify::is-privacy-screen-enabled", - G_CALLBACK (on_privacy_screen_enabled_changed), - onscreen_native, G_CONNECT_DEFAULT); + onscreen_native->privacy_screen_changed_handler_id = + g_signal_connect (output, "notify::is-privacy-screen-enabled", + G_CALLBACK (on_privacy_screen_enabled_changed), + onscreen_native); } return onscreen_native; } +static void +clear_invalidation_handlers (MetaOnscreenNative *onscreen_native) +{ + g_clear_signal_handler (&onscreen_native->gamma_lut_changed_handler_id, + onscreen_native->crtc); + g_clear_signal_handler (&onscreen_native->privacy_screen_changed_handler_id, + onscreen_native->output); +} + static void meta_onscreen_native_dispose (GObject *object) { @@ -2232,6 +2246,8 @@ meta_onscreen_native_dispose (GObject *object) MetaRendererNative *renderer_native = onscreen_native->renderer_native; MetaRendererNativeGpuData *renderer_gpu_data; + clear_invalidation_handlers (onscreen_native); + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, onscreen_native->render_gpu); @@ -2300,3 +2316,9 @@ meta_onscreen_native_get_crtc (MetaOnscreenNative *onscreen_native) { return onscreen_native->crtc; } + +void +meta_onscreen_native_detach (MetaOnscreenNative *onscreen_native) +{ + clear_invalidation_handlers (onscreen_native); +} diff --git a/src/backends/native/meta-onscreen-native.h b/src/backends/native/meta-onscreen-native.h index 5c6af820a..05a9ecdb8 100644 --- a/src/backends/native/meta-onscreen-native.h +++ b/src/backends/native/meta-onscreen-native.h @@ -64,4 +64,6 @@ MetaCrtc * meta_onscreen_native_get_crtc (MetaOnscreenNative *onscreen_native); void meta_onscreen_native_invalidate (MetaOnscreenNative *onscreen_native); +void meta_onscreen_native_detach (MetaOnscreenNative *onscreen_native); + #endif /* META_ONSCREEN_NATIVE_H */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 83c373a9a..756caad63 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -94,7 +94,7 @@ struct _MetaRendererNative GList *pending_mode_set_views; gboolean pending_mode_set; - GList *kept_alive_onscreens; + GList *detached_onscreens; GList *lingering_onscreens; guint release_unused_gpus_idle_id; @@ -793,11 +793,11 @@ old_onscreen_freed (gpointer user_data, } static void -clear_kept_alive_onscreens (MetaRendererNative *renderer_native) +clear_detached_onscreens (MetaRendererNative *renderer_native) { GList *l; - for (l = renderer_native->kept_alive_onscreens; l; l = l->next) + for (l = renderer_native->detached_onscreens; l; l = l->next) { CoglOnscreen *onscreen; @@ -812,7 +812,7 @@ clear_kept_alive_onscreens (MetaRendererNative *renderer_native) g_list_prepend (renderer_native->lingering_onscreens, onscreen); } - g_clear_list (&renderer_native->kept_alive_onscreens, + g_clear_list (&renderer_native->detached_onscreens, g_object_unref); } @@ -855,7 +855,7 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) } } - clear_kept_alive_onscreens (renderer_native); + clear_detached_onscreens (renderer_native); meta_kms_notify_modes_set (kms); @@ -1416,7 +1416,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer, } static void -keep_current_onscreens_alive (MetaRenderer *renderer) +detach_onscreens (MetaRenderer *renderer) { MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); GList *views; @@ -1428,8 +1428,11 @@ keep_current_onscreens_alive (MetaRenderer *renderer) ClutterStageView *stage_view = l->data; CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view); - renderer_native->kept_alive_onscreens = - g_list_prepend (renderer_native->kept_alive_onscreens, + if (META_IS_ONSCREEN_NATIVE (onscreen)) + meta_onscreen_native_detach (META_ONSCREEN_NATIVE (onscreen)); + + renderer_native->detached_onscreens = + g_list_prepend (renderer_native->detached_onscreens, g_object_ref (onscreen)); } } @@ -1446,7 +1449,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) meta_kms_discard_pending_page_flips (kms); meta_kms_discard_pending_updates (kms); - keep_current_onscreens_alive (renderer); + detach_onscreens (renderer); parent_renderer_class->rebuild_views (renderer); @@ -2141,7 +2144,7 @@ meta_renderer_native_finalize (GObject *object) g_clear_handle_id (&renderer_native->release_unused_gpus_idle_id, g_source_remove); - clear_kept_alive_onscreens (renderer_native); + clear_detached_onscreens (renderer_native); g_hash_table_destroy (renderer_native->gpu_datas); g_clear_object (&renderer_native->gles3);