clutter/frame-clock: Start next update ASAP after idle period

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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3174>
This commit is contained in:
Michel Dänzer 2023-08-10 16:37:16 +02:00 committed by Robert Mader
parent effc985401
commit 8f27ebf87e

View File

@ -566,12 +566,25 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
} }
} }
while (next_presentation_time_us < now_us + min_render_time_allowed_us) if (next_presentation_time_us != last_presentation_time_us + refresh_interval_us)
next_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; next_update_time_us = next_presentation_time_us - max_render_time_allowed_us;
if (next_update_time_us < now_us) if (next_update_time_us < now_us)
next_update_time_us = now_us; next_update_time_us = now_us;
}
*out_next_update_time_us = next_update_time_us; *out_next_update_time_us = next_update_time_us;
*out_next_presentation_time_us = next_presentation_time_us; *out_next_presentation_time_us = next_presentation_time_us;