Skip to content

Android CameraGLRenderBase/CameraGLSurfaceView crash on application pause/exit due to invalid EGL context. #11233

Open
@W1M0R

Description

@W1M0R
System information (version)
  • OpenCV => 3.4.1
  • Operating System / Platform => Windows 64 Bit
  • Compiler => Android Studio 3.1 (Clang NDK 16)
Detailed description

My Android activity creates a GL surface view that derives from CameraGLSurfaceView. During execution everything works as expected, but when I switch to another running app, forcing the activity to pause, the activity crashes. Logcat indicates that a thread was trying to work with an EGL context that didn't exist.

Steps to reproduce
  1. Using Android Studio, create an Android app based on OpenCV Android Tutorial 4.

  2. Install and run the app on your phone.

  3. Use Android Studio's Logcat view to inspect the applications log while it executes.

  4. Press the Android app switching button.

  5. Your list of running applications appear.

  6. After a few short moments, your app crashes.

  7. Verify with Logcat that an EGL context error occurred.

Fix

The crash is caused by trying to access the EGL context from different threads. It happens in CameraGLRenderBase's updateState method. It typically calls doStart in the correct thread (the GLThread), but doStop sometimes gets called from the main thread. The solution entails doing proper thread management.

To solve the problem, the code can be changed in the following ways (using Kotlin in this example):

  1. CameraGLRenderBase:

     @MainThread
     @Synchronized
     fun enableView() {
         mEnabled = true
         mView.queueEvent( { updateState() } ) // this is the fix
     }
     ...
     @MainThread
     @Synchronized
     fun disableView() {
         mEnabled = false
         mView.queueEvent( { updateState() } ) // this is the fix
     }
     ...
     @WorkerThread
     protected fun updateState() {
         ... // keep body as is
     }
    
     @WorkerThread
     @Synchronized
     protected open fun doStart() {
         ... // keep body as is
     }
    
     @WorkerThread
     protected open fun doStop() {
         ... // keep body as is
     }
     ...
     @MainThread
     fun onPause() {
         mHaveSurface = false
         mView.queueEvent( { updateState() } ) // this is the fix
         mCameraHeight = -1
         mCameraWidth = mCameraHeight
     }
     ...
     @WorkerThread
     override fun onSurfaceChanged(gl: GL10, surfaceWidth: Int, surfaceHeight: Int) {
         ... // keep body as is
     }
  2. CameraGLSurfaceView.java: Call setCameraIndex after setRenderer is called. This will satisfy the conditions for the mView.queueEvent function.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy