[mutter] tests: Add test for destroyed frame clock free timeline actor



commit c60cba4eeb4ba24b8fa6e736bb05e2a8e2a703e3
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Feb 8 18:40:18 2021 +0100

    tests: Add test for destroyed frame clock free timeline actor
    
    This would without 'clutter/timeline: Clear stage view listener when
    actor destroyed' result in backtraces such as
    
    Program terminated with signal SIGSEGV, Segmentation fault.
      #0  on_stage_stage_views_changed ()
      #1  g_closure_invoke ()
      #2  signal_emit_unlocked_R ()
      #3  g_signal_emit_valist ()
      #4  g_signal_emit ()
      #5  update_stage_views ()
      #6  clutter_actor_update_stage_views ()
      #7  clutter_stage_update_actor_stage_views ()
      #8  handle_frame_clock_frame ()
      #9  clutter_frame_clock_dispatch ()
      #10 frame_clock_source_dispatch ()
      #11 g_main_dispatch ()
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1719>

 src/tests/stage-view-tests.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
---
diff --git a/src/tests/stage-view-tests.c b/src/tests/stage-view-tests.c
index 9604a4ab59..101fbdcdaa 100644
--- a/src/tests/stage-view-tests.c
+++ b/src/tests/stage-view-tests.c
@@ -1077,6 +1077,81 @@ meta_test_actor_stage_views_and_frame_clocks_freed (void)
   clutter_actor_destroy (actor_2);
 }
 
+static void
+ensure_view_count (int n_views)
+{
+  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 test_case_setup;
+  MetaMonitorTestSetup *test_setup;
+
+  test_case_setup = initial_test_case_setup;
+  test_case_setup.n_outputs = n_views;
+  test_case_setup.n_crtcs = n_views;
+  test_setup = create_monitor_test_setup (&test_case_setup,
+                                          MONITOR_TEST_FLAG_NO_STORED);
+  meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
+}
+
+static void
+meta_test_timeline_actor_destroyed (void)
+{
+  MetaBackend *backend = meta_get_backend ();
+  ClutterActor *stage;
+  GList *stage_views;
+  ClutterActor *persistent_actor;
+  ClutterActor *actor;
+  ClutterTimeline *timeline;
+  gboolean did_stage_views_changed = FALSE;
+
+  ensure_view_count (0);
+
+  stage = meta_backend_get_stage (backend);
+  clutter_actor_show (stage);
+
+  persistent_actor = clutter_actor_new ();
+  clutter_actor_add_child (stage, persistent_actor);
+
+  stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
+  g_assert_null (stage_views);
+  stage_views = clutter_actor_peek_stage_views (stage);
+  g_assert_null (stage_views);
+  g_assert_null (clutter_actor_pick_frame_clock (stage, NULL));
+
+  actor = clutter_actor_new ();
+  clutter_actor_add_child (stage, actor);
+  g_assert_null (clutter_actor_pick_frame_clock (actor, NULL));
+
+  timeline = clutter_timeline_new_for_actor (actor, 100);
+  clutter_timeline_start (timeline);
+
+  g_signal_connect (stage, "stage-views-changed",
+                    G_CALLBACK (on_stage_views_changed),
+                    &did_stage_views_changed);
+
+  clutter_actor_destroy (actor);
+  g_object_unref (timeline);
+
+  ensure_view_count (1);
+
+  stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
+  g_assert_cmpint (g_list_length (stage_views), ==, 1);
+
+  g_assert_false (did_stage_views_changed);
+  clutter_actor_queue_redraw (persistent_actor);
+  clutter_stage_schedule_update (CLUTTER_STAGE (stage));
+  wait_for_paint (stage);
+  g_assert_true (did_stage_views_changed);
+
+  g_signal_handlers_disconnect_by_func (stage, on_stage_views_changed,
+                                        &did_stage_views_changed);
+
+  clutter_actor_destroy (persistent_actor);
+}
+
 static void
 init_tests (int argc, char **argv)
 {
@@ -1104,6 +1179,8 @@ init_tests (int argc, char **argv)
                    meta_test_actor_stage_views_parent_views_changed);
   g_test_add_func ("/stage-views/actor-stage-views-and-frame-clocks-freed",
                    meta_test_actor_stage_views_and_frame_clocks_freed);
+  g_test_add_func ("/stage-views/timeline/actor-destroyed",
+                   meta_test_timeline_actor_destroyed);
 }
 
 int


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]