In short - I have an OpenGL texture which I need to copy into a FBO or another texture in the most efficient way possible under OpenGL ES 2.0.
At the moment I'm simply drawing the first texture into an FBO.
Is there a more efficient way? E.g. some sort of pixel copy that doesn't involve pulling the pixel data back to RAM and then buffering over to another texture - in ES 2.0 profile.
To give you context - this is video rendering related:
I have an OpenGL texture being buffered with video frame data from LibVLC, but due to timing issues between my app redraw rate and the decoder refresh rate, its possible that the OpenGL texture has no new frame to update & very oddly if I were to draw the texture to the screen without a frame to update - instead of it containing the previous frame's data, it draws some weird image of its own ( it looks like a space invader ?? ) - hence why I need to 'cache' the previous frame's content.
Specifically, this is an OpenGL texture, used to create an Android SurfaceTexture, which I have to call updateTexImage and releaseTexImage manually to either update the Texture's content and then to mark that I'm done with the SurfaceTexture's content once I've drawn it. If I don't release it then no new frames can be updated to it. If I release it I can't redraw the same frame more than once. Which has lead me to caching the texture once it's updated so the decoder is free to write to it & I still have the previous frame if when I come to draw again & there hasn't been an update yet.
Thanks.
This solution is based on having worked out how to properly interface with the Android SurfaceTexture to avoid having to cache its contents altogether.
If anyone wants to share an answer regarding efficient texture copies in OpenGL ES 2.0 please feel free - that would befit my original question.
For anyone interested, this is what I did:
My GLPaint class for rendering video on Android contains the SurfaceTexture instance, it's created from a JOGL OpenGL Texture ( using it's ID ) - This enables me to draw the texture as part of my GLPaint.paint function.
This GLPaint implements the onFrameAvailable method of the SurfaceTexture.OnFrameAvailableListener interface. I have a private boolean to flag when the first frame has been 'written' - this is needed to avoid releasing the SurfaceTexture prematurely.
The class GUIThreadLock is my extension of a ReentrantLock - I extended it for additional debugging info and to make a static singleton. This lock in my 'one in - one out' controller for threads in my UI, ensuring only a single thread is active in my UI at a time ( usually just the main renderer looper ) but also handles getting the OpenGL context bound or unbound to the lock owner thread whenever one acquires and relinquishes the lock respectively.
@Override
public void onFrameAvailable( SurfaceTexture pSurfaceTexture )
{
try
{
GUIThreadLock.acquire();
if( written )
{
pSurfaceTexture.releaseTexImage();
}
pSurfaceTexture.updateTexImage();
written = true;
}
finally
{
GUIThreadLock.relinquish();
}
}
This means that when a new frame is ready, the SurfaceTexture releases the old one & updates to the new one - it is then buffered with the current frame for any point I wish to draw the video until the next frame is ready. The GUIThreadLock protects the SurfaceTexture from updating the content while I may be drawing it but also acquires my GL Context so that the callback thread can actually perform the update here.
My Redraw thread would also require the GUIThreadLock before it could draw my app - thus the GL context is protected and the relationship between frame updates and frame draws cemented.