I want to improve glReadPixels()
performance using PBO (for GLES 3 devices) and I ran into a problem in this piece of code:
final ByteBuffer pboByteBuffer = ByteBuffer.allocateDirect(4 * mWidth * mHeight);
pboByteBuffer.order(ByteOrder.nativeOrder());
//set framebuffer to read from
GLES30.glReadBuffer(GLES30.GL_BACK);
// bind pbo
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, mPboHandleContainer[0]);
// read pixels(should be instant)
GLES30.glReadPixels(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, pboByteBuffer);
// map pbo to bb
ByteBuffer byteBuffer =
((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, 4 * mWidth * mHeight,
GLES30.GL_MAP_READ_BIT)).order(ByteOrder.nativeOrder());
// unmap pbo
GLES30.glUnmapBuffer(GLES30.GL_PIXEL_PACK_BUFFER);
// unbind pbo
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, 0);
At the moment it fails glReadPixels()
method. I found this & this, but I'm unable to send a zero because it takes an IntBuffer argument. I would very appreciate any suggestions about the issue
UPDATE: It seems to be impossible to only use Java API for that task. So I've used ndk to add a function that calls glReadPixels()
with correct last argument(int offset)
Now none of my GL calls produce an error.
That's my jni c code:
#include <jni.h>
#include <GLES3/gl3.h>
#ifdef __cplusplus
extern "C" {
JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv * env, jobject obj, jint x, jint y, jint width, jint height, jint format, jint type, jint offsetPBO);
};
#endif
JNIEXPORT void JNICALL Java_somepackage_GLES3PBOReadPixelsFix_glReadPixelsPBO(JNIEnv * env, jobject obj, jint x, jint y, jint width, jint height, jint format, jint type, jint offsetPBO)
{
glReadPixels(x, y, width, height, format, type, offsetPBO);
}
Now problem is that glReadPixels()
call takes even more time than without PBOs so there's no performance gain yet. I'm going to explore why that happens and update when I find something.
UPDATE 2 I forgot to update it earlier, but in fact the problem was that I was using pbuffer surface that's why I had no performance gain. I compared that option and option of not using pbuffer surface and performance gain was huge.
So in case rendering offscreen and using glReadPixels it's worth using pbuffer surface