From 090c72b3c32a393826e6d3bc52a647dc81ae70ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 12 Aug 2020 19:30:57 +0200 Subject: [PATCH] tests/stage-view: Test timelines notice stage views changing Timelines where the frame clock was picked from a parent of the associated actor didn't get notified about any stage views changes, as it only listened on the associated actor. If that actor didn't actually get its stage views changed (because it went from empty to empty), we'd end up with a stale frame clock, leading to crashes. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1404 --- src/tests/stage-view-tests.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/tests/stage-view-tests.c b/src/tests/stage-view-tests.c index 684319d41..cff212d4f 100644 --- a/src/tests/stage-view-tests.c +++ b/src/tests/stage-view-tests.c @@ -814,6 +814,90 @@ meta_test_actor_stage_views_timeline (void) g_main_loop_unref (test.main_loop); } +static void +meta_test_actor_stage_views_parent_views_rebuilt (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MonitorTestCaseSetup frame_clock_test_setup; + MetaMonitorTestSetup *test_setup; + ClutterActor *stage, *container, *test_actor; + GList *stage_views; + ClutterTimeline *timeline; + ClutterFrameClock *timeline_frame_clock; + ClutterFrameClock *view_frame_clock; + ClutterStageView *old_stage_view; + ClutterFrameClock *old_frame_clock; + + stage = meta_backend_get_stage (backend); + + frame_clock_test_setup = initial_test_case_setup; + frame_clock_test_setup.n_outputs = 1; + frame_clock_test_setup.n_crtcs = 1; + test_setup = create_monitor_test_setup (&frame_clock_test_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage)); + g_assert_cmpint (g_list_length (stage_views), ==, 1); + + container = clutter_actor_new (); + clutter_actor_set_size (container, 100, 100); + clutter_actor_set_position (container, 0, 0); + clutter_actor_add_child (stage, container); + + test_actor = clutter_actor_new (); + clutter_actor_set_size (test_actor, 0, 0); + clutter_actor_add_child (container, test_actor); + + clutter_actor_show (stage); + wait_for_paint (stage); + + is_on_stage_views (test_actor, 0); + is_on_stage_views (container, 1, stage_views->data); + is_on_stage_views (stage, 1, stage_views->data); + + timeline = clutter_timeline_new_for_actor (test_actor, 100); + clutter_timeline_start (timeline); + + timeline_frame_clock = clutter_timeline_get_frame_clock (timeline); + view_frame_clock = clutter_stage_view_get_frame_clock (stage_views->data); + g_assert_nonnull (timeline_frame_clock); + g_assert_nonnull (view_frame_clock); + g_assert (timeline_frame_clock == view_frame_clock); + + /* Keep the stage view alive so it can be used to compare with later. */ + old_stage_view = g_object_ref (stage_views->data); + old_frame_clock = + g_object_ref (clutter_stage_view_get_frame_clock (old_stage_view)); + + test_setup = create_monitor_test_setup (&frame_clock_test_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + wait_for_paint (stage); + + stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage)); + g_assert_cmpint (g_list_length (stage_views), ==, 1); + + g_assert (stage_views->data != old_stage_view); + view_frame_clock = clutter_stage_view_get_frame_clock (stage_views->data); + g_assert_nonnull (view_frame_clock); + g_assert (view_frame_clock != old_frame_clock); + + timeline_frame_clock = clutter_timeline_get_frame_clock (timeline); + g_assert_nonnull (timeline_frame_clock); + g_assert (timeline_frame_clock == view_frame_clock); + + g_object_unref (old_stage_view); + g_object_unref (old_frame_clock); + + clutter_actor_destroy (test_actor); + clutter_actor_destroy (container); +} + static void init_tests (int argc, char **argv) { @@ -835,6 +919,8 @@ init_tests (int argc, char **argv) meta_test_actor_stage_views_frame_clock); g_test_add_func ("/stage-views/actor-stage-views-timeline", meta_test_actor_stage_views_timeline); + g_test_add_func ("/stage-views/actor-stage-views-parent-rebuilt", + meta_test_actor_stage_views_parent_views_rebuilt); } int