[Xcb] Mixing VSync with XSync

Jonathan Purol coding at folling.de
Thu Jul 8 09:12:07 UTC 2021

 > Indeed. The main trick is to always wait for the previous buffer swap 
to complete (using GLX_INTEL_swap_event or
 > GLX_OML_sync_control) before drawing the next frame. Then the normal 
_NET_WM_SYNC protocol should work.

As far as I can tell I am doing that. the current loop looks something 
like this:

(non-highlighted version at the bottom for longevity purposes)

Although I might have understood wrong what you actually mean. From my 
PoV glXSwapBuffers should already "wait" until the frame is drawn, 
especially when we block afterwards using something like glClear(0) or 
There's obviously a lot more code around that, but that's the basis of it.

The  _synced_resize is, as I mentioned, set in another thread which just 
polls XNextEvent.

What I understand to be the problem is that during resizes we would need 
to render at > framerate, as resize events can be submitted at that 
speed, or could be submitted between vblanks asking for additional 
frames that the compositor needs to make things look smooth. But using 
VSYNC we are capped to *exactly* the framerate of the monitor that we're 
on, so we cannot submit frames any faster than that, especially since 
OpenGL must be run singlethreaded, i.e. we have no way to submit frames 
with VSYNC without blocking with glXSwapBuffers().

My current "fix", is to simply deactivate VSync before the buffer swap 
if it's a synced resize and reactivate it afterwards.
This achieves quite satisfying results, although I believe it is the 
entirely wrong path to take. At least that way we can submit more frames 
than VSYNC dictates whilst keeping VSYNC on for the remainder of the 
program's operation.

plain code version:
while(!_closed) {
     // acquire at start to avoid submitting a frame rendered for a 
smaller size as the response to the synced resize
     bool synced_resize = _synced_resize;


     // glXSwapBuffers doesn't block itself, only the next 
window-altering GL call does, if we want to force a block we can put a 
glClear(0) here

     if (synced_resize) {
         // respond to sync using counter here

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/xcb/attachments/20210708/9b13d1c1/attachment.htm>

More information about the Xcb mailing list