Draft: Wayland Compositor: Reduce latency by sending frame callbacks before painting
Frame Callbacks
wl_surface:request:frame
provides a callback to the compositor, that is intended to be used to signal the wayland client "when it is a good time to draw and commit the next frame of animation".
KWin currently emits wl_surface::frame
callbacks after completing frame rendering/painting. Frame rendering is done in WaylandCompositor::composite
, which is scheduled by RenderLoopPrivate::compositeTimer
, so that it finishes just before the next estimated presentation time.
With frame callbacks being emitted shortly after rendering, clients immediately start commiting new frames right after presetation. These early commits will be presented at least a full refresh cycle later, resulting in unneccesarily high latency.
Approach
This MR attempts to reduce latency by splitting the framePass in WaylandCompositor::composite
into two separate passes:
-
frameCallbackPass
: emits frameCallbacks to "request" clients to commit frames just before painting/rendering -
frameFeedbackPass
: emits presentationFeedback after rendering
Next Steps
Marking this as draft to get some early feedback on the idea. I havent done much c++ yet, so I might have missed something.
Some possible improvements / concerns:
- Painting immediately after emitting frame callbacks might be problematic, as the client will take some time to act on the callback.
- Perhaps rendering (GlFinish, acquiring buffers etc.) should be moved completely out of
WaylandCompositor::composite
as is the case with explicit sync (?), so thatWaylandCompositor::composite
really only deals with compositing. In that case we could:- trigger commits by using a timer
renderTimer
to schedule frameCallbacks atnextPresentationTime - renderDuration - compositeDuration
- (or multiple timers and render duration estimations for per-window latency optimization)
- asynchronously acquire buffers ASAP on commit
- use a second timer
compositeTimer
to schedule compositing atnextPresentationTime - compositeDuration
while only using readily acquired buffers
- trigger commits by using a timer