0% found this document useful (0 votes)
20 views3 pages

Opengl - glXSwapBuffers Blocks Until Vblank - Stack Overflow

The document discusses how glXSwapBuffers() blocks until the vertical blank period, causing lag. It suggests using a swap interval extension to set the interval to 0 to make glXSwapBuffers() asynchronous and return immediately without waiting. It also notes issues with synchronization between OpenGL commands and buffer swaps.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views3 pages

Opengl - glXSwapBuffers Blocks Until Vblank - Stack Overflow

The document discusses how glXSwapBuffers() blocks until the vertical blank period, causing lag. It suggests using a swap interval extension to set the interval to 0 to make glXSwapBuffers() asynchronous and return immediately without waiting. It also notes issues with synchronization between OpenGL commands and buffer swaps.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

4/7/24, 4:16 PM opengl - glXSwapBuffers() blocks until vblank - Stack Overflow

glXSwapBuffers() blocks until vblank


Asked 9 years, 6 months ago Modified 2 years, 5 months ago Viewed 4k times

While trying to make a compositing window manager for X11 using OpenGL as backend, I'm caught in a
nasty situation where glXSwapBuffers() blocks until vblank rendering the compositor irresponsive to X
7 events which causes windows being dragged around to lag behind the cursor by roughly one frame. I've
tried multithreading but it didn't work well, so I decide the only proper solution is to make
glXSwapBuffers() asynchronous. It would be desirable to send drawing commands to GPU and return
immediately without waiting for the operations to actually finish, and AFAIK this is possible under modern
Linux with DRI2. So what should I do?

opengl x11 vsync

Share Improve this question Follow asked Oct 2, 2014 at 14:12


wildptr
107 1 7

2 Answers Sorted by: Highest score (default)

Actually glXSwapBuffers should return immediately. What's blocking however is the very next OpenGL
command that introduces a so called synchronization point. Usually this is the next glClear that follows
8 the call of glXSwapBuffers .

Note that it's actually desireable to somehow synchronize with the V-Blank, otherwise nasty tearing
artifacts happen. But you're right, that in a naive implementation this introduces about one display
refresh interval of latency.

The big problem here is, that double buffered windows redirected to an off-screen surface may still
subjected to the active swap interval (i.e. V-Sync setting); and of course double buffering itself doesn't
make a lot of sense in a composited setting.

So here's what you can do: Use a swap interval extension to set your compositor's swap interval to 0 (no
V-Sync); depending on your system's settings this choice may actually not be honored (user configured
all applications are forced to V-Sync). Unfortunately there are several swap interval extensions and what
works with one display driver doesn't work with another. I suggest you look at the swap interval example
programs of Mesa and the sources of glxgears of Mesa, which contain code that deals with pretty much
every situation you may encounter.

It's also desireable to somehow turn off V-Sync in the clients too. I don't see better way than injecting a
shared object into them, hooking glXSwapBuffers , glXCreateContext and the swap interval extensions
to override them.

Finally you must use one of the available video synchronization GLX extensions to implement a timed
buffer swap in your compositor (i.e. call an "unsynchronized" glXSwapBuffers at just the right moment
when the V-Blank happens). With a direct OpenGL context and a realtime scheduling policy applied to
the compositor process you can do that.

https://stackoverflow.com/questions/26162745/glxswapbuffers-blocks-until-vblank?rq=3 1/3
4/7/24, 4:16 PM opengl - glXSwapBuffers() blocks until vblank - Stack Overflow

Note that all these issues are shortcomings in the existing X11 protocol. But if you think Wayland would
get rid of these issues, think again. While Wayland was originally intended to make "every frame perfect"
and do away with the synchronization issues, in practice I encountered many of the problems, again. In
this blog post the creator of Wayland talks about roundtrips and overhead, but he completely avoids the
point of pipeline synchronization and buffer swap latency. The problems are inherent to the concept of
stacked composition and buffer swap based V-Sync. To really solve the issue there must be some kind
of screen associated V-Sync event that's independent from graphics operations and can be applied an
arbitrary phase offset, so that applications can synchronize their rendering loops with display refresh.
And there should be an additional "framebuffer commit" function that makes the whole composition
chain consider the newly arrived frame. This would allow the compositor to sync applications to a few
100µs before the V-Blank happens, so that composition can happen in that margin between framebuffer
commit and V-Blank.

Share Improve this answer Follow edited Oct 2, 2014 at 21:20 answered Oct 2, 2014 at 18:11
datenwolf
161k 13 188 303

As @datenwork says, I don't think it's glxSwapBuffers that's blocking. But something is. I solved the
issue inspired by this blog post.
2
Specifically, on my platform (Ubuntu 14 + Nvidia driver + Nvidia OpenGL implementation), the following
code works:

PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
(PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); // Set
the glxSwapInterval to 0, ie. disable vsync! khronos.org/opengl/wiki/Swap_Interval
glXSwapIntervalEXT(x11_display, glx_window, 0); // glXSwapIntervalEXT(0);

where x11_display is built as

Display* x11_display = XOpenDisplay(0);

and glx_window is built as

GLXWindow glx_window = glXCreateWindow(x11_display, fb_config, window, 0);

and fb_config is a suitable GLXFBConfig , that I, specifically, get as follows:

int visual, n_fb_configs;


GLXFBConfig* fb_configs = glXGetFBConfigs(x11_display, screen_number, &n_fb_configs);
GLXFBConfig fb_config = fb_configs[2]; // Select 3rd FB config! Many others work!
glXGetFBConfigAttrib(x11_display, fb_config, GLX_VISUAL_ID, &visual); // Query visual?
printf("screen %x fb_configs %d fb_config %llx visual %x\n", screen_number, n_fb_configs,
(ull)fb_config, visual);

Note that I don't get any screen tearing that wasn't alread there with (the largely useless, imo) vsync
enabled.

Also, depending on your GPU driver and OpenGL implementation (Is it Nvidia's? Is it Mesa's?), there's
other glxSwapInteral*(...) functions that you may have to use. Eg. there's a
glXSwapIntervalMESA(...) and a glXSwapIntervalSGI(...) .

https://stackoverflow.com/questions/26162745/glxswapbuffers-blocks-until-vblank?rq=3 2/3
4/7/24, 4:16 PM opengl - glXSwapBuffers() blocks until vblank - Stack Overflow

Rant: As usual with X11 programming, there's very little documentation to hold your hand... Good luck! :)

Bonus. To quote the OpenGL documentation:

Your application's use of swap interval may be overridden by external, driver-specific


configuration. For example, forcing Vsync Off in a driver's control panel will prevent Vsync, even
if swap interval is set to 1 in your application.

Share Improve this answer Follow edited Oct 20, 2021 at 19:48 answered May 8, 2017 at 19:27
Raph Levien étale-cohomology
5,158 26 24 2,226 2 29 36

https://stackoverflow.com/questions/26162745/glxswapbuffers-blocks-until-vblank?rq=3 3/3

You might also like