glXSwapBuffers very slow, potential problems?

Aaron Plattner aplattner at nvidia.com
Tue Oct 5 09:48:05 PDT 2010


On Tue, Oct 05, 2010 at 08:05:47AM -0700, Roland Plüss wrote:
> I'm running here into a heavy performance problem on both ATI and nVidia cards and the culprit is the glXSwapBuffers call. I've got here two performance readings showing the problem.
> 
> The first reading is in a case where performance is somewhat okay.
> 
> II [OpenGL] OpenGL Timer: BeginFrame: Run Optimizers = 3ys
> II [OpenGL] OpenGL Timer: BeginFrame: Make Current = 57ys
> II [OpenGL] OpenGL Timer: BeginFrame: Activate primary GC = 7ys
> II [OpenGL] OpenGL Timer: EndFrame: Entering = 2312ys
> II [OpenGL] OpenGL Timer: EndFrame: Activate primary GC = 28ys
> II [OpenGL] OpenGL Timer: EndFrame: Flush = 27ys
> II [OpenGL] OpenGL Timer: EndFrame: Swap Buffers = 4238ys
> II [OpenGL] OpenGL Timer-Total End Frame = 6694ys
> 
> "EndFrame: Entering" is the time for all rendering for the window (hence the time between leaving BeginFrame and entering EndFrame calls). The flush there is only to make sure it is a problem with glXSwapBuffers. 4ms for a swap I would consider a bit high if the rendering itself is done in <3ms but maybe this is normal, I don't know. But when I show/hide the window to switch to another window rendering the same 3D scene (for testing purpose) and switching back (always only one of the two windows visible, aka mapped to the screen) performance breaks down horribly.

Rendering on the GPU is queued by the rendering commands, and is processed
asynchronously.  This means that you can't assume that just because all of
your rendering commands have returned, that the rendering is actually
complete.  Also, glXSwapBuffers will queue a swap to occur when the
rendering is complete, but most GL implementations have code to prevent the
CPU from getting too far ahead.  In particular, at least on our driver, if
there's a previous swap still pending, glXSwapBuffers won't return until
that swap is complete.  This means that if your rendering is slow on the
GPU for some reason (e.g. because you have a pixel shader that takes ages
to complete), you'll see that time show up in the SwapBuffers call for the
next frame.

glFlush doesn't wait for the rendering to complete either, it just ensures
that any queued rendering is actually sent to the card.  glXSwapBuffers is
specified as doing an implicit glFlush, so calling it yourself is
redundant.  If you want to see how long your rendering is actually taking
on the GPU, try using the GL_ARB_timer_query extension.

> II [OpenGL] OpenGL Timer: BeginFrame: Run Optimizers = 4ys
> II [OpenGL] OpenGL Timer: BeginFrame: Make Current = 59ys
> II [OpenGL] OpenGL Timer: BeginFrame: Activate primary GC = 14ys
> II [OpenGL] OpenGL Timer: EndFrame: Entering = 2560ys
> II [OpenGL] OpenGL Timer: EndFrame: Activate primary GC = 37ys
> II [OpenGL] OpenGL Timer: EndFrame: Flush = 45ys
> II [OpenGL] OpenGL Timer: EndFrame: Swap Buffers = 66642ys
> II [OpenGL] OpenGL Timer-Total End Frame = 69401ys
> 
> As it is visible here swap buffers eats suddenly 66ms!
> 
> This is on the ATI system. On the nVidia system there is no difference between the two situations but swap buffer always consumes 48ms. Any ideas what can cause glXSwapBuffer to horribly slow down like this? The DE is KDE4 with compositing present but disabled (so it should not have any influence).
> 
> I read somewhere that somebody tried placing glXSwapBuffers in a separate thread. Would this not cause troubles with the X-server? (meaning, is X thread safe?). But even if this would work 68ms for a swap is brutal.

SwapBuffers from a separate thread should work fine, but you may have
trouble making sure everything is synchronized correctly.  Also, it's
almost certainly barking up the wrong tree.



More information about the xorg mailing list