I have an application written in C using GTK (although the language is probably unimportant for this question).
This application has a fullscreengtk_window
with a single gtk_drawing_area
. For the drawing area, I have registered a tick callback via gtk_widget_add_tick_callback
which just calls gtk_widget_queue_draw
every tick. Inside the drawing area draw
callback, I change the color of the entire window at regular intervals (e.g., from black to white at 1Hz).
Say that in this call to the draw callback I want to change the window from black to white. I would like to know the precise time (down to the nearest ms) that the change is actually drawn on the screen (ideally in the same units as CLOCK_MONOTONIC
). I don't think this is the same thing as the GdkFrameClock
available in the tick callback, which, as I understand it, is about the time of the frame, not the time when the frame is actually displayed on the screen.
If I just measure the CLOCK_MONOTONIC
time in the drawing callback, and then use a photo-diode to measure when the actual change is via an attached A2D, the actual change is the display is understandably delayed by a number of refresh intervals (in my case, 3 screen refreshes).
Just as a summary: if I am in a GTK widget draw callback, is there any way to know the time when the display will actually be shown on the monitor in the units of CLOCK_MONOTONIC
? Or alternatively, is there a way that I can block a separate thread until a specific redraw that I care about is actually displayed on the screen (a function I can write like wait_for_screen_flip()
)?
Update: Ideally, the same solution would work for any Linux compositor (X11 or Wayland), which is why I am hoping for a GTK/GDK solution, where the compositor is abstracted away.
I just came across https://developer.gnome.org/gdk3/stable/gdk3-GdkFrameTimings.html#gdk-frame-timings-get-presentation-time which seems to do just like what you want and is part of Gdk. I do not know how to use it nor have I seen some example of it, but https://developer.gnome.org/gdk3/stable/gdk3-GdkFrameTimings.html#gdk3-GdkFrameTimings.description says
The information in GdkFrameTimings is useful for precise synchronization of video with the event or audio streams, and for measuring quality metrics for the application’s display, such as latency and jitter.
Similarly to Uli's answer of the Present extension and PresentCompleteNotify for X11, Wayland has a similar protocol called wp_presentation_feedback
:
https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/presentation-time/presentation-time.xml
This protocol allows the Wayland compositor to inform clients when their content was actually displayed (turned to light). It is independent of the actual buffer mechanism used (EGL/SHM/etc). To use it, you call wp_presentation_get_feedback
before wl_surface_commit
; when the commit has completed, a presented
event will be sent to the client from the new wp_presentation_feedback
object, or discarded
if it was never shown.
Presentation feedback is currently implemented in Weston; it is not yet implemented in Mutter, and I don't believe it's implemented in KWin either. GTK+ plans to support it when it becomes available in Mutter, but I don't have any great insight as to how it would be exposed through the GTK+ API.
That being said, if you can get access to the Wayland display, it's possible that you could use the interface directly yourself.
Take a look at https://cgit.freedesktop.org/xorg/proto/presentproto/tree/presentproto.txt. Specifically, you want PresentCompleteNotify
events. Note that these can only tell you later when presentation actually happened, so (I think) you will not know ahead of time when this is (but you could perhaps guess based on recent notifies?).
Note that this is
- a relatively new X11 extension, so might not actually be supported everywhere
- depends on the driver used (and likely lots of other factors) for the quality of data
- cannot be used from GTK since it requires a different way to display to the screen (you draw to a Pixmap and then use PresentPixmap to make it visible and ask for a notify)
Also note that this extension provides lots of other things. You can for example say "please display at time ". Just read the protocol specification from start to end. :-)