From 8f27ebf87eee6057992a90560d4118ab7bdf138d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 10 Aug 2023 16:37:16 +0200 Subject: [PATCH] clutter/frame-clock: Start next update ASAP after idle period MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For frame updates in response to sporadic user interaction, this results in input → output latency somewhere between the minimum possible and the minimum plus the length of one display refresh cycle (assuming the frame update can complete within a refresh cycle). Applying a max_render_time based deadline which corresponds to higher than the minimum possible latency would result in higher effective minimum latency for sporadic user interaction. This was discovered by Ivan Molodetskikh, based on measurements described in https://mastodon.online/@YaLTeR/110848066454900941 . v2: * Set min_render_time_allowed_us = 0 as well, to avoid unthrottled frame events. (Robert Mader) Part-of: --- clutter/clutter/clutter-frame-clock.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c index 207a607a7..ab493e0b0 100644 --- a/clutter/clutter/clutter-frame-clock.c +++ b/clutter/clutter/clutter-frame-clock.c @@ -566,12 +566,25 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock, } } - while (next_presentation_time_us < now_us + min_render_time_allowed_us) - next_presentation_time_us += refresh_interval_us; + if (next_presentation_time_us != last_presentation_time_us + refresh_interval_us) + { + /* There was an idle period since the last presentation, so there seems + * be no constantly updating actor. In this case it's best to start + * working on the next update ASAP, this results in lowest average latency + * for sporadic user input. + */ + next_update_time_us = now_us; + min_render_time_allowed_us = 0; + } + else + { + while (next_presentation_time_us < now_us + min_render_time_allowed_us) + next_presentation_time_us += refresh_interval_us; - next_update_time_us = next_presentation_time_us - max_render_time_allowed_us; - if (next_update_time_us < now_us) - next_update_time_us = now_us; + next_update_time_us = next_presentation_time_us - max_render_time_allowed_us; + if (next_update_time_us < now_us) + next_update_time_us = now_us; + } *out_next_update_time_us = next_update_time_us; *out_next_presentation_time_us = next_presentation_time_us;