Обновление # 1 Я реализовал очередь PBO, которые я перебираю, чтобы попытаться помочь уменьшить задержку пользовательского интерфейса.По сути, я привязываюсь к PBO, вызываю glReadPixels
, настраиваю объект забора и жду, пока этот объект будет сигнализирован.
Все время я загружаю больше пикселей в другие PBO через glReadPixels
,Как только объект синхронизации становится сигнальным, я пытаюсь glMapBufferRange
на сигнализированном PBO.Однако это все еще блокирует пользовательский интерфейс.
Есть ли способ заставить эти вызовы выполняться на отдельном рендерере?
Я пишу приложение для отключения экранных данныхтелефона и превратить серию изображений в видео.Моя проблема в том, что независимо от того, что я делаю, вызовы openGL блокируют поток пользовательского интерфейса.
Ниже я разместил код, который я использую для чтения пикселей с экрана, а затем отобразил их обратно вByteBuffer, которым я могу манипулировать позже.
Мое приложение использует GLSurface, в который я ставлю события в очередь, однако очередь событий на этот переданный GLSurface блокирует пользовательский интерфейс.
Я попытался создать новое представление GLSurface со следующим:GLSurfaceView mGLSurfaceView = new GLSurfaceView(mContext);
Однако все события, вызываемые через queueevent
, никогда не обрабатываются.Почему это?
private void screenScrape() {
sync = 0;
//read pixels from frame buffer into PBO (GL_PIXEL_PACK_BUFFER)
mGLSurfaceView.queueEvent(new Runnable() {
@Override
public void run() {
//generate and bind buffer ID
GLES30.glGenBuffers(1, pboIds);
checkGlError("Gen Buffers");
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIds.get(0));
checkGlError("Bind Buffers");
//creates and initializes data store for PBO. Any pre-existing data store is deleted
GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER, (mWidth * mHeight * 4), null, GLES30.GL_STATIC_READ);
checkGlError("Buffer Data");
glReadPixelsPBO(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0);
checkGlError("Read Pixels");
long afterTime = System.currentTimeMillis() - startTime;
sync = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
});
//map PBO data into client address space
mGLSurfaceView.queueEvent(new Runnable() {
@Override
public void run() {
int result = GLES30.glClientWaitSync(sync, GLES30.GL_SYNC_FLUSH_COMMANDS_BIT, 15000000);
Log.d(TAG, "GL Client Wait Sync Result = " + result);
//read pixels from PBO into a byte buffer for processing. Unmap buffer for use in next pass
mapBuffer = ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, 4 * mWidth * mHeight, GLES30.GL_MAP_READ_BIT)).order(ByteOrder.nativeOrder());
checkGlError("Map Buffer");
GLES30.glUnmapBuffer(GLES30.GL_PIXEL_PACK_BUFFER);
checkGlError("Unmap Buffer");
flipBuffer(mapBuffer);
mapBuffer.clear();
}
});
}