From 7e27fb6d56e45ccdd91017fc58d9febf39f58d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 21 Mar 2020 23:23:23 +0100 Subject: [PATCH] clutter/frame-clock: Add API to schedule next frame immediately Aimed to replace the 'skip-sync-delay' mechanism currently used by XSyncAlarmNotify to schedule an more immediate redraw. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285 --- clutter/clutter/clutter-frame-clock.c | 45 ++++++++++++++++++++++++--- clutter/clutter/clutter-frame-clock.h | 3 ++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c index 3248b4dcc..1f3d10926 100644 --- a/clutter/clutter/clutter-frame-clock.c +++ b/clutter/clutter/clutter-frame-clock.c @@ -76,6 +76,7 @@ struct _ClutterFrameClock int64_t next_presentation_time_us; gboolean pending_reschedule; + gboolean pending_reschedule_now; }; G_DEFINE_TYPE (ClutterFrameClock, clutter_frame_clock, @@ -108,14 +109,21 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, break; case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: + frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; + if (frame_clock->pending_reschedule) { frame_clock->pending_reschedule = FALSE; - clutter_frame_clock_schedule_update (frame_clock); - } - else - { - frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; + + if (frame_clock->pending_reschedule_now) + { + frame_clock->pending_reschedule_now = FALSE; + clutter_frame_clock_schedule_update_now (frame_clock); + } + else + { + clutter_frame_clock_schedule_update (frame_clock); + } } break; } @@ -185,6 +193,33 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock, *out_next_presentation_time_us = next_presentation_time_us; } +void +clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) +{ + int64_t next_update_time_us = -1; + + switch (frame_clock->state) + { + case CLUTTER_FRAME_CLOCK_STATE_INIT: + case CLUTTER_FRAME_CLOCK_STATE_IDLE: + next_update_time_us = g_get_monotonic_time (); + break; + case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: + return; + case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: + case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: + frame_clock->pending_reschedule = TRUE; + frame_clock->pending_reschedule_now = TRUE; + return; + } + + g_warn_if_fail (next_update_time_us != -1); + + g_source_set_ready_time (frame_clock->source, next_update_time_us); + frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; + frame_clock->is_next_presentation_time_valid = FALSE; +} + void clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) { diff --git a/clutter/clutter/clutter-frame-clock.h b/clutter/clutter/clutter-frame-clock.h index a7fee3dca..42bb212fe 100644 --- a/clutter/clutter/clutter-frame-clock.h +++ b/clutter/clutter/clutter-frame-clock.h @@ -55,4 +55,7 @@ void clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, CLUTTER_EXPORT void clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock); +CLUTTER_EXPORT +void clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock); + #endif /* CLUTTER_FRAME_CLOCK_H */