为什么openGL会阻止UI?

问题描述 投票:0回答:1

更新#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();
        }
    });
}
android opengl-es glsurfaceview
1个回答
0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.