【发布时间】:2015-04-18 16:37:09
【问题描述】:
我想使用 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);
目前它失败了glReadPixels() 方法。我找到了this 和this,但我无法发送零,因为它需要一个 IntBuffer 参数。我将非常感谢有关此问题的任何建议
更新:似乎不可能只使用 Java API 来完成该任务。所以我使用 ndk 添加了一个函数,该函数调用 glReadPixels() 并带有正确的最后一个参数(int offset)
现在我的 GL 调用都不会产生错误。
这是我的 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);
}
现在的问题是glReadPixels() 调用比没有 PBO 需要更多的时间,所以 还没有性能提升。我将探索为什么会发生这种情况并在我发现某些内容时进行更新。
更新 2 我忘了早点更新它,但实际上问题是我使用的是 pbuffer 表面,这就是我没有性能提升的原因。我比较了这个选项和不使用 pbuffer 表面的选项,性能提升是巨大的。
因此,如果在屏幕外渲染并使用 glReadPixels,则值得使用 pbuffer 表面
【问题讨论】:
-
很奇怪。似乎缺少为
glReadPixels()使用 PBO 的 Java 入口点。如果确实如此,这不是Android第一次发生这种情况。使用本机代码始终是一种解决方案。也就是说,如果您立即等待结果,使用 PBO 可能对您没有多大帮助。整个想法是glReadPixels()调用不会阻塞。如果你事后立即阻止,那不会有多大好处。 -
@RetoKoradi 感谢您的反馈!就我而言,本机代码仍然不是一种选择。唯一真正重要的是与简单的 glReadPixels() 调用相比,我的代码块需要多少时间
-
我在 Android 上遇到了同样的问题,即使用 PBO 没有看到性能提升。您能否解释一下如何不在 Android 上使用 pbuffer 表面来启用快速和异步 glReadPixels 到 PBO?谢谢。
标签: android glreadpixels opengl-es-3.0 pbo