Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserving back buffer content after eglSwapBuffers

I'm implementing in Android and native C++ a scene drawing for android using egl 1.1. Currently using android's glSurfaceView - which allows me to draw to a back buffer which is displayed at the end of "onDrawFrame" - when the back buffer and the front buffer are swapped.

My problem is this - I need to be able to display the back buffer and continue writing as if I havn't swapped. The reason behind this demand is that the scene is very large, and building it each frame is not possible, neither is waiting for the end of the drawing - since the user will have to wait for too long.

In other words - I need to build the scene incrementally. At a certain point during the rendering, I decide it's time and I call eglSwapBuffers which displays the drawn content from the back buffer, but when I continue writing obviously I'm writing to the 'former-front-buffer' which is out of sync.. (not containing the things I've drawn so far).

As far as I see my only option is to copy the back buffer before swapping. pseudo :

  1. Draw to back buffer
  2. Copy Back Buffer to temp Buffer
  3. Swap
  4. Copy temp buffer to (the new) back buffer
  5. Draw more things to back buffer
  6. And so on...

My question - Is there a way to do steps 2,4?

  • Is glCopyPixels useful in this case? example?
  • Is glBlitFramebuffer?

Or am I approaching this all wrong?

Things I already did :

  • I tried setting EGL_SWAP_BEHAVIOR to EGL_BUFFER_PRESERVED but it only seems to work on certain devices (as described in the khronos notes) :

Some surfaces allow applications to control whether or not the color buffer contents are preserved

  • Re-rendering the scene in each frame - not possible. I've read many times that this is recommended.
like image 259
Dror Fichman Avatar asked May 29 '14 08:05

Dror Fichman


1 Answers

Your general approach is correct. Using glBlitFramebuffer() is likely to be more helpful, as glCopyPixels just copies some sub-rectangle of the buffer to anouth position in the same buffer.

However, I can think of a potentially better approach, at least if OES_framebuffer_object is available:

  1. draw to texture or a user-defined renderbuffer
  2. render texture to BACK buffer/blit renderbuffer to BACK buffer
  3. swap
  4. update texture/renderbuffer
  5. render texture to BACK buffer/blit renderbuffer to BACK buffer
  6. swap
  7. [... and so on ...]

That way you don't have a copy/update/copy/swap cycle with 2 copies per frame, but only update/copy/swap with a single extra copy.

like image 104
derhass Avatar answered Oct 30 '22 12:10

derhass