rafalczuj
rafalczuj

Reputation: 51

Prevent EGLContext to be destroyed when going to background

My Android (OpenGL ES 2.0) game needs to be paused when user is minimizing it, without destroying what is already drawn on screen. Originally it used NativeActivity and pure C++, but it looks like it is not possible there. I have rewritten it and it is now Java generating custom GLSurfaceView and game logic+rendering is in C++. I added setPreserveEGLContextOnPause(true) when surface is created.

So the flaw after user click Home button is:

  1. onPause is sending nativeOnPause to C++ code through JNI
  2. C++ code sets pause variable which prevents updating and rendering

This works ok. After we get back to app:

  1. onResume calls nativeOnResume
  2. nativeOnResume calls EGL methods to get current context, display and surface and pass that to game manager.
  3. Updating and rendering is now activated
  4. We get few EGL_BAD_SURFACE messages and finally crash on eglMakeCurrent

The question is: should we in any way recreate EGLSurface and EGLDisplay using current context, or getting current surface and display is fine?

I also noticed that when we get back to app, onResume is called, but onSurfaceChanged or onSurfaceCreated is not called.

Any suggestion how to approach that problem on >4.0 devices?

Upvotes: 2

Views: 2320

Answers (1)

fadden
fadden

Reputation: 52303

Don't use GLSurfaceView if you want to control the EGL context lifetime.

The GLSurfaceView class handles the EGL context for you, and is fairly aggressive about discarding it. The setPreserveEGLContextOnPause() call probably won't do what you want. If you switch to a SurfaceView you will have full control over the EGL context lifetime, but that's a double-edged sword, as you are now required to manage the EGL context entirely.

You can find various examples of using GLES with SurfaceView in Grafika. The "hardware scaler exerciser" activity is a reasonable example.

That activity also demonstrates one approach to Activity lifecycle management. A discussion of the relationship between Activity and SurfaceView, including why you're not always seeing surfaceChanged() and surfaceCreated(), can be found in an appendix to the graphics architecture document.

Having said all that, keeping the EGL context and all associated resources around while your app is inactive is a bad practice. When the user pauses your app, those resources should be released so that other apps have the full capabilities of the device at their disposal.

Upvotes: 2

Related Questions