Can eglSwapBuffers be parallellized?

Hi All,

I learned from Chris Pruett/ Replica Island that it should be possible to parallelize the eglSwapBuffers call. So if eglSwapBuffers is running in one thread other threads can run while eglSwapBuffers is completing. Reason for this should be that eglSwapBuffers is running on the GPU - not CPU.

I thus coded a game using two threads - a Render thread and a Physics thread. However I experienced none or very little performance gain. Very little if the thread priorities where calibrated. The eglSwapBuffers call takes 10-20 ms so if it was possible for other threads to run parallel with it it should result in 20% more frames.

Anyone has an opinion on 2-threaded GL games like this or even experience on Android or other platforms?

Thanks,

Martin

Well, my opinion on this is that the actual call to eglSwapBuffers should internally be asyncrhonous; that is, it should return immediately, which it does on some modern desktop drivers. Trying to work around it yourself on Android might not really be worth the effort.

Cas :slight_smile:

Hehe, tell me about it… Definitely not worth the effort so far.

I agree that it would be nice if it was asynchronous - that would fit better into my idea about how things should work.

A little follow-up: After testing in depth we actually found that on Droid and Nexus One eglSwapbuffers returns before all the work is done. So it allows for paralellism in the way we hoped. The G1 however appears to block on the eglSwapbuffers call until all work is done. If running multithreaded however it is still possible to gain a performance increase of up to 20% on the G1 by parallelizing work.

Nice findings. Good thing the G1 is quite a rare phone.

Cas :slight_smile:

Don’t know if the 'roid has it, but in normal OpenGL, there is glFlush, which forces a flush on the OGL pipeline. If it is not used, (on some cards) it is possible to be 2.5 frames in advance to what is seen on the screen. You could emulate the G1 behavior with adding glFlush after SwapBuffers.

They have glFlush - it is part of OpenGL 1.0 I believe. Read a bit about it. My impression so far was that it could be done before glSwapBuffers and also that glSwapBuffers can be expected to do a glFlush as the first thing it does. Will flush the pipeline but NOT wait for swap to complete. Was my impression. Curiously on G1 glFlush seems to return immidiatly and not wait for work to be done.

glFlush() has no place outside of an actual distributed client/server graphics system (eg. remote X). Its presence is really a bit of an anachronism - not even sure why it’s in OpenGL-ES at all, as any gl* methods that actually require a flush (eg. picking, reads) perform an implicit flush anyway.

Cas :slight_smile:

glFlush can be useful in ES when interacting with other APIs (OpenCL/VG/MAX etc). It doesn’t help with SwapBuffers parallelism though, the driver has to be multi-thread aware to see any gains (which I don’t think will be very common on current ES implementations).

I think that glFlush is useful when you only want to update the screen in specific situations only, eg when the program keeps track of the changes to the scene, and only updates the display when necessary. I think that such a scenario is valid for Android, since the display complexity is probably simple, and updating the screen only when necessary would save processor and thus battery power. But i’m not into Android coding (yet), so i don’t know how important that is.

That’d be valid in a single-buffered context but… nobody uses single buffering :slight_smile:

Cas :slight_smile:

Not so. It has nothing to do with double or single buffering. Its just that the display is not updated in the render loop at 30 or whatever frames per second, but only when something changes on the screen. glFlush works perfectly with double-buffered display.

I still don’t follow :confused: I can’t see any need whatsoever for glFlush in a double-buffered display… any command requiring that the buffers are flushed, flushes it. That includes swapBuffers of course, too… so I must be being dim. What am I missing?

Cas :slight_smile:

SwapBuffers does no flush the command queue. I assume that no other commands are used which would flush it. That’s why it is possible for display to lags behind in addition to double-buffering. When updating the screen in ad-hoc manner (not regularily), then it is unwanted that OGL buffers multiple frames, since we want the new display to be seen as soon as possible, since the screen update was probably initiated as a reaction to user input. In a normal render loop glFlush is bad, and causes lower frame-rate.

EDIT: Actually i’m somewhere mistaking in this, since swapbuffers does do the actual rendering, but my tests showed that glFlush did reduce framerate.