gbm: cleanup session rendering loop restart

This commit is contained in:
Victor Brekenfeld 2020-04-26 22:37:42 +02:00
parent 5e530b8263
commit 5fb73a497e
1 changed files with 24 additions and 25 deletions

View File

@ -12,6 +12,7 @@ use std::rc::{Rc, Weak};
use super::{GbmDevice, GbmSurfaceInternal}; use super::{GbmDevice, GbmSurfaceInternal};
use crate::backend::drm::{RawDevice, RawSurface}; use crate::backend::drm::{RawDevice, RawSurface};
use crate::backend::graphics::CursorBackend;
use crate::backend::session::{AsSessionObserver, SessionObserver}; use crate::backend::session::{AsSessionObserver, SessionObserver};
/// [`SessionObserver`](SessionObserver) /// [`SessionObserver`](SessionObserver)
@ -27,11 +28,12 @@ pub struct GbmDeviceObserver<
} }
impl< impl<
S: SessionObserver + 'static, O: SessionObserver + 'static,
D: RawDevice + ::drm::control::Device + AsSessionObserver<S> + 'static, S: CursorBackend<CursorFormat=dyn drm::buffer::Buffer> + RawSurface + 'static,
> AsSessionObserver<GbmDeviceObserver<S, D>> for GbmDevice<D> D: RawDevice<Surface=S> + drm::control::Device + AsSessionObserver<O> + 'static,
> AsSessionObserver<GbmDeviceObserver<O, D>> for GbmDevice<D>
{ {
fn observer(&mut self) -> GbmDeviceObserver<S, D> { fn observer(&mut self) -> GbmDeviceObserver<O, D> {
GbmDeviceObserver { GbmDeviceObserver {
observer: (**self.dev.borrow_mut()).observer(), observer: (**self.dev.borrow_mut()).observer(),
backends: Rc::downgrade(&self.backends), backends: Rc::downgrade(&self.backends),
@ -41,9 +43,10 @@ impl<
} }
impl< impl<
S: SessionObserver + 'static, O: SessionObserver + 'static,
D: RawDevice + ::drm::control::Device + AsSessionObserver<S> + 'static, S: CursorBackend<CursorFormat=dyn drm::buffer::Buffer> + RawSurface + 'static,
> SessionObserver for GbmDeviceObserver<S, D> D: RawDevice<Surface=S> + drm::control::Device + AsSessionObserver<O> + 'static,
> SessionObserver for GbmDeviceObserver<O, D>
{ {
fn pause(&mut self, devnum: Option<(u32, u32)>) { fn pause(&mut self, devnum: Option<(u32, u32)>) {
self.observer.pause(devnum); self.observer.pause(devnum);
@ -56,20 +59,19 @@ impl<
for (crtc, backend) in backends.borrow().iter() { for (crtc, backend) in backends.borrow().iter() {
if let Some(backend) = backend.upgrade() { if let Some(backend) = backend.upgrade() {
// restart rendering loop, if it was previously running // restart rendering loop, if it was previously running
if let Some(fb) = backend.current_frame_buffer.get() { if let Some(current_fb) = backend.current_frame_buffer.get() {
if backend.crtc.page_flip(fb).is_err() { let result = if backend.crtc.commit_pending() {
// Try more! backend.crtc.commit(current_fb)
if let Err(err) = backend.recreate() { } else {
error!( RawSurface::page_flip(&backend.crtc, current_fb)
self.logger, };
"Failed to re-create gbm surface, is the device gone?\n\t{}", err
); if let Err(err) = result {
} warn!(
if let Err(err) = unsafe { backend.page_flip() } { self.logger,
warn!(self.logger, "Failed to restart rendering loop. Error: {}", err); "Failed to restart rendering loop. Re-creating resources. Error: {}", err
// TODO bubble this up the user somehow );
// maybe expose a "running" state from a surface? // TODO bubble up
}
} }
} }
@ -79,10 +81,7 @@ impl<
let &(ref cursor, ref hotspot): &(BufferObject<()>, (u32, u32)) = let &(ref cursor, ref hotspot): &(BufferObject<()>, (u32, u32)) =
unsafe { &*backend.cursor.as_ptr() }; unsafe { &*backend.cursor.as_ptr() };
if backend if backend.crtc.set_cursor_representation(cursor, *hotspot)
.dev
.borrow()
.set_cursor2(*crtc, Some(cursor), ((*hotspot).0 as i32, (*hotspot).1 as i32))
.is_err() .is_err()
{ {
if let Err(err) = backend.dev.borrow().set_cursor(*crtc, Some(cursor)) { if let Err(err) = backend.dev.borrow().set_cursor(*crtc, Some(cursor)) {