2015-02-17 3 views
3

Я хочу, чтобы улучшить 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 это стоит использовать пиксельный буфер поверхности

+1

Weird. Похоже, что точка входа Java для использования PBO для 'glReadPixels()' отсутствует. Если это действительно так, это не первый случай, когда это произошло в Android. Использование собственного кода всегда является решением. Тем не менее, если вы сразу же ждете результата, использование PBO, вероятно, вам не поможет. Вся идея состоит в том, что вызов 'glReadPixels()' не будет блокироваться. Если вы сразу же заблокируете его, это не принесет пользы. –

+0

@RetoKoradi Спасибо за отзыв! В моем случае все еще собственный код не является вариантом. И единственное, что действительно имеет значение, - это то, сколько времени занимает мой блок кода по сравнению с простым вызовом glReadPixels() – Sam

+0

. Я столкнулся с той же проблемой на Android, что не видел повышения производительности с помощью PBO. Можете ли вы любезно объяснить, как не использовать поверхность pbuffer на Android, чтобы включить быстрые и асинхронные glReadPixels в PBO? Благодарю. –

ответ

2

Mapping ОПО буфер сразу после glReadPixels всегда убивает производительность. GPU все еще работает, когда вы запрашиваете сопоставление. Следовательно, glMapBufferRange ожидает, что gpu завершит чтение пикселей в PBO. Если вы продолжаете рендеринг после glReadPixels и будете делать сопоставление после некоторых кадров, вы получите прирост производительности.

Дополнительная информация здесь: http://www.songho.ca/opengl/gl_pbo.html Посмотрите раздел «Сопоставление PBO».

+0

Обновлен мой ответ. И я видел эту статью и многие другие тоже - к сожалению, в то время я не понимал, что произошло – Sam

Смежные вопросы