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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2863>
This commit is contained in:
Jonas Ådahl 2023-02-22 10:10:06 +01:00 committed by Marge Bot
parent 9434b01998
commit 45bda2d969
3 changed files with 43 additions and 16 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);