Search code examples
androidopengl-esopenclglsurfaceview

Why is there no onSurfaceDestroyed method in GLSurfaceView.Renderer?


I am working on an Android app that performs OpenCL/OpenGL interops on the camera perview. I am using GLSurfaceView.Renderer. Naturally the code to create and initialize the OpenCL running environment (from OpenGL) is called from onSurfaceCreated, and the actual processing of each preview frame happens in onDrawFrame.

All work well, except when I am finished, I want to clean up the OpenCL stuff. Ideally an onSurfaceDestroyed method would be the perfect place to clean up, but there is no such method in GLSurfaceView.Renderer. So the cleanup code has nowhere to go, and there is probably memory leak in my app.

Here are my questions:

  1. Why is there no onSurfaceDestroyed method in GLSurfaceView.Renderer? There are onSurfaceCreated and onSurfaceChanged. One would expect onSurfaceDestroyed to be there.

  2. Given the fact that no onSurfaceDestroyed exists in GLSurfaceView.Renderer, where should my cleanup code go, and why?


Solution

  • GLSurfaceView is a collection of helper code that simplifies the use of OpenGL ES with a SurfaceView. You're not required to use it to use GLES, and if you've got a bunch of other stuff going on at the same time I recommend that you don't.

    If you compare the complexity of Grafika's "show + capture camera", which uses GLSurfaceView, to "continuous capture", which uses plain SurfaceView, you can see that the latter requires a bunch of extra code to manage EGL and the renderer thread, but it also has fewer hoops to jump through because it doesn't have to fight with GLSurfaceView's EGL and thread management. (Just read the comments at the top of the CameraCaptureActivity class.)

    As one of the commenters noted, I suspect there's no "on destroyed" callback because the class aggressively destroys its EGL context, so there's no GLES cleanup needed. It would certainly have been useful for the renderer thread to have an opportunity to clean up non-GLES resources, but it doesn't, so you have to handle that through the Activity lifecycle callbacks. (At one point in development, CameraCaptureActivity handled the camera on the renderer thread, but the lack of a reliable shutdown callback made that difficult.)

    Your cleanup code should probably be based on the Activity lifecycle callbacks. Note these are somewhat dissociated from the SurfaceView callbacks. A full explanation can be found in an architecture doc appendix.