PBO на Android не улучшает производительность glReadPixels
Я хочу сделать снимок текущего кадра в OpenGL для дальнейшей обработки, и я пытаюсь улучшить производительность glReadPixels, используя PBO для асинхронного чтения кадровых буферов.
У меня сложилось впечатление, что glReadPixels после того, как GL_PIXEL_PACK_BUFFER привязан к буферу, должен немедленно вернуться, но на самом деле это занимает аналогичное или даже больше времени, чем без использования 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);
Основываясь на этой статье, причиной замедления может быть преобразование между внутренним форматом, который может быть GL_BGRA, и форматом передачи пикселей, который в моем коде является GL_RGBA. Изменение формата передачи на GL_RGB уменьшит задержку glReadPixels примерно до 100 мс, но когда я сопоставлю буфер с GLES30.glMapBufferRange, выходной кадр будет выглядеть неправильно. Я также попробовал формат GL_BGRA в GLES11Ext, но это вызовет GL_INVALID_OPERATION в glReadPixel.
Есть ли другой способ заставить glReadPixels на Android сразу же вернуться, чтобы PBO мог улучшить производительность?
1 ответ
Как и предполагал Рето, это проблема, связанная с реализацией. Графический процессор, с которым я первоначально тестировал, - это Adreno 306. Когда я тестирую те же коды на Samsung Note 4 (Adreno 420), он работает как положено. Поэтому всегда стоит протестировать на разных устройствах и графических процессорах такие проблемы.