1

I'm creating a game with the Android NDK and OpenGLES (and not using NativeActivity / native_app_glue).

When the user rotates their phone, I don't want the whole activity to be destroyed and restarted, so I've added the necessary part to the manifest file:

android:configChanges="keyboardHidden|keyboard|orientation|screenSize"

and get an onConfigurationChanged() callback as expected. I also get a surfaceRedrawNeeded() callback, which is fine.

However, I would also expect to get a surfaceChanged() callback, but this never happens.

The java code looks like this:

public class MyActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        surface = new MySurface();
        getWindow().takeSurface(surface);

        view = new MyView(this);
        getWindow().setContentView(view);

        ... native setup
    }

    ...

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);

        ...
    }

    ...
}

class MyView extends View
{

    public MyView(Context context)
    {
        super(context);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) { ... }

    ... other input stuff
}

class MySurface implements SurfaceHolder.Callback2
{
    @Override
    public void surfaceCreated(SurfaceHolder holder) { ... }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { ... }

    @Override
    public void surfaceRedrawNeeded(SurfaceHolder holder) { ... }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) { ... }

    ...
}

Questions:

  • Should I be getting a surfaceChanged() callback in the surface when the orientation changes?

If not, I guess I have two options:

  1. Rotate my camera and adjust the viewport width / height (not really something I want to keep track of).
  2. Call ANativeWindow_setBuffersGeometry (would this actually give me a rotated display?) and / or eglCreateWindowSurface again? Would I then need to recreate my EGLContext (and reload all my OpenGL stuff... ick)?

So in general, what's the "correct" way of handling orientation changes with regard to the ANativeWindow, EGLSurface and EGLContext?

user673679
  • 1,327
  • 1
  • 16
  • 35
  • I'd expect you to be getting a surfaceChanged, I'm not sure why you're not. It might be worth taking a look at glSurfaceView: https://android-developers.googleblog.com/2009/04/introducing-glsurfaceview.html. You might decide to use it instead of rolling your own OpenGL surface functionality, but if not, then it might at least help you figure out where yours is going a bit wrong. – Columbo Jan 07 '18 at 14:25
  • Thanks. In onCreate I'm using `takeSurface` and `setContentView` in the same way as the `NativeActivity` does it. However, it looks like the `NativeActivity` `onNativeWindowResized` callbacks never happen either: https://stackoverflow.com/questions/32587572/app-cmd-window-resized-is-not-called-but-native-window-is-resized . Although the bug report linked there suggests another reason, I wouldn't be surprised if it's actually the same issue (`surfaceChanged` not happening). So I guess `SurfaceView` or `GLSurfaceView` are the way to go. – user673679 Jan 07 '18 at 20:42

0 Answers0