Skip to content

Implement presentation-time Wayland protocol

Ivan Molodetskikh requested to merge YaLTeR/mutter:presentation-time into master

This MR implements the presentation-time protocol which provides clients with presentation timestamps for their surface commits, as well as some flags and an estimated refresh rate.

Some new information (hw_clock, zero_copy, sequence) is added to CoglFrameInfo and ClutterFrameInfo to pass it from DRM to presentation-time. The presentation timestamp in CoglFrameInfo is changed from nanoseconds to microseconds since both KMS and GLX report device timestamps in microseconds, and to match ClutterFrameInfo. The presentation timestamp in both CoglFrameInfo and ClutterFrameInfo is also changed to always be CLOCK_MONOTONIC; when the device reports non-monotonic timestamps (which is apparently exceedingly rare according to #gnome-shell conversations) the current monotonic time is sampled instead.

A few questions making this a WIP MR:

  • page_flip_feedback_discarded() in meta-renderer-native.c fakes the presented event "to avoid freezing the frame clock". How to signal discarded feedback for this case? Add a flag to C{ogl,lutter}FrameInfo saying "fake, wasn't actually presented"?
    • Handled by introducing a SYNTHETIC flag.
  • In on_presented() in meta-wayland.c I find the MetaWaylandOutput corresponding to the ClutterStageView via rectangle intersection, then bump MetaWaylandOutput's last_sequence according to the delta. However, if it's possible that there are multiple ClutterStageViews on a single MetaWaylandOutput, last_sequence will get bumped multiple times, which is incorrect. How to handle this?
    • Handled by only bumping when the "main" stage view for the output is presented.
  • How to adapt this to cursor surfaces? I guess, attach a presented handler to MetaCursorRenderer and do a similar thing to what was done in MetaWaylandCompositor?
    • Postponed until !1488 (merged) lands since it simplifies things in this regard.
  • The presentation feedbacks are fired rather haphazardly when the surface is on multiple outputs at once; !1468 (merged) will fix this (the same condition should be applied to presentation feedbacks).
  • I was unable to verify the ZERO_COPY flag being set correctly because I was unable to get any Wayland clients to unredirect. However, when running weston-presentation-shm and full-screening glxgears (which does get unredirected), weston-presentation-shm gets a single "presented" feedback with the ZERO_COPY flag set. I'm not sure how to prevent this.

I've tested this using weston-presentation-shm and my own test client. For weston-presentation-shm, you're looking for:

  • f2p equal to about 2 frames minus 2 ms, that is, (1000 / 60) * 2 - 2 = 31 ms on 60 Hz monitors;
  • p2p equal to about 1 frame, that is, 1000000 / 60 = 16667 us on 60 Hz monitors;
  • the c flag set when testing on the host (for hardware timestamps);
  • the z flag set when unredirection is active (not actually possible since this client can't fullscreen properly).

On the following image I'm running two weston-presentation-shms side-by-side in-between two monitors, the left one set to 144 Hz (top terminal) and the right one set to 60 Hz (the bottom terminal).

image_2020-10-08_17-20-06

On the following photo I'm running two test clients on the same monitor setup; the clients are using presentation-time to draw exactly for predicted presentation timestamps (so they predict when the frame will be shown and draw the scene according to that timestamp). The rectangles are all moving down at a constant speed, so on this high exposure photo all individual renderings of the rectangles must be exactly the same distance apart (since the monitors are operating at a constant refresh rate):

IMG_20201008_171737

Additionally, the test client can output some presentation-time debug info:

  • refresh from presentation-time, which should be equal to 1000 / 144 = 6.944 ms for my 144 Hz monitor;
  • presentation_latency, the difference between the client's predicted target timestamp for a buffer and the actual timestamp when that buffer was presented, which should be as close to zero as possible.

image

I've made a COPR with this MR rebased to Mutter 3.38.1 for F33 testing, should anyone find that useful: https://copr.fedorainfracloud.org/coprs/yalter/mutter-presentation-time/ (sudo dnf reinstall --repo=copr:copr.fedorainfracloud.org:yalter:mutter-presentation-time mutter)

Resolves #1140 (closed).

Edited by Ivan Molodetskikh

Merge request reports