clutter/frame-clock: Apply error diffusion (dithering) to dispatch times
But only the dispatch times used when `last_presentation_time_us == 0` (Nvidia + Xorg). This ensures the average dispatch interval is always precisely equal to the refresh interval, regardless of any jitter in the mainloop. Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1751, https://gitlab.gnome.org/GNOME/mutter/-/issues/1758, https://gitlab.gnome.org/GNOME/mutter/-/issues/1870 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1826>
This commit is contained in:
parent
ba1490ec9c
commit
0555a5bbc1
1 changed files with 14 additions and 1 deletions
|
@ -86,6 +86,7 @@ struct _ClutterFrameClock
|
||||||
|
|
||||||
ClutterFrameClockState state;
|
ClutterFrameClockState state;
|
||||||
int64_t last_dispatch_time_us;
|
int64_t last_dispatch_time_us;
|
||||||
|
int64_t last_dispatch_lateness_us;
|
||||||
int64_t last_presentation_time_us;
|
int64_t last_presentation_time_us;
|
||||||
|
|
||||||
gboolean is_next_presentation_time_valid;
|
gboolean is_next_presentation_time_valid;
|
||||||
|
@ -378,7 +379,8 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||||
{
|
{
|
||||||
*out_next_update_time_us =
|
*out_next_update_time_us =
|
||||||
frame_clock->last_dispatch_time_us ?
|
frame_clock->last_dispatch_time_us ?
|
||||||
frame_clock->last_dispatch_time_us + refresh_interval_us :
|
((frame_clock->last_dispatch_time_us -
|
||||||
|
frame_clock->last_dispatch_lateness_us) + refresh_interval_us) :
|
||||||
now_us;
|
now_us;
|
||||||
|
|
||||||
*out_next_presentation_time_us = 0;
|
*out_next_presentation_time_us = 0;
|
||||||
|
@ -613,9 +615,20 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
|
||||||
{
|
{
|
||||||
int64_t frame_count;
|
int64_t frame_count;
|
||||||
ClutterFrameResult result;
|
ClutterFrameResult result;
|
||||||
|
int64_t ideal_dispatch_time_us, lateness_us;
|
||||||
|
|
||||||
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockDispatch, "Frame Clock (dispatch)");
|
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockDispatch, "Frame Clock (dispatch)");
|
||||||
|
|
||||||
|
ideal_dispatch_time_us = (frame_clock->last_dispatch_time_us -
|
||||||
|
frame_clock->last_dispatch_lateness_us) +
|
||||||
|
frame_clock->refresh_interval_us;
|
||||||
|
|
||||||
|
lateness_us = time_us - ideal_dispatch_time_us;
|
||||||
|
if (lateness_us < 0 || lateness_us >= frame_clock->refresh_interval_us)
|
||||||
|
frame_clock->last_dispatch_lateness_us = 0;
|
||||||
|
else
|
||||||
|
frame_clock->last_dispatch_lateness_us = lateness_us;
|
||||||
|
|
||||||
frame_clock->last_dispatch_time_us = time_us;
|
frame_clock->last_dispatch_time_us = time_us;
|
||||||
g_source_set_ready_time (frame_clock->source, -1);
|
g_source_set_ready_time (frame_clock->source, -1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue