Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run long task on glThread without blocking UI thread on Android

Tags:

I have to run through a lot of initialisation before I can render anything in my GLSurfaceView

Theses must be done on the OpenGL thread.

However this hangs my main thread for the duration of the initialisation.

Here is my code:

@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);
        /* [...] */
    }
like image 747
Antzi Avatar asked Oct 04 '16 06:10

Antzi


People also ask

Why should you avoid to run non UI code on the main thread?

If you put long running work on the UI thread, you can get ANR errors. If you have multiple threads and put long running work on the non-UI threads, those non-UI threads can't inform the user of what is happening.

What is run on UI thread Android?

User Interface Thread or UI-Thread in Android is a Thread element responsible for updating the layout elements of the application implicitly or explicitly. This means, to update an element or change its attributes in the application layout ie the front-end of the application, one can make use of the UI-Thread.

Is it ever okay block the UI thread?

That's a bad idea, never block the ui thread, instead have a callback you dismiss the dialog with. Your current implementation may generate anr crashes.

Does handler run on UI thread?

A Handler allows communicating back with UI thread from other background thread. This is useful in android as android doesn't allow other threads to communicate directly with UI thread. A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.


1 Answers

I found a solution:

The issue is that you must not block in onDrawFrame or onSurfaceCreated, since they are called synchronously by the main thread.

To disable the calls, I used in my surface constructor:

setRenderMode(RENDERMODE_WHEN_DIRTY);

This way, the calls to onDrawFrame will stop once the view is settled.

I performed the initialisation from

public void onWindowFocusChanged(boolean hasFocus) 

Be careful it can be called twice. If anyone has a better suggestion I'd gladly listen to it (taken from How to make a callback after the view is completely rendered?)

I also overrided

@Override
public boolean isDirty()
   return false;
}

And don't forget to use queueEvent to run code on the GLThread

like image 181
Antzi Avatar answered Sep 24 '22 16:09

Antzi