Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly initialize and terminate EGL on Android

While there are many samples around about using OpenGL ES on Android all of them seems to be incorrect (even ones come with Android SDK/NDK) in respect to initialization/termination of EGL. And source of problem is just in Android application model which make correct using of EGL weird.

The real problem that EGL initialized per OS's process while all Android samples and even GLSurfaceView (actually most of samples just use it) involve the EGL initialization/termination per Component (Activity or WallpaperService). And this is completely wrong due to the fact that all components are running in same process! There is no problem if application consist of just one component but this is an issue if there are multiple components in application and they are using OpenGL ES each.

Just consider the situation when two application's components which use the OpenGL ES runs at same time and one of them finished. On finishing such component will call the eglTerminate() (Look in GLSurfaceView source code to see what I am talking about) and this will terminate the EGL for whole process! And any EGL calls from another already running component will fail starting from this moment!

I have check for tons of examples and all of them initialize and terminate EGL per component basis (actually no one I have seen do something different than GLSurfaceView do, most of them just copy of GLSurfaceView internals).

And now I am interesting in find a "proper" way to get working (with respect to initialization/termination) with EGL on Android.

The "proper" way should provide:

  1. EGL initialization when any first component using EGL is started
  2. EGL termination when last component using EGL is finished
  3. Multithreading. There is should not be restriction on EGL manipulation only from main application thread.

Please note that (2) is essential to minimize the system resources usage by application when there is no active entities which use the EGL/OpenGL ES.

Any ideas? Or maybe I have overlooked something about the EGL on Android?

Update

There is another interesting related issue:

Due to the fact that only one active rendering context is allowed per thread, only one Component at same time may use OpenGL ES from main thread normally. Having more than one Component which use the OpenGL ES in main thread running at same time will lead to problems because last component calling eglMakeCurrent() will implicitly "substitute" all other Components' contexts by his own one (and this actually will completely broke the components logic).

Update 2 (final)

It was revealed (thanks to Romain Guy) that Android actually has an internal workaround for EGL initialization/termination issue in a form of explicit (it is against the EGL specification and not mentioned in the Android documentation) "reference counting" inside the eglInitialize() and eglTerminate().

like image 741
Alexey Kryshen Avatar asked Jun 15 '11 22:06

Alexey Kryshen


1 Answers

eglTerminate() and eglInitialize() are reference counted so it's okay for each "component" to invoke them. On Android 3.0 in particular, it is very common to have several OpenGL contexts in the same app, and there is no problem whatsoever with EGL.

like image 173
Romain Guy Avatar answered Oct 18 '22 11:10

Romain Guy