From d29c8e290c99d1d9f8ffe4ffc5e4789783e26f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 10 Jun 2020 14:43:16 +0200 Subject: [PATCH] clutter/frame-clock: Add explicit destroy function The frame clock owner should be able to explicitly destroy (i.e. make defunct) a frame clock, e.g. when a stage view is destructed. This is so that other objects can keep reference to its without it being left around even after stopped being usable. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285 --- clutter/clutter/clutter-frame-clock.c | 38 ++++++++++++++++--- clutter/clutter/clutter-frame-clock.h | 3 ++ clutter/clutter/clutter-stage-view.c | 2 +- .../clutter/conform/frame-clock-timeline.c | 6 +-- src/tests/clutter/conform/frame-clock.c | 16 ++++---- 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c index 3ff7ca551..9c39ade38 100644 --- a/clutter/clutter/clutter-frame-clock.c +++ b/clutter/clutter/clutter-frame-clock.c @@ -24,6 +24,15 @@ #include "clutter/clutter-timeline-private.h" #include "cogl/cogl-trace.h" +enum +{ + DESTROY, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + /* Wait 2ms after vblank before starting to draw next frame */ #define SYNC_DELAY_US ms2us (2) @@ -495,18 +504,26 @@ clutter_frame_clock_new (float refresh_rate, return frame_clock; } -static void -clutter_frame_clock_finalize (GObject *object) +void +clutter_frame_clock_destroy (ClutterFrameClock *frame_clock) { - ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object); + g_object_run_dispose (G_OBJECT (frame_clock)); + g_object_unref (frame_clock); +} + +static void +clutter_frame_clock_dispose (GObject *object) +{ +ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object); if (frame_clock->source) { + g_signal_emit (frame_clock, signals[DESTROY], 0); g_source_destroy (frame_clock->source); - g_source_unref (frame_clock->source); + g_clear_pointer (&frame_clock->source, g_source_unref); } - G_OBJECT_CLASS (clutter_frame_clock_parent_class)->finalize (object); + G_OBJECT_CLASS (clutter_frame_clock_parent_class)->dispose (object); } static void @@ -520,5 +537,14 @@ clutter_frame_clock_class_init (ClutterFrameClockClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = clutter_frame_clock_finalize; + object_class->dispose = clutter_frame_clock_dispose; + + signals[DESTROY] = + g_signal_new (I_("destroy"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 0); } diff --git a/clutter/clutter/clutter-frame-clock.h b/clutter/clutter/clutter-frame-clock.h index 60eb41ea7..3c9ab7b5a 100644 --- a/clutter/clutter/clutter-frame-clock.h +++ b/clutter/clutter/clutter-frame-clock.h @@ -56,6 +56,9 @@ ClutterFrameClock * clutter_frame_clock_new (float re const ClutterFrameListenerIface *iface, gpointer user_data); +CLUTTER_EXPORT +void clutter_frame_clock_destroy (ClutterFrameClock *frame_clock); + CLUTTER_EXPORT void clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, ClutterFrameInfo *frame_info); diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c index 5dd8fc0d9..9e19055d6 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c @@ -1274,7 +1274,7 @@ clutter_stage_view_dispose (GObject *object) g_clear_pointer (&priv->offscreen, cogl_object_unref); g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); g_clear_pointer (&priv->redraw_clip, cairo_region_destroy); - g_clear_object (&priv->frame_clock); + g_clear_pointer (&priv->frame_clock, clutter_frame_clock_destroy); G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object); } diff --git a/src/tests/clutter/conform/frame-clock-timeline.c b/src/tests/clutter/conform/frame-clock-timeline.c index 766d49f11..7e5798b4e 100644 --- a/src/tests/clutter/conform/frame-clock-timeline.c +++ b/src/tests/clutter/conform/frame-clock-timeline.c @@ -109,7 +109,7 @@ frame_clock_timeline_basic (void) g_main_loop_unref (main_loop); g_object_unref (timeline); g_assert_null (timeline); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); g_assert_null (frame_clock); } @@ -192,9 +192,9 @@ frame_clock_timeline_switch (void) g_main_loop_unref (main_loop); g_object_unref (timeline); g_assert_null (timeline); - g_object_unref (frame_clock1); + clutter_frame_clock_destroy (frame_clock1); g_assert_null (frame_clock1); - g_object_unref (frame_clock2); + clutter_frame_clock_destroy (frame_clock2); g_assert_null (frame_clock2); } diff --git a/src/tests/clutter/conform/frame-clock.c b/src/tests/clutter/conform/frame-clock.c index 1943c174a..fad3001cd 100644 --- a/src/tests/clutter/conform/frame-clock.c +++ b/src/tests/clutter/conform/frame-clock.c @@ -166,7 +166,7 @@ frame_clock_schedule_update (void) g_main_loop_unref (test.main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); g_source_destroy (source); g_source_unref (source); } @@ -242,7 +242,7 @@ frame_clock_immediate_present (void) g_assert_cmpint (after_us - before_us, >, 9 * refresh_interval_us); g_main_loop_unref (main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); } static gboolean @@ -323,7 +323,7 @@ frame_clock_delayed_damage (void) g_assert_cmpint (after_us - before_us, >, 100000 + refresh_interval_us); g_main_loop_unref (test.main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); g_source_destroy (source); g_source_unref (source); } @@ -372,7 +372,7 @@ frame_clock_no_damage (void) g_main_loop_run (main_loop); g_main_loop_unref (main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); } typedef struct _UpdateNowFrameClockTest @@ -472,7 +472,7 @@ frame_clock_schedule_update_now (void) g_main_loop_unref (test.base.main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); g_source_destroy (source); g_source_unref (source); } @@ -543,7 +543,7 @@ frame_clock_before_frame (void) g_assert_cmpint (expected_frame_count, >, 2); g_main_loop_unref (main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); } typedef struct _InhibitTest @@ -625,7 +625,7 @@ frame_clock_inhibit (void) g_assert_cmpint (test.frame_count, ==, 2); g_main_loop_unref (test.main_loop); - g_object_unref (test.frame_clock); + clutter_frame_clock_destroy (test.frame_clock); } typedef struct _RescheduleOnIdleFrameClockTest @@ -687,7 +687,7 @@ frame_clock_reschedule_on_idle (void) g_main_loop_run (test.base.main_loop); g_main_loop_unref (test.base.main_loop); - g_object_unref (frame_clock); + clutter_frame_clock_destroy (frame_clock); } CLUTTER_TEST_SUITE (