[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:
https://privatebin.net/?7c57104ced0a8790#9Usgz9FTsXvTeoJmYQ5tVyMPs6sQKynb8LtXf39NnhsH
<https://privatebin.net/?7c57104ced0a8790#9Usgz9FTsXvTeoJmYQ5tVyMPs6sQKynb8LtXf39NnhsH>
(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
glXWait*
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;
render();
glXSwapBuffers();
// 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