为什么openGL会阻止UI?

时间:2019-02-11 22:03:28

标签: android opengl-es glsurfaceview

更新#1 我已经实现了一个PBO队列,我循环遍历这些PBO以尝试减少UI滞后。基本上,我绑定到一个PBO,调用glReadPixels,设置一个fence对象,然后等待该对象被发信号。

一直以来,我都通过glReadPixels将更多像素加载到其他PBO中。发出同步对象信号后,我尝试在发出信号的PBO上glMapBufferRange。但是,这仍然阻止了用户界面。

有没有办法让这些调用在单独的渲染器上运行?


我正在编写一个应用程序,以从手机中获取屏幕数据,并将一系列图像转换为视频。我的问题是,无论做什么,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();
        }
    });
}

1 个答案:

答案 0 :(得分:0)

也许您会感到困惑,因为glReadPixels PBO是一个异步调用,但是在所有这些情况下,它实际上会阻塞渲染线程很长时间。这就是为什么您遇到这些问题。

  

无论如何,不​​是glReadPixelsPBO-> glReadPixelsFBO