[mutter] clutter/frame-clock: Handle reschedule then dispatch results in idle
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter/frame-clock: Handle reschedule then dispatch results in idle
- Date: Thu, 2 Jul 2020 20:53:20 +0000 (UTC)
commit 847e89d31f103ebdca527eacbb78d590e60a4dbd
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Sat May 23 21:20:54 2020 +0200
clutter/frame-clock: Handle reschedule then dispatch results in idle
A frame clock dispatch doesn't necessarily result in a frame drawn,
meaning we'll end up in the idle state. However, it may be the case that
something still requires another frame, and will in that case have
requested one to be scheduled. In order to not dead lock, try to
reschedule directly if requested after dispatching, if we ended up in
the idle state.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
clutter/clutter/clutter-frame-clock.c | 1 +
src/tests/clutter/conform/frame-clock.c | 63 +++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
---
diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c
index c325c63fee..1ea524aca7 100644
--- a/clutter/clutter/clutter-frame-clock.c
+++ b/clutter/clutter/clutter-frame-clock.c
@@ -419,6 +419,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
break;
case CLUTTER_FRAME_RESULT_IDLE:
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
+ maybe_reschedule_update (frame_clock);
break;
}
break;
diff --git a/src/tests/clutter/conform/frame-clock.c b/src/tests/clutter/conform/frame-clock.c
index b865b132c3..74bcc42289 100644
--- a/src/tests/clutter/conform/frame-clock.c
+++ b/src/tests/clutter/conform/frame-clock.c
@@ -628,6 +628,68 @@ frame_clock_inhibit (void)
g_object_unref (test.frame_clock);
}
+typedef struct _RescheduleOnIdleFrameClockTest
+{
+ FrameClockTest base;
+} RescheduleOnIdleFrameClockTest;
+
+static ClutterFrameResult
+reschedule_on_idle_clock_frame (ClutterFrameClock *frame_clock,
+ int64_t frame_count,
+ int64_t time_us,
+ gpointer user_data)
+{
+ RescheduleOnIdleFrameClockTest *test = user_data;
+ GMainLoop *main_loop = test->base.main_loop;
+
+ g_assert_cmpint (frame_count, ==, expected_frame_count);
+
+ expected_frame_count++;
+
+ if (test_frame_count == 0)
+ {
+ g_main_loop_quit (main_loop);
+ return CLUTTER_FRAME_RESULT_IDLE;
+ }
+
+ test_frame_count--;
+
+ clutter_frame_clock_schedule_update (frame_clock);
+
+ return CLUTTER_FRAME_RESULT_IDLE;
+}
+
+static const ClutterFrameListenerIface reschedule_on_idle_listener_iface = {
+ .frame = reschedule_on_idle_clock_frame,
+};
+
+static void
+frame_clock_reschedule_on_idle (void)
+{
+ RescheduleOnIdleFrameClockTest test;
+ ClutterFrameClock *frame_clock;
+ FakeHwClock *fake_hw_clock;
+ GSource *source;
+
+ test_frame_count = 10;
+ expected_frame_count = 0;
+
+ test.base.main_loop = g_main_loop_new (NULL, FALSE);
+ frame_clock = clutter_frame_clock_new (refresh_rate,
+ &reschedule_on_idle_listener_iface,
+ &test);
+ fake_hw_clock = fake_hw_clock_new (frame_clock, NULL, NULL);
+ source = &fake_hw_clock->source;
+ g_source_attach (source, NULL);
+ test.base.fake_hw_clock = fake_hw_clock;
+
+ clutter_frame_clock_schedule_update (frame_clock);
+ g_main_loop_run (test.base.main_loop);
+
+ g_main_loop_unref (test.base.main_loop);
+ g_object_unref (frame_clock);
+}
+
CLUTTER_TEST_SUITE (
CLUTTER_TEST_UNIT ("/frame-clock/schedule-update", frame_clock_schedule_update)
CLUTTER_TEST_UNIT ("/frame-clock/immediate-present", frame_clock_immediate_present)
@@ -636,4 +698,5 @@ CLUTTER_TEST_SUITE (
CLUTTER_TEST_UNIT ("/frame-clock/schedule-update-now", frame_clock_schedule_update_now)
CLUTTER_TEST_UNIT ("/frame-clock/before-frame", frame_clock_before_frame)
CLUTTER_TEST_UNIT ("/frame-clock/inhibit", frame_clock_inhibit)
+ CLUTTER_TEST_UNIT ("/frame-clock/reschedule-on-idle", frame_clock_reschedule_on_idle)
)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]