MissingGlContextException when opening another screen from AR

See original GitHub issue

I have a Flutter app the uses ArCore with com.gorisse.thomas.sceneform:sceneform:1.20.4 (I checked also 1.20.5). When I open the AR view, open another screen from it and go back, the app crashes with:

E/native  ( 1062): ARCoreError: third_party/arcore/ar/core/session.cc:1740
E/native  ( 1062):  at third_party/arcore/ar/core/session.cc:1740 [type.googleapis.com/util.ErrorSpacePayload='ArStatusErrorSpace::AR_ERROR_MISSING_GL_CONTEXT']
E/native  ( 1062): === Source Location Trace: ===
E/native  ( 1062): third_party/arcore/ar/core/session.cc:1740
E/native  ( 1062): 
E/native  ( 1062): ################### Undecorated Trace End  #################
E/native  ( 1062): 
D/AndroidRuntime( 1062): Shutting down VM
E/AndroidRuntime( 1062): FATAL EXCEPTION: main
E/AndroidRuntime( 1062): Process: co.cosmose.dealhunter, PID: 1062
E/AndroidRuntime( 1062): com.google.ar.core.exceptions.MissingGlContextException
E/AndroidRuntime( 1062): 	at java.lang.reflect.Constructor.newInstance0(Native Method)
E/AndroidRuntime( 1062): 	at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
E/AndroidRuntime( 1062): 	at com.google.ar.core.Session.throwExceptionFromArStatus(Session.java:16)
E/AndroidRuntime( 1062): 	at com.google.ar.core.Session.nativeUpdate(Native Method)
E/AndroidRuntime( 1062): 	at com.google.ar.core.Session.update(Session.java:2)
E/AndroidRuntime( 1062): 	at com.google.ar.sceneform.ArSceneView.onBeginFrame(ArSceneView.java:463)
E/AndroidRuntime( 1062): 	at com.google.ar.sceneform.SceneView.doFrameNoRepost(SceneView.java:466)
E/AndroidRuntime( 1062): 	at com.google.ar.sceneform.SceneView.doFrame(SceneView.java:450)
E/AndroidRuntime( 1062): 	at com.google.ar.sceneform.ArSceneView.doFrame(ArSceneView.java:552)
E/AndroidRuntime( 1062): 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1042)
E/AndroidRuntime( 1062): 	at android.view.Choreographer.doCallbacks(Choreographer.java:839)
E/AndroidRuntime( 1062): 	at android.view.Choreographer.doFrame(Choreographer.java:771)
E/AndroidRuntime( 1062): 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1030)
E/AndroidRuntime( 1062): 	at android.os.Handler.handleCallback(Handler.java:873)
E/AndroidRuntime( 1062): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 1062): 	at android.os.Looper.loop(Looper.java:201)
E/AndroidRuntime( 1062): 	at android.app.ActivityThread.main(ActivityThread.java:6864)
E/AndroidRuntime( 1062): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 1062): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
E/AndroidRuntime( 1062): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

The crash occurs only when the screen has the CardFormField widget from flutter_stripe, which uses ReactNative underneath.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:9

github_iconTop GitHub Comments

1reaction
jakub-cosmosecommented, Mar 9, 2022

I’m not sure if my code will work in all cases, so I’d need to make much more testing before making a PR. I can’t promise that I’ll be able to do it any time soon but I’ll try. My application has a single screen with AR, so I just save the EGL context using static variables. It might or might not work for more complex apps. Below I provide the whole code that I used for my work-around:

When ArSceneView is created or resumed:

    private fun restoreEglContext() {
        if (Looper.getMainLooper().thread != Thread.currentThread()) {
            throw IllegalStateException("restoreEglContext called from non-UI thread")
        }
        debugLog("Restoring EGL context")
        if (savedContext != null && savedContext != EGL14.EGL_NO_CONTEXT) {
            if (!EGL14.eglMakeCurrent(savedDisplay, savedDrawSurface, savedReadSurface, savedContext)) {
                debugLog("Failed to restore")
            }
        } else {
            debugLog("Nothing to restore")
        }
    }

When ArSceneView is paused:

    private fun saveEglContext() {
        if (Looper.getMainLooper().thread != Thread.currentThread()) {
            throw IllegalStateException("saveEglContext called from non-UI thread")
        }
        debugLog("Saving EGL context")
        val currentContext = EGL14.eglGetCurrentContext()
        if (currentContext == null || currentContext == EGL14.EGL_NO_CONTEXT) {
            debugLog("Nothing to save")
        } else {
            savedContext = currentContext
            savedDisplay = EGL14.eglGetCurrentDisplay()
            savedDrawSurface = EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW)
            savedReadSurface = EGL14.eglGetCurrentSurface(EGL14.EGL_READ)
            EGL14.eglMakeCurrent(
                savedDisplay,
                EGL14.EGL_NO_SURFACE,
                EGL14.EGL_NO_SURFACE,
                EGL14.EGL_NO_CONTEXT
            )
        }
    }

When ArSceneView is destoyed:

arSceneView?.renderer?.dispose()

Static variables to store the context:

    companion object {
        private var savedContext: EGLContext? = null
        private var savedDisplay: EGLDisplay? = null
        private var savedReadSurface: EGLSurface? = null
        private var savedDrawSurface: EGLSurface? = null
    }

EDIT: I actually don’t know if the approach in my work-around is something that should be used in the library. Probably the EGL14.eglMakeCurrent should be called internally for every frame.

1reaction
jakub-cosmosecommented, Mar 9, 2022

After a long night of debugging my colleagues created a work-around for the problem in our app. The reason of the problem is that there’s the assumption in Sceneform that nothing will touch the singleton EGL context. Unfortunately, some code used by the Stripe library cleared the singleton. The work-around is to save the EGL context every time the activity is paused and restore it every time it’s resumed. Saving can be done by storing the value of EGL14.eglGetCurrentContext() and then setting the singleton context to EGL14.EGL_NO_CONTEXT using EGL14.eglMakeCurrent. Restoring can be done with the EGL14.eglMakeCurrent call. There’s also one other problem with Sceneform: the method ArSceneView.destroy() doesn’t call renderer?.dispose(), so it has to be called manually every time the ArSceneView.destroy() is called.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Opening an ARFragment consecutive times causes ... - GitHub
When I close and open the AugmentedImageActivity the second time it crashes with MissingGlContextException: E/native: s...
Read more >
MissingGlContextException | ARCore - Google Developers
Stay organized with collections Save and categorize content based on your preferences. Thrown when an operation requires GL context (unchecked).
Read more >
MIssingGlContextApplication Exception while getting RGB ...
Though, I'm getting the following error from session.update(): W/System.err: com.google.ar.core.exceptions.MissingGlContextException.
Read more >
MissingGlContextException when opening another screen ...
I have a Flutter app the uses ArCore with com.gorisse.thomas.sceneform:sceneform:1.20.4 (I checked also 1.20.5). When I open the AR view, open another ......
Read more >
Untitled
open. cookies. LoginCookieUtils.java; CookieManagerWrapper.java; CookieManagerService.java ... MiPushClient4Hybrid.java; Logger.java; ab.java; ar.java ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found