clutter/frame-clock: Add notify_ready()
In constrast to notify_presented(), notify_ready() also returns the state machine to the idle state, but without providing new frame information, as no frame was actually presented. This will happen for example with the simple KMS impl backend will do a cursor movement, which will trigger a symbolic "page flip" reply in order to emulate atomic KMS behavior. When this happen, we should just try to reschedule again. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
@ -747,6 +747,78 @@ frame_clock_destroy_signal (void)
|
||||
g_object_unref (frame_clock_backup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
notify_ready_and_schedule_update_idle (gpointer user_data)
|
||||
{
|
||||
ClutterFrameClock *frame_clock = user_data;
|
||||
|
||||
clutter_frame_clock_notify_ready (frame_clock);
|
||||
clutter_frame_clock_schedule_update (frame_clock);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static ClutterFrameResult
|
||||
frame_clock_ready_frame (ClutterFrameClock *frame_clock,
|
||||
int64_t frame_count,
|
||||
int64_t time_us,
|
||||
gpointer user_data)
|
||||
{
|
||||
GMainLoop *main_loop = user_data;
|
||||
|
||||
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--;
|
||||
|
||||
g_idle_add (notify_ready_and_schedule_update_idle, frame_clock);
|
||||
|
||||
return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
|
||||
}
|
||||
|
||||
static const ClutterFrameListenerIface frame_clock_ready_listener_iface = {
|
||||
.frame = frame_clock_ready_frame,
|
||||
};
|
||||
|
||||
static void
|
||||
frame_clock_notify_ready (void)
|
||||
{
|
||||
GMainLoop *main_loop;
|
||||
ClutterFrameClock *frame_clock;
|
||||
int64_t before_us;
|
||||
int64_t after_us;
|
||||
|
||||
test_frame_count = 10;
|
||||
expected_frame_count = 0;
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
frame_clock = clutter_frame_clock_new (refresh_rate,
|
||||
&frame_clock_ready_listener_iface,
|
||||
main_loop);
|
||||
|
||||
before_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_frame_clock_schedule_update (frame_clock);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
after_us = g_get_monotonic_time ();
|
||||
|
||||
/* The initial frame will only be delayed by 2 ms, so we are checking one
|
||||
* less.
|
||||
*/
|
||||
g_assert_cmpint (after_us - before_us, >, 8 * refresh_interval_us);
|
||||
|
||||
g_main_loop_unref (main_loop);
|
||||
clutter_frame_clock_destroy (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)
|
||||
@ -757,4 +829,5 @@ CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/frame-clock/inhibit", frame_clock_inhibit)
|
||||
CLUTTER_TEST_UNIT ("/frame-clock/reschedule-on-idle", frame_clock_reschedule_on_idle)
|
||||
CLUTTER_TEST_UNIT ("/frame-clock/destroy-signal", frame_clock_destroy_signal)
|
||||
CLUTTER_TEST_UNIT ("/frame-clock/notify-ready", frame_clock_notify_ready)
|
||||
)
|
||||
|
Reference in New Issue
Block a user