PBO in openGL ES is stalling

Hello Guys,

I am running into some troubles when it come to using PBO’s in opengl es. I did a fairly large amount of reading trough the forum and the Internet concerning that issue (there are several posts on pbo stalling issue, and found 2 specifically about openglEs on that forum), and I am thinking the issue I am facing is hardware related more than anything else; even though I may also have a made a mistake in my code as I am fairly new to the world of OpenGl in general.

The goal that I am trying to achieve is to grab a screen capture of the OpenGl context and save it directly in the app so the user as full control of creating/saving and sharing content within my app: it is essential that I use glReadPixels to get a hold of the actual gl context, and hopefully achieve video capture with a triple or quadruple-buffered approach.

The code bellow is in Java, I call takeSnap() at the end of my OnDrawFrame() method meaning that it is supposed to be the last thing that is called at the end of the frame.

Also not having acces to the glReadPixels( […], void* data) in Java I used the JNI to call that function that is what glReadPixelsPBO() stands for.


 private void takeSnap(Viewport eyeView) {
        
        if (bDoScreenShot) {


            if (destination == null) {
                destination = ByteBuffer.allocate(eyeView.width * 4 * eyeView.height);
                destination.order(ByteOrder.nativeOrder());
            }

            index = index % 2;
            int nextIndex = (index + 1) % 2;

           // Log.d("Indexscreen", " index = " + index + " index2 = " + nextIndex);

            int videoSize = eyeView.width * eyeView.height;
            long startime = System.nanoTime();
            if (frameNum == 0) {

                GLES30.glGenBuffers(2, pboIndex, 0);
                
                GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIndex[0]);
                GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER, videoSize * 4, null, GLES30.GL_DYNAMIC_READ);
                
                GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIndex[1]);
                GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER, videoSize * 4, null, GLES30.GL_DYNAMIC_READ);

                GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, 0);
               
            }
            /////

            /////
            GLES30.glReadBuffer(GLES20.GL_FRONT);
            GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIndex[index]);

            startime = System.nanoTime();
            glReadPixelsPBO(0, 0, eyeView.width, eyeView.height, GLES30.GL_RGBA, GL10.GL_UNSIGNED_BYTE, 0);
            long pixelRead = (System.nanoTime() - startime) / 1000000;
            Log.d("TimeValues", "Times 
 " + " Time to read pixel = " + pixelRead);


So in my testing pixelRead is usually around 200ms… glReadPixels stall and I can’t get why !

Phone is 3 years old, Sony Xperia SP that run android 4.3, supporting GLES30 !

Check the parameters to your glReadPixels call - if there’s a mismatch between these and your native framebuffer format the driver will certainly have to do a software conversion, which will also require a temporary allocation and some one-pixel-at-a-time conversions.

Because you’re using GL_RGBA and GL_UNSIGNED_BYTE you almost certainly do have such a mismatch. I don’t know the optimal format for your device; it will depend on hardware, what you select during startup, etc, so the best I can say is that you’re going to need to try different combinations of the available parameters, time them, and see which comes out fastest.

Hello mhagain,

Never mind, I found out where my issue where: I am actually using a frame work that implements custom call to OnDrawFrame() in which it seems is not final rendering operation : so it was stalling because the GPU actually needed to do some more rendering/processing on to the frame…

Wish I could delete the thread now ! >.>