的Android的OpenGL ES 3.0 PBO代替
我想提高使用PBO glReadPixels()
性能glReadPixels()(对于GLES 3个装置)和我遇到了一个问题在这一段代码:的Android的OpenGL ES 3.0 PBO代替
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()
通话时间比没有公益组织这样有没有性能增益还甚至更多的时间。我会探索为什么会发生这种情况,并在我找到某些东西时进行更新。
更新2 我忘了前面更新,但实际上的问题是,我用p缓冲器表面,这就是为什么我没有性能增益。我比较了这个选项和不使用pbuffer表面的选项,性能增益巨大。
所以,如果渲染屏幕外使用glReadPixels它使用p缓冲器表面
映射PBO缓冲glReadPixels总是杀死性能之后的价值。当您请求映射时,GPU仍在工作。因此,glMapBufferRange等待GPU完成读取像素到PBO。如果在glReadPixels之后继续渲染并在一些帧之后执行映射,则会获得性能提升。
更多的信息在这里:http://www.songho.ca/opengl/gl_pbo.html 看“映射PBO”部分。
更新了我的答案。我也看到了那篇文章和其他许多文章 - 不幸的是那时我并没有意识到发生了什么 – Sam 2015-05-26 11:50:57
奇怪。看起来像使用PBO for'glReadPixels()'的Java入口点缺失。如果确实如此,这不是Android中第一次发生这种情况。使用本地代码始终是一个解决方案。也就是说,如果您立即等待结果,那么使用PBO可能对您没有多大帮助。整个想法是'glReadPixels()'调用不会被阻止。如果你之后马上阻止,那不会有太大好处。 – 2015-02-18 06:27:07
@ReetoKoradi感谢您的反馈!在我的情况下,仍然是本机代码。唯一真正重要的是我的代码块与简单的glReadPixels()相比需要多少时间调用 – Sam 2015-02-18 13:35:09
我在Android上遇到过使用PBO没有看到性能增益的相同问题。你能不能解释一下如何在Android上使用pbuffer表面来启用快速异步glReadPixels到PBO?谢谢。 – 2016-11-30 10:17:04