OpenGL Access Within a Thread

I need some help!!

I am developing for Android, using OpenGL ES 1.0 with some 1.1 accessibility.

Okay so I have OpenGL load my textures when onSurfaceCreated is called.


Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),bitmaps[i]);
glBindTexture(GL_TEXTURE_2D,textures[i]);
glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE); 
glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
texImage2D(GL_TEXTURE_2D,0,bitmap,0);
bitmap.recycle();

The textures load great, everything works fine.
But I am giving the user the option to adjust the color/hue of some of the textures that are loaded.

The color change function loops through the image pixel by pixel and changes the color and hue using “Color.colorToHSV”

and then rebinds the adjusted image like such


localBitmap = changeHue(2, BitmapFactory.decodeResource(Wallpaper.this.getApplication().getApplicationContext().getResources(), Wallpaper.this.bitmaps[1]));
glBindTexture(GL10.GL_TEXTURE_2D,textures[1]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, localBitmap, 0);
localBitmap.recycle();

This works fine, but while it is adjusting the color of the image, it locks my GUI thread making my application to appear freeze for roughly 10 seconds while it makes the adjustments.

I have been playing around today on ways to prevent this lockup and speed up the time it takes to adjust the colors.
The images are only 512*512 and I am trying to make this color change happen immediately so there is no delay and no lock-up.

So I thought about using a thread/runnable.
I have used them before and they have significantly decreased the wait time for calculations to be performed, but I have never used them with OpenGL and from what I have heard OpenGL and multitasking can be a complicated thing.

I had made a thread to do the calculations when necessary then rebind the textures etc.

But it seems that I cannot rebind textures outside of the main OpenGL context even if I try to save the context to a variable and access it that way.

Basically I am trying to reduce/remove the wait time for the color change to take effect and move the color change function to a separate thread to prevent locking up my GUI.

Anyone care to shed some light on the best way for me to achieve this? Thanks!

So I have created a TextureManager in a separate class file and I seem to have fixed my problem with not being able to bind textures from another context.

I will see if I am now able to fix my color change function, in my meantime if anyone has any suggestions please post.

There is a wiki page that explains the basic constraints http://www.opengl.org/wiki/OpenGL_and_multithreading.

Basically it comes down to:

  • a context can only be current to one thread at a time (i.e. if your context is current in thread A you need to make it not current there first, before you can make it the current context of thread B).
  • having a context per thread can simplify this; make sure to set up the contexts so that they share resources (e.g. textures)

For your case:

  • using a thread is not going to make the colour conversion faster, so if the result is not available instantly now it won’t be when using threads either. Your GUI should remain responsive though.
  • you can avoid the hassle of using OpenGL from multiple threads by only moving the computation to a thread and signal your main thread when it is done, so that it uploads the new data.
  • when only changing the contents of a texture it is better to use glTexSubImage2D, because glTexImage2D reinitializes the texture object in addition to setting its content.

All this is for desktop OpenGL, for ES specifics you may want to try the Khronos OpenGL ES forums.

Excellent thank you for the response.

Hmm I will take a look at these and figure out my best plan of action.

If I am unable to speed up the color conversion, then keeping the GUI responsive will be sufficient for now.

Although there must be a way to reduce the color conversion some how.

And thanks for the glTexSubImage2D I had not thought of that!
Thanks!