更新#1我已经实现了一个PBO队列,我循环尝试帮助减少UI延迟。基本上我绑定到PBO,调用glReadPixels
,设置fence对象,并等待该对象发出信号。
我一直在通过glReadPixels
将更多像素加载到其他PBO中。一旦同步对象发出信号,我就会尝试在发出信号的PBO上发布glMapBufferRange
。但是这仍然阻止了UI。
有没有办法让这些调用在单独的渲染器上运行?
我正在编写一个应用程序,用于从手机中取出屏幕数据,并将一系列图像转换为视频。我的问题是,无论我做什么,openGL调用都会阻止UI线程。
下面我发布了我用来从屏幕上读取像素的代码,然后将它们映射回ByteBuffer,稍后我可以操作它。
我的应用程序采用了GLSurface,我将事件排队到,但是将事件排队到此传递的GLSurface会阻止UI。
我尝试使用以下内容创建一个新的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();
}
});
}
也许你会感到困惑的是,glReadPixels PBO
是一个异步调用,但在所有这些情况下,它实际上阻止了渲染线程很长一段时间。这就是你遇到这些问题的原因。
无论如何,而不是
glReadPixelsPBO
- >glReadPixelsFBO