google-ar / sceneform-android-sdk

Sceneform SDK for Android
https://developers.google.com/sceneform/develop/
Apache License 2.0
1.23k stars 604 forks source link

Strange screen wobbling when using Sceneform then another 3D viewer then again Sceneform #514

Open kstpr opened 5 years ago

kstpr commented 5 years ago

In our app we have a OpenGL ES 3.0-based 3D viewer with a custom renderer that we used to visualize architectural models. After adding a Sceneform module for viewing the models in AR we found that the two viewers (that in theory have no common points) interfere with each other. More specifically when we open a model in the Sceneform module then exit, open a model in our 3D viewer, exit again and then open again a model in Sceneform the screen starts to wobble, as if it tries to adjust the screen size dynamically. You can see this in action here: https://drive.google.com/open?id=1vGEr7keFeZ1FDBI76nKVgqnRSA4FUwqT.

This thing happens only when doing the Sceneform -> Custom 3D viewer -> Sceneform sequence described above. If we open only Sceneform sessions it's not happening, neither if we go first Custom 3D viewer -> Sceneform. There's a test project attached with our 3D viewer included as a library where the same thing happens. Any help/ideas why this happens and how can we fix it will be welcome.

Simple project reproducing the problem: MyApplication.zip

romainguy commented 5 years ago

Sceneform uses dynamic resolution and it does look like a bug related to that indeed. @pixelflinger

First step would be to make sure your 3D viewer doesn't stay running in the background when you leave it (which would explain why Sceneform has to do such large resolution changes). What version of Sceneform does this happen with?

romainguy commented 5 years ago

Also on what thread does your custom 3D viewer work? We have an EGL shared context in Sceneform so I wonder if you're somehow messing with the state of our GL context.

kstpr commented 5 years ago

Dumped the activities task and the activity hosting our GLSurfaceView is properly destroyed on exit of our 3D viewer. So in the GLSurfaceView we extend we set our GLSurfaceView.EGLContextFactory where we create/destroy the context:

public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
    int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
    EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
    return context;
}

public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
    egl.eglDestroyContext(display, context);
}

We set our renderer in the GLSurfaceView in setRenderer which creates a dedicated GLThread inside the call. We also set our GLSurfaceView.EGLConfigChooser. We are calling setPreserveEGLContextOnPause(true) in the GLSurfaceView constructor which looked suspicious to me, but removing it changed nothing.