-
-
Notifications
You must be signed in to change notification settings - Fork 484
Do not panic when swap_buffer (egl) fails #1320
Description
I notices some bug in running on android. When resuming to the app, sometimes the swap_buffer method is throwing an egl error:
... /? E/BufferQueueProducer: [rust.rust_android_example/android.app.NativeActivity#0] queueBuffer: BufferQueue has been abandoned
.../rust.rust_android_example E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -19
.../? E/BufferQueueProducer: [rust.rust_android_example/android.app.NativeActivity#0] dequeueBuffer: BufferQueue has been abandoned
.../rust.rust_android_example E/EGL_emulation: tid 21300: swapBuffers(552): error 0x300d (EGL_BAD_SURFACE)
The problem is located under glutin/src/api/egl/mod.rs line 663:
#[inline]
pub fn swap_buffers(&self) -> Result<(), ContextError> {
let egl = EGL.as_ref().unwrap();
let surface = self.surface.as_ref().unwrap().lock();
if *surface == ffi::egl::NO_SURFACE {
return Err(ContextError::ContextLost);
}
let ret = unsafe { egl.SwapBuffers(self.display, *surface) };
if ret == 0 {
match unsafe { egl.GetError() } as u32 {
ffi::egl::CONTEXT_LOST => {
return Err(ContextError::ContextLost)
}
err => panic!(
"swap_buffers: eglSwapBuffers failed (eglGetError returned 0x{:x})",
err
),
}
} else {
Ok(())
}
}
Calling the panic! kills the app. There is no chance to recover from this state. I noticed, that this problem can easily be fixed by recreating the graphics context. Therefore we need to have a chance to handle that problem:
My simple hack is following:
#[inline]
pub fn swap_buffers(&self) -> Result<(), ContextError> {
let egl = EGL.as_ref().unwrap();
let surface = self.surface.as_ref().unwrap().lock();
if *surface == ffi::egl::NO_SURFACE {
return Err(ContextError::ContextLost);
}
let ret = unsafe { egl.SwapBuffers(self.display, *surface) };
if ret == 0 {
Err(ContextError::ContextLost)
} else {
Ok(())
}
}
This gives me a chance to release all openGL resources, recreate the context, and finally recreate all buffers, and the app keeps running. The user doesn't even notice...
Maybe the problem is lies somewhere else, but calling panic! takes away all possibilities.