Restart application instead of reload all resources when opengl es context lost on Android

Current status

Currently, when opengl es context lost after back from background, cocos2d-x will try to reload all resources as possible. In order to achieve it, we do some complex work in engine:

  • reload all programs
  • re-create all textures
  • re-set all gl state

Then you can see similar codes spread all over the engine:

#if CC_ENABLE_CACHE_TEXTURE_DATA
    // Listen this event to save render texture before come to background.
    // Then it can be restored after coming to foreground on Android.
    auto toBackgroundListener = EventListenerCustom::create(EVENT_COME_TO_BACKGROUND, CC_CALLBACK_1(RenderTexture::listenToBackground, this));
    _eventDispatcher->addEventListenerWithSceneGraphPriority(toBackgroundListener, this);

    auto toForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(RenderTexture::listenToForeground, this));
    _eventDispatcher->addEventListenerWithSceneGraphPriority(toForegroundListener, this);
#endif

And if program or texture is created from raw data, then we should record all the raw data in engine. It will add the memory usage too.

possible solution

Another solution is to re-start application if the opengl es context lost. This method will simplify the codes, we can remove all codes to recover the states. And may be we can use native activity to prevent missing opengl es context, i am not sure if it works.

pros and cons

Pros and cons of recovering opengl es context:

  • pros
    • application can continue from the point before lost opengl es context
  • cons
    • should add complex logic to recover opengl es context
    • increase memory usage
    • may not recover all the things
    • take a long time to return to foreground if opengl es context lost in background

Pros and cons of re-start application:

  • pros
    • simplify the codes
    • reduce memory usage
  • cons
    • will restart application if gl context lost

when opengl es context lost

I don’t find a documentation to mention it. I think it may happen when system resource is limited. And we find it will not happen frequently as we add this line in engine:

this.mGLSurfaceView.setPreserveEGLContextOnPause(true);

Conclusion

I think we can restart application if opengl es context lost, it will simplify and unify the codes. cocos creator use this method now, and not one complain it.

And we will continue to research how to prevent missing opengl es context, native active may be the solution.

4 Likes

@zhangxm
Can you elaborate more on what does it means “Context” is lost ?
If context is lost the app will crash no? why do you what to reload the application internally ?

First you can check the doc for OpenGL context. When the context is lost, then program, texture, buffer and other OpenGL resource are invalid.

This would be a massive degradation to user experience for most games.
You’re asking users to have to navigate back to the same point in the game anytime the context is lost.

If a device or user pattern (switching to another app that invalidates the OpenGL context) causes the context to be lost often you it will essentially make the app appear like a non multi-tasking app having to be restarted everytime someone uses it.

You should have a reasonable amount of information or analytics on the occurance of this before potentially causing quite a large negative change of behaviour

As i know it is not happen often, but we don’t have the data. We don’t have the data to show how often it is. It depends on the devices, the settings and the user behavior.

what if you store all relevant data to a temp file when the app receiving the on enter background to load the data from that file?

@slackmoehrle
This another good reason to release cocos2dx-3.17.1 cpp-tests in Google Play:)

Can I just upload your .apk? :slight_smile:

I do not think that this will help much, since cpp-tests project is not an actual game, and any users will not interact with it as such. Although I remember that he promised to do it long time ago. Promises… promises…

Fragment from the book Android NDK: Beginner's Guide by Sylvain Ratabouil

I am fine with restarting in most of these situations, but I do not like the case if the user has achieved some great result in the game and decides to share it, then he decided to return to the game to continue (maybe he did not just finish the round, he may improve the result continuing from that particular point), and now he is trying to get back into the game to see that it has restarted. What the hell !! ?? Crying user, 1 star rating.
Of course I can save his results and try to start the game from the same place, but it would be better not to restart it.