If the GPU is moderately loaded, the GPU render time can be higher than the CPU render time. Currently, our frame scheduling algorithm doesn't account for that. This means that there may be frame drops when playing video games.
With this change, opengl timer query objects will be inserted before and after finishing a compositing cycle. On a page flip, the final render time will be computed based on the timer queries and the cpu render time.
fixes #47 (closed)
What to do about direct scanout? Due to implicit synchronization, the next frame will be presented only after all the rendering commands to the client buffer complete. It might be also worth sending out frame callbacks at the page flip, but we need to handle somehow the case where a window is moved between two screens correctly, e.g. a window is rendered on screen A, a window has been moved to screen B, a page flip on the screen A occurs, but since there are no windows, the frame callback won't be sent.
With multi-gpu, the frame scheduling algorithm needs to know how long it took to transfer a buffer between gpus. I highly doubt that the transfer time is 0.
10:21:12 AM <MrCooper> zzag: see also https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762
10:26:34 AM <zzag> MrCooper: can you please explain how !1762 works? I don't think that I follow. It seems like a texture is created before flipping buffers. Why does that produce the desired results? and how does that actually work? it looks like black magic to be honest :D
10:30:22 AM <MrCooper> it binds the client buffer as the EGL draw buffer, then emits a timestamp query, which records the time when the GPU finishes drawing to the buffer
10:34:33 AM <zzag> MrCooper: thanks. that's pretty clever