OpenGL ES 2.0 - Interaction between the game loop and the rendering thread

Hi all,
I’ve been a lurker of the site for a while now so I thought I’d set up an account and see if I can get some community input on game engine design. I’ve been working on basic engines on-and-off for a while now with some LWJGL-based Java engines running off of Box2D and others off of a custom 2D collision and physics engine and I’m in the process of porting over a lot of my previous work to an Android system. I’ve been at this for a couple of weeks now and I have a rudimentary engine running, rendering with OpenGL ES 2.0. Input, updates, rendering, glitchy physics, the works.

But I’m pretty stumped on what is the best architecture for a game engine on Android. I have my game loop and rendering occurring in separate threads currently and I’m fighting against concurrent modification exceptions every now and again. I’ve heard of three methods around threaded engine issues so far:

  1. Synchronize all object calls that might cause concurrent access issues between the two threads. I tried this, it was messy and lead to framerate stutter as both threads were essentially waiting for each other constantly (kind of against the point of threads)
  2. Run everything from the render loop. Create new threads for things such as I/O or whatever, but all game logic could just run on one thread. This doesn’t seem very attractive as a solution though?
  3. Create some sort of “intermediate buffer” which stores all renderable object positions. Meaning that thread access to this would be more optimized, rather than synchronizing a full update loop for example. Also means that the render thread won’t run against values which are mid-update and lead occasional artifacts such as tearing between sprites.

If anyone has heard any opinion on the best way to layout an Android game engine, please let me know. I’m finding myself pretty stumped on this so far. Currently going to look into option 3 over the week until I have something better to work off of.

From my experience, Android is a lot different from traditional desktop systems. Unlike the desktop, you have two threads, the android UI thread and the GLThread created for you by the GLSurfaceView. I see that you are trying to separate rendering and logic, but I’d say it’s not worth the effort on Android.

I agree that parallelization gives a performance boost, but only if done correctly. And most of the time, there will be other reasons of you experience the performance issues. I’d not go for it unless there are no other areas of optimization left.

Coming to the question, I guess you want to run some tasks on the UI thread, like operations that switch the device orientation etc., and some other you want to handle in the GLThread, like in the case of inputs.


surfaceView.queueEvent(() -> postTouchEvent(finger, false, 0, 0));

That will make your code run on the GLThread. Now for operations like changing the device orientation, you can use the activity methods like this.


activity.runOnUiThread(() ->
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE));

This is very similar to swing’s SwingUtilities.invokeLater method. Now let us get to the game loop. In the renderer of the GLSurfaceView, there is no separation of logic and render. When you set the render mode to continuous, it repeatedly calls the onDrawFrame method, so keep both the update and render calls directly in it.

For reference, you can checkout the code in my android backend: https://github.com/sriharshachilakapati/SilenceEngine/tree/master/backend-android/src/main/java/com/shc/silenceengine/backend/android

Thanks for the reply. I haven’t had the chance to properly check out your Android backend since I’ve just checked back here but it looks to be an invaluable resource. In the meantime while I was away for the last few hours I went ahead and developed a buffer list for rendering objects to work with my current architecture. So I’m still doing all game logic on a separate thread. I’m going to have to let it stew for some time and make sure it gets thoroughly tested out but so far its looking to be a great solution. The only thing I’m worried about is possible performance issues but I’m not seeing them so far.
In the future I would definitely take your advice to avoid going down this route, it certainly is not worth the effort so far. As a warning to anyone who finds themselves in similar issues, you’re better off running the game logic in the render thread. The introduction of additional threads has proved as nothing more than a headache, even if I seem to have everything in a working order now.

I’m doing all my game logic in the rendering thread. The actual rendering happens in parallel on the GPU anyway (at least to a degree), so there’s not much to gain (if anything) by doing the logic in another thread.
For most games, the logic isn’t that time consuming anyway. I once tried to separate them into two threads and the performance benefit was null, nada, niente…none at all. My current game (https://play.google.com/store/apps/details?id=com.threed.jpct.games.rpg) supports the option to do some heavier calculations in a different thread, but it’s disabled in production code, because it just isn’t worth it.

Did some tune up on the architecture today and still not seeing any issues (related to the threading at least). The code seems to be pretty sound. But as the others have pointed out, and I’m seeing the same, there’s no sense of optimization from this format.
So far, was not worth the effort it took to figure out and implement and it makes the code far less intuitive to read since I had to push so many values related to rendering out of the game objects they belong in and into corresponding buffer objects.