在Android上在glThread上运行长时间任务而不阻塞UI线程

6

在我的GLSurfaceView中渲染任何内容之前,我必须运行大量的初始化。

这些必须在OpenGL线程上完成。

然而,这会在初始化过程中挂起我的主线程。

以下是我的代码:

@Override
protected void onStart() {
    super.onStart();
    FrameLayout renderingLayout = (FrameLayout) findViewById(R.id.movie_rendering_layout);
    if (renderingLayout != null && mGLView == null) {
        mGLView = new MyGLSurfaceView(getApplicationContext());
        /** [..] **/
        renderingLayout.addView(mGLView, params);
    }
}

/*--------------- OPENGL RELATED ---------------*/

protected class MyGLSurfaceView  extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

    public MyGLSurfaceView(Context context) {
        super(context);
        // Create an OpenGL ES 1.0 context
        setEGLContextClientVersion(1);
        mRenderer = new MyGLRenderer();
        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);
    }
}


protected class MyGLRenderer implements GLSurfaceView.Renderer {
    private int mWidth, mHeight = 0;
    private boolean isFinished = false;


    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
       GLES10.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        init(mMovieIndex, AssetsUtils.getBinPath(getApplicationContext())); // <----- THIS takes long time

    }

    public void onDrawFrame(GL10 pGL10) {

        GLES10.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT);
        /* [...] */
    }
2个回答

4
我找到了一个解决方案:
问题在于你不能在onDrawFrameonSurfaceCreated中阻塞,因为它们是由主线程同步调用的。
为了禁用这些调用,我在我的表面构造函数中使用了以下代码:
setRenderMode(RENDERMODE_WHEN_DIRTY);

这样,一旦视图稳定下来,对onDrawFrame的调用就会停止。
我从中执行了初始化。
public void onWindowFocusChanged(boolean hasFocus) 

要小心,它可能会被调用两次。如果有更好的建议,我很乐意听取(摘自如何在视图完全渲染后进行回调?

我还覆盖了

@Override
public boolean isDirty()
   return false;
}

不要忘记使用queueEvent在GLThread上运行代码。


0

通常的解决方案是在同一共享组中创建两个EGL上下文,每个上下文绑定到一个单独的线程。

渲染循环中的主线程将任何渲染内容呈现到屏幕上,在资源加载期间通常是一些“无聊”的东西 - 即加载图形、进度条等。

第二个线程在后台加载任何大量资源,例如加载纹理文件、模型网格等并上传它们。

一旦加载完成,主线程就可以使用由辅助异步加载线程加载的所有数据资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接