I am using OpenGL ES on Android using a GLSurfaceView
and I want to be able to load textures on a separate thread to the render thread used by GLSurfaceView
since I want to load textures on demand rather than loading them all in onSurfaceCreated
.
Currently I load bitmap files on a background thread and then at the start of onDrawFrame
if there are any bitmaps to load then GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
is utilised, however this can cause some laggy behaviour.
Based upon some other articles I believe that I need to create an off-screen surface using eglCreatePbufferSurface
with an associated thread separate to the thread used in the GLSurfaceView
for rendering, but with a shared context being the EGLContext
used by the rendering thread. This would enable me to have a dedicated thread for uploading textures but the context would be shared so then the rendering thread could access the uploaded textures.
Is this the correct way to approach this problem or am I misunderstanding what is required?
I have seen this post, which describes a similar issue: Threading textures load process for android opengl game but unfortunately it uses OpenGLES 1.0 and the example project doesn't seem to work. I have tried to modify it for OpenGLES 2.0 but I am unable to generate a texture, which suggests an issue with associating the EGLContext to the thread. I have also looked at the Grafika project, which has examples of creating a WindowSurface
and an OffscreenSurface
but I haven't seen these used together and probably need to migrate to using SurfaceView
which if necessary is fine to do.
CodePudding user response:
The basic approach is to create a secondary EGLContext
in the same sharegroup as the original application context. You can create and upload textures in the secondary context, and use them in the primary context.
Importantly note that you will need to include synchronization between the contexts to ensure that the data upload to the texture has actually completed before the primary thread starts to use it. OpenGL ES provides automatic synchronization of the texture object state when bound, but not the data the texture contains.
Most modern devices allow a surfaceless context, so you may not need to allocate a dummy Pbuffer surface for context creation - YMMV here.