Fix randomly high latency with the Nvidia Xorg driver
The documentation for clutter_stage_skip_sync_delay
where it said
"drawn as quickly as possible" had led to a literal interpretation
that was ignoring the display's refresh rate and overfilling the
SwapBuffers
queue. This overfilling led to visible lag between the
hardware cursor and the screen contents as
clutter_stage_cogl_schedule_update
would repeatedly schedule new
frames faster than the refresh rate here:
if (sync_delay < 0)
{
stage_cogl->update_time = now;
return;
}
But nobody noticed this earlier because:
-
The offending code path is only used on Xorg.
-
It's only a problem on Xorg drivers (Nvidia since 3.34, !602 (merged)) that don't implement
last_presentation_time
so don't get a value above zero forpending_swaps
to forcefully throttle updates to the refresh rate:clutter_stage_cogl_get_update_time (ClutterStageWindow *stage_window) { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); if (stage_cogl->pending_swaps) return -1; /* in the future, indefinite */
Which is also documented in the original design:
If a redraw is scheduled for time T, and we’re still waiting for the previous swap to complete at time T, redraw immediately when the swap completes.
https://blog.fishsoup.net/2012/11/28/avoiding-jitter-in-composited-frame-display/
Now we correct both the implementation and the documentation to only skip the sync delay and not skip throttling to the refresh rate. As intended by the original design. And now we don't get runaway lag from repeated overscheduling when using the Nvidia Xorg driver.