Android上的PBO并没有改善glReadPixels的性能

时间:2016-12-03 05:24:29

标签: android opengl-es glreadpixels pbo

我想在OpenGL中截取当前帧的截图以进行进一步处理,并且我试图通过使用PBO异步读取帧缓冲区来提高glReadPixels的性能。

我认为GL_PIXEL_PACK_BUFFER绑定到缓冲区后的glReadPixels应立即返回,但它实际上需要的时间与不使用PBO相似甚至更长。

以下是我的代码示例:

// Setup PBO
GLES30.glGenBuffers(nPbo, pboIndex, 0);
for(int i=0;i<nPbo; i++){
    GLES30.glBindBuffer (GL_PIXEL_PACK_BUFFER, pboIndex[i]);
    GLES30.glBufferData(GL_PIXEL_PACK_BUFFER, size, null,GL_STREAM_READ);
}
GLES30.glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

......

// For each frame, trigger async transfer of framebuffer to PBO.
// Note that I don't even map the PBO to memory yet
GLES30.glBindBuffer (GL_PIXEL_PACK_BUFFER, pboIndex[index]);
// The following is a JNI method to overload glReadPixels in GLES20.glReadPixels,
// to allow passing int offset to the last param in order to use PBO, 
// and slowdown (around 500ms on my device) happens here
GLES3PBOReadPixelsFix.glReadPixelsPBO(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0); 
GLES30.glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

基于this article,导致速度放缓的原因可能是内部格式(可能是GL_BGRA)与像素传输格式(我的代码中为GL_RGBA)之间的转换。将传输格式更改为GL_RGB会将glReadPixels的延迟减少到大约100ms,但是当我使用GLES30.glMapBufferRange映射缓冲区时,输出帧看起来没有正确呈现。我还在GLES11Ext中尝试了GL_BGRA格式,但它会在glReadPixel中导致GL_INVALID_OPERATION。

还有其他方法可以让Android上的glReadPixels立即返回,以便PBO可以提高性能吗?

1 个答案:

答案 0 :(得分:0)

正如Reto所建议的那样,事实证明这是一个特定于实现的问题。我最初测试的GPU是Adreno 306.当我在Samsung Note 4(Adreno 420)上测试相同的代码时,它按预期工作。因此,在不同的设备和GPU上测试此类问题总是值得的。