Search code examples
javaandroidopengl-esglsurfaceviewegl

Android: Share a Texture Between GLSurfaceViews in Separate EGL Contexts


Each GLSurfaceView is constructed with its own EGLContext. Using the same context across multiple GLSurfaceViews to have access to the same textures seems to not work on across all GPUs (as shown here).

My question is whether there is a way to share a GL_TEXTURE_EXTERNAL_OES texture across multiple GLSurfaceViews with their default, separate contexts. By default only the thread that creates the GL_TEXTURE_EXTERNAL_OES would be able to access the texture, but I am looking for a way to let the other threads in separate EGL contexts read from this texture, and then render to their separate GLSurfaceViews.

Any guidance would be appreciated. Thank you.


Solution

  • You can't share contexts between multiple GLSurfaceViews because the API doesn't provide a way to do so. You can try to kluge it, but that's likely to break in unpleasant ways. The best way to handle this is to use a plain SurfaceView.

    Bear in mind that a GLSurfaceView is just a SurfaceView with some helper code that manages threading and EGL contexts. If you don't mind writing that part (or just lifting it wholesale out of Grafika) it can be much more convenient to work with SurfaceView.

    To the other part of your question, it is possible to share an external texture across EGL contexts, but it's risky. Grafika's "show + capture camera" Activity shares a GLSurfaceView context with a second context created for MediaCodec, and accesses the texture from both. Unfortunately it does this incorrectly, leading to a race condition. A bug report explains the problem and a suggested solution, and has links to the EGL/GLES docs that specify the behavior when multiple contexts on separate threads share a texture.

    FWIW, I haven't seen a GPU where the Activity in question simply didn't work, so I don't think there's a fundamental problem with sharing. You just have to do the barriers correctly. It's much easier to work with a single context though.