9

I have a simple Android application that renders data with our OpenGL rendering SDK to an Android GLSurfaceView. Since we provide and SDK for others to use we need to support all use cases for the GLSurfaceViews. Currently we need to be able to rotate the device while recreating all the Android views and keeping the OpenGL context alive. This originates from a customer needing different layouts in landscape and horizontal mode.

The normal way of going about this would be:

1. Add android:configChanges="orientation|screenSize" to your Activity in AndroidManifest.xml and you will be fine.

This will not work in this case as this does not recreate the views on rotation. Thus by doing this we cannot have different layouts in landscape and horizontal mode.

2. Call GLSurfaceView.onPause() and GLSurfaceView.onResume() from the Activity.

While this is considered good practice it is not enough in this use case as the OpenGL context is destroyed when doing this. Note that we are still doing this, it just doesn't solve our issue.

3. Use an EGLContextFactory to preserve the OpenGL context while rotating.

This is possible and useful as described in, for example, this answer. It feels like a hack, but it definitely works. The idea is simply to create an EGLContext when you don't have one and reuse the one you have if it exists.

The main problem we face when using this hack is that the render thread is destroyed and recreated when the GLSurfaceView is detached and reattached to the view hierarchy. This seems to be by design by looking at the GLSurfaceView implementation.

In our SDK we have some Thread Local Store connected to the thread, so suddenly getting a new render thread is not really desirable. We could probably change some state when the render thread has changed, but we want to investigate if there are better ways of doing this.

So my questions are:

A. Is using the EGLContextFactory the "proper" way to be able to manually save the OpenGL context on rotation?

B. Are there any ways to not destroy and recreate the render thread on rotation (without modifying the source)?

C. Are there any better/simpler alternatives to achieving rotation with views destruction/recreation while keeping the OpenGL context and the rendering thread?

Extra info:

  • We always call setPreserveEGLContextOnPause(true);.
  • There are no issues with the rendering itself, it is simply the described related issues that are problematic.
Xplora
  • 837
  • 3
  • 12
  • 24
Krøllebølle
  • 2,878
  • 6
  • 54
  • 79
  • You should not need to recreate the EGLContext when the device changes orientation. This generally is only required if the device goes to sleep (and also possibly if the application is backgrounded and the OS decides it needs more resources). A rotation should only result in a `GLSurfaceView.Renderer.onSurfaceChanged` callback. – MuertoExcobito Oct 25 '17 at 14:12
  • The behavior you describe is only when `android:configChanges="orientation|screenSize"` is set in `AndroidManifest.xml`. I cannot use this in my case as I want different layouts in landscape and portrait mode. – Krøllebølle Oct 26 '17 at 07:49
  • This is my question too, cause I am using GLSurfaceView in my project now. And, it will be easily crashed when you do quickly rotate the device. My temp solution is that we need to detect the rotation happened, and pause the Surface rendering first, after done the rotation, we resume the surface rendering. – Chauyan Mar 29 '18 at 10:30
  • Did you find a solution? I have been able to handle rotation, but my GLSurfaceView is displaying a warped camera preview (its the wrong orientation and squished) – JCutting8 Apr 28 '20 at 13:32

0 Answers0