简体   繁体   English

Android OpenGL ES 3.0 PBO而不是glReadPixels()

[英]Android OpenGL ES 3.0 PBO instead of glReadPixels()

I want to improve glReadPixels() performance using PBO (for GLES 3 devices) and I ran into a problem in this piece of code: 我想使用PBO(对于GLES 3设备)改进glReadPixels()性能,我在这段代码中遇到了一个问题:

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. 目前它失败了glReadPixels()方法。 I found this & this , but I'm unable to send a zero because it takes an IntBuffer argument. 我发现了这个这个 ,但我无法发送零,因为它需要一个IntBuffer参数。 I would very appreciate any suggestions about the issue 我非常感谢有关这个问题的任何建议

UPDATE: It seems to be impossible to only use Java API for that task. 更新:似乎不可能只为该任务使用Java API。 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. 所以我使用ndk添加一个函数,用正确的最后一个参数调用glReadPixels() (int offset)现在没有一个GL调用产生错误。

That's my jni c code: 这是我的jni c代码:

#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 . 现在的问题是glReadPixels()调用比没有PBO需要更多的时间,所以还没有性能提升 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. 更新2我忘了更早更新它,但事实上问题是我使用pbuffer表面,这就是为什么我没有性能提升。 I compared that option and option of not using pbuffer surface and performance gain was huge. 我比较了不使用pbuffer表面的选项和选项,性能提升很大。

So in case rendering offscreen and using glReadPixels it's worth using pbuffer surface 因此,如果在屏幕外渲染并使用glReadPixels,则值得使用pbuffer表面

Mapping PBO buffer right after glReadPixels always kills performance. 在glReadPixels总是杀死性能之后立即映射PBO缓冲区。 GPU is still working when you requested the mapping. 您请求映射时GPU仍在工作。 Hence, glMapBufferRange waits gpu to complete reading pixels to the PBO. 因此,glMapBufferRange等待gpu完成读取PBO的像素。 If you continue rendering after glReadPixels and will do the mapping after some frames then you will get performance gain. 如果你继续在glReadPixels之后渲染并且在一些帧之后进行映射,那么你将获得性能提升。

More information here: http://www.songho.ca/opengl/gl_pbo.html Look "Mapping PBO" section. 更多信息请访问: http//www.songho.ca/opengl/gl_pbo.html查看“映射PBO”部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM