gbm: Try to re-create resources and commit if restarting the rendering loop fails

This commit is contained in:
Victor Brekenfeld 2020-04-15 23:29:30 +02:00
parent d30bd4555e
commit d3b8563f65
2 changed files with 22 additions and 8 deletions

View File

@ -56,13 +56,23 @@ impl<
for (crtc, backend) in backends.borrow().iter() {
if let Some(backend) = backend.upgrade() {
// restart rendering loop, if it was previously running
if let Some(Err(err)) = backend
.current_frame_buffer
.get()
.map(|fb| backend.crtc.page_flip(fb))
{
warn!(self.logger, "Failed to restart rendering loop. Error: {}", err);
if let Some(fb) = backend.current_frame_buffer.get() {
if let Err(_) = backend.crtc.page_flip(fb) {
// Try more!
if let Err(err) = backend.recreate() {
error!(
self.logger,
"Failed to re-create gbm surface, is the device gone?\n\t{}", err
);
}
if let Err(err) = unsafe { backend.page_flip() } {
warn!(self.logger, "Failed to restart rendering loop. Error: {}", err);
// TODO bubble this up the user somehow
// maybe expose a "running" state from a surface?
}
}
}
// reset cursor
{
use ::drm::control::Device;

View File

@ -91,11 +91,15 @@ impl<D: RawDevice + 'static> GbmSurfaceInternal<D> {
}
pub fn recreate(&self) -> Result<(), Error<<<D as Device>::Surface as Surface>::Error>> {
let (w, h) = self.pending_mode().ok_or(Error::NoModeSet)?.size();
let (w, h) = self
.pending_mode()
.or(self.current_mode())
.ok_or(Error::NoModeSet)?
.size();
// Recreate the surface and the related resources to match the new
// resolution.
debug!(self.logger, "(Re-)Initializing surface for mode: {}:{}", w, h);
debug!(self.logger, "(Re-)Initializing surface (with mode: {}:{})", w, h);
let surface = self
.dev
.borrow_mut()