From d3b8563f65c76e11effe8caf1e5da5c006d707b9 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Wed, 15 Apr 2020 23:29:30 +0200 Subject: [PATCH] gbm: Try to re-create resources and commit if restarting the rendering loop fails --- src/backend/drm/gbm/session.rs | 22 ++++++++++++++++------ src/backend/drm/gbm/surface.rs | 8 ++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/backend/drm/gbm/session.rs b/src/backend/drm/gbm/session.rs index 5da767c..00d3516 100644 --- a/src/backend/drm/gbm/session.rs +++ b/src/backend/drm/gbm/session.rs @@ -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; diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index 57261c8..11d7bf3 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -91,11 +91,15 @@ impl GbmSurfaceInternal { } pub fn recreate(&self) -> Result<(), Error<<::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()