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);
/* [...] */
}
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With