3

I am making this game using open gl es 2.0 on android using c/c++ (NDK)

As the most imp thing in game I laid out two schemes for the game loop!

Scheme 1 serial scheme:

enter image description here

step a. Game reads input and updates states and physics

step b. After step a is complete it draws the graphics using the data set in step a

scheme 2 parallel scheme:

enter image description here

step a. A thread (Thread A) keeps reading input and updating game state and physics continuosly

step b. Another thread (Thread B) draws from data generated by thread A using the open GL draw calls (at a maximum of set fps)

Problems Scheme 1:

The problem with scheme 1 is that I dont know what will happen in the case when there are lot of objects in the scene and hence the actual draw operation in the GPU (not the GL api calls) takes longer than desired frame time (say 1/60 seconds).

Since most openGL Api calls return immediately this may lead to the illusion that next frame can be drawn while actually the last frame draw will still be in progress while the loop issues next frame draw calls.

As such the draw calls will stack up and might reach a limit. What happens at that limit? will it block further api calls or just drop the calls or something else?

Scheme 2:

In scheme 2 the problem is similar . while you issue the draw calls you'll have to put the input/update thread to sleep so that the game state does not changes in the middle of a draw. So again when your draw operation is longer than the calculated frame delay how will you implement the frame drop since the draw calls will return immediately?

EDIT: There are lots of "may" "should" and "most" on this official page as such how can one be sure of anything?

It looks like openGL specification has no platform or implementation independent guidelines on how to make use of parallel processing or threading for synchronization at all! How can they miss it ?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Allahjane
  • 1,920
  • 3
  • 24
  • 42
  • Many OpenGL do return immediately, but not all. At least SwapBuffers will wait until all previously scheduled commands are executed, making it nearly impossible to overflow the command buffer. Even if you call more OpenGL commands then can be stored within one frame, you will not notice this in most OpenGL implementations, since they will simply wait until the next command can be added to the command buffer. – BDL Jan 02 '15 at 13:41
  • Some commands may block on certain drivers while they'll not block on other drivers or hardwares – Allahjane Jan 02 '15 at 13:47
  • It is clearly specified in the standard which functions will block in which case. [glFinish](https://www.opengl.org/sdk/docs/man4/) has to block until the command buffer is empty. All commands that retrieve data from the GPU also have to block. Read more in this article about [OpenGL synchronisation](https://www.opengl.org/wiki/Synchronization). In my experience (and also confirmed by comment [here](http://stackoverflow.com/questions/11948702/eglswapbuffers-is-erratic-slow)) eglSwapBuffer is a blocking call in android. – BDL Jan 02 '15 at 14:01
  • 1
    "At least SwapBuffers will wait until all previously scheduled commands are executed" NO! as per that open gl page "Swapping the back and front buffers on the Default Framebuffer **may** cause some form of synchronization" , So there is no gurantee – Allahjane Jan 02 '15 at 14:31
  • In android it does (at least according to my experience and the one of the comment from last post). If you don't believe it, try it out. – BDL Jan 02 '15 at 14:36
  • Android does not define specific standards for that , its rather more dependent on MALI or PowerVR or adreno's implementation, Also I wanted a general process since openGL is not platform specific – Allahjane Jan 02 '15 at 14:39
  • I think you are worried too much. Go ahead with any implementation and you will be fine. Android's double buffering is actually tripple buffering and it does not accept your latest draw buffer until `prev_to_prev` has finished and `prev` has started. PS: this is true for HC-1.3, without HWC. Are/have you experiencing any REAL issue stated in your problems? – Adorn Jan 03 '15 at 20:57

1 Answers1

0

From the view of GPU execution, your two setups are essentially equivalent. As others comments' suggest, the driver may (must) stall the execution of GL commands if the command buffer gets overloaded (eg. you have issued too many state changing operations). This is highly dependent on the driver implementation, and it is difficult to determine upfront when these stalls will occur, because you have no knowledge of the driver's implementation of the command buffer. You must just rely on this being the case, and the implementation details being hidden from you.

If you are highly concerned about CPU/GPU synchronization, you can use the glFenceSync + glClientWaitFence (https://www.khronos.org/opengles/sdk/docs/man3/html/glFenceSync.xhtml) to determine when the GPU has finished processing GPU commands up to the point at which the fence was inserted, and (potentially) wait until those commands have completed. For example, you could stall the CPU if the fence from the Nth previous frame has not completed. Generally, this is not necessary in the case you're describing, it is usually only used in the cases where the CPU and GPU have unsynchronized access to the same resource (eg. with glMapBufferRange + GL_MAP_UNSYNCHRONIZED_BIT).

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78