Я хочу, чтобы улучшить glReadPixels()
производительность с помощью ОПО (для GLES 3 устройств), и я столкнулся с проблемой в этой части кода:Android OpenGL ES 3.0 ПБО вместо 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. Я был бы очень признателен за любые предложения по выпуску
UPDATE: По-видимому, невозможно использовать только Java API для этой задачи. Поэтому я использовал ndk для добавления функции, которая вызывает glReadPixels()
с правильным последним аргументом (int offset) Теперь ни один из моих вызовов GL не вызывает ошибку.
Это мой JNI с код:
#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()
вызов занимает еще больше времени, чем без ОПО так нет никакого прироста производительности пока. Я собираюсь исследовать, почему это происходит и обновляется, когда я что-то нахожу.
UPDATE 2 Я забыл обновить его раньше, но на самом деле проблема заключалась в том, что я использовал поверхность пиксельный буфер, поэтому у меня не было никакого выигрыша в производительности. Я сравнил этот вариант и возможность не использовать поверхность pbuffer и прирост производительности был огромным.
Таким образом, в случае оказания закадровый и используя glReadPixels это стоит использовать пиксельный буфер поверхности
Weird. Похоже, что точка входа Java для использования PBO для 'glReadPixels()' отсутствует. Если это действительно так, это не первый случай, когда это произошло в Android. Использование собственного кода всегда является решением. Тем не менее, если вы сразу же ждете результата, использование PBO, вероятно, вам не поможет. Вся идея состоит в том, что вызов 'glReadPixels()' не будет блокироваться. Если вы сразу же заблокируете его, это не принесет пользы. –
@RetoKoradi Спасибо за отзыв! В моем случае все еще собственный код не является вариантом. И единственное, что действительно имеет значение, - это то, сколько времени занимает мой блок кода по сравнению с простым вызовом glReadPixels() – Sam
. Я столкнулся с той же проблемой на Android, что не видел повышения производительности с помощью PBO. Можете ли вы любезно объяснить, как не использовать поверхность pbuffer на Android, чтобы включить быстрые и асинхронные glReadPixels в PBO? Благодарю. –