From eaa3a0ca87cae2f257cb97d5417b8428bfe5e419 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 16:51:14 +0200 Subject: [PATCH 01/25] egl: fix broken egl check --- src/backend/egl/display.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backend/egl/display.rs b/src/backend/egl/display.rs index baf716b..62f7d7c 100644 --- a/src/backend/egl/display.rs +++ b/src/backend/egl/display.rs @@ -150,7 +150,7 @@ impl> EGLDisplay { }; info!(log, "EGL Extensions: {:?}", extensions); - if egl_version >= (1, 2) { + if egl_version <= (1, 2) { return Err(Error::OpenGlesNotSupported(None)); } wrap_egl_call(|| unsafe { ffi::egl::BindAPI(ffi::egl::OPENGL_ES_API) }) @@ -485,16 +485,17 @@ impl EGLBufferReader { buffer: WlBuffer, ) -> ::std::result::Result { let mut format: i32 = 0; - wrap_egl_call(|| unsafe { + if wrap_egl_call(|| unsafe { ffi::egl::QueryWaylandBufferWL( **self.display, buffer.as_ref().c_ptr() as _, ffi::egl::EGL_TEXTURE_FORMAT, &mut format, ) - }) - .map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?; - + }).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))? == ffi::egl::FALSE { + return Err(BufferAccessError::NotManaged(buffer.clone(), EGLError::BadParameter)); + } + let format = match format { x if x == ffi::egl::TEXTURE_RGB as i32 => Format::RGB, x if x == ffi::egl::TEXTURE_RGBA as i32 => Format::RGBA, @@ -502,7 +503,7 @@ impl EGLBufferReader { ffi::egl::TEXTURE_Y_UV_WL => Format::Y_UV, ffi::egl::TEXTURE_Y_U_V_WL => Format::Y_U_V, ffi::egl::TEXTURE_Y_XUXV_WL => Format::Y_XUXV, - _ => panic!("EGL returned invalid texture type"), + x => panic!("EGL returned invalid texture type: {}", x), }; let mut width: i32 = 0; From 0a716438e394ab9d8018b8b2bed865e7c153cd45 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 16:53:02 +0200 Subject: [PATCH 02/25] gbm: split out clear_framebuffers --- src/backend/drm/gbm/surface.rs | 40 ++++++++++------------------------ 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index 1668d17..80bcaf8 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -106,6 +106,17 @@ impl GbmSurfaceInternal { .map_err(Error::SurfaceCreationFailed)?; // Clean up buffers + self.clear_framebuffers(); + + // Drop the old surface after cleanup + *self.surface.borrow_mut() = surface; + + self.recreated.set(true); + + Ok(()) + } + + pub fn clear_framebuffers(&self) { if let Some(Ok(Some(fb))) = self.next_buffer.take().map(|mut bo| bo.take_userdata()) { if let Err(err) = self.crtc.destroy_framebuffer(fb) { warn!( @@ -123,13 +134,6 @@ impl GbmSurfaceInternal { ); } } - - // Drop the old surface after cleanup - *self.surface.borrow_mut() = surface; - - self.recreated.set(true); - - Ok(()) } } @@ -228,27 +232,7 @@ impl Drop for GbmSurfaceInternal { fn drop(&mut self) { // Drop framebuffers attached to the userdata of the gbm surface buffers. // (They don't implement drop, as they need the device) - if let Ok(Some(fb)) = { - if let Some(mut next) = self.next_buffer.take() { - next.take_userdata() - } else { - Ok(None) - } - } { - // ignore failure at this point - let _ = self.crtc.destroy_framebuffer(fb); - } - - if let Ok(Some(fb)) = { - if let Some(mut next) = self.front_buffer.take() { - next.take_userdata() - } else { - Ok(None) - } - } { - // ignore failure at this point - let _ = self.crtc.destroy_framebuffer(fb); - } + self.clear_framebuffers(); } } From 64fc1aa0da834e93c9cb0d74ad985819f87734c6 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 16:53:44 +0200 Subject: [PATCH 03/25] gbm: do not block buffer forever if commit/page_flip fails --- src/backend/drm/gbm/surface.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index 80bcaf8..74c4898 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -74,18 +74,26 @@ impl GbmSurfaceInternal { }; self.next_buffer.set(Some(next_bo)); - if self.recreated.get() { + let result = if self.recreated.get() { debug!(self.logger, "Commiting new state"); - self.crtc.commit(fb).map_err(Error::Underlying)?; + let res = self.crtc.commit(fb).map_err(Error::Underlying); self.recreated.set(false); + res } else { trace!(self.logger, "Queueing Page flip"); - RawSurface::page_flip(&self.crtc, fb).map_err(Error::Underlying)?; + RawSurface::page_flip(&self.crtc, fb).map_err(Error::Underlying) + }; + + match result { + Ok(_) => { + self.current_frame_buffer.set(Some(fb)); + Ok(()) + }, + Err(err) => { + self.unlock_buffer(); + Err(err) + } } - - self.current_frame_buffer.set(Some(fb)); - - Ok(()) } pub fn recreate(&self) -> Result<(), Error<<::Surface as Surface>::Error>> { From 49215f6a3d9bf472f44ad8d97316b3d82ac96372 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:22:16 +0200 Subject: [PATCH 04/25] gbm: do not implicitly restart rendering loop --- src/backend/drm/gbm/session.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/backend/drm/gbm/session.rs b/src/backend/drm/gbm/session.rs index 0fb6a28..4ae20c8 100644 --- a/src/backend/drm/gbm/session.rs +++ b/src/backend/drm/gbm/session.rs @@ -58,22 +58,7 @@ impl< if let Some(backends) = self.backends.upgrade() { for (crtc, backend) in backends.borrow().iter() { if let Some(backend) = backend.upgrade() { - // restart rendering loop, if it was previously running - if let Some(current_fb) = backend.current_frame_buffer.get() { - let result = if backend.crtc.commit_pending() { - backend.crtc.commit(current_fb) - } else { - RawSurface::page_flip(&backend.crtc, current_fb) - }; - - if let Err(err) = result { - warn!( - self.logger, - "Failed to restart rendering loop. Re-creating resources. Error: {}", err - ); - // TODO bubble up - } - } + backend.clear_framebuffers(); // reset cursor { From 1a5cc599838659ca49def3815dcd25d142f5adac Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:23:12 +0200 Subject: [PATCH 05/25] drm: do not ignore events for inactive devices --- src/backend/drm/atomic/mod.rs | 34 +++++++++++++--------------------- src/backend/drm/legacy/mod.rs | 30 +++++++++++++----------------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/backend/drm/atomic/mod.rs b/src/backend/drm/atomic/mod.rs index 769e653..fa0911b 100644 --- a/src/backend/drm/atomic/mod.rs +++ b/src/backend/drm/atomic/mod.rs @@ -389,29 +389,21 @@ impl Device for AtomicDrmDevice { for event in events { if let Event::PageFlip(event) = event { trace!(self.logger, "Got a page-flip event for crtc ({:?})", event.crtc); - if self.active.load(Ordering::SeqCst) { - if self - .backends - .borrow() - .get(&event.crtc) - .iter() - .flat_map(|x| x.upgrade()) - .next() - .is_some() - { - trace!(self.logger, "Handling event for backend {:?}", event.crtc); - if let Some(handler) = self.handler.as_ref() { - handler.borrow_mut().vblank(event.crtc); - } - } else { - self.backends.borrow_mut().remove(&event.crtc); + if self + .backends + .borrow() + .get(&event.crtc) + .iter() + .flat_map(|x| x.upgrade()) + .next() + .is_some() + { + trace!(self.logger, "Handling event for backend {:?}", event.crtc); + if let Some(handler) = self.handler.as_ref() { + handler.borrow_mut().vblank(event.crtc); } } else { - debug!( - self.logger, - "Device ({:?}) not active. Ignoring PageFlip", - self.dev_path() - ); + self.backends.borrow_mut().remove(&event.crtc); } } else { trace!( diff --git a/src/backend/drm/legacy/mod.rs b/src/backend/drm/legacy/mod.rs index 000b7c6..d99294f 100644 --- a/src/backend/drm/legacy/mod.rs +++ b/src/backend/drm/legacy/mod.rs @@ -306,25 +306,21 @@ impl Device for LegacyDrmDevice { Ok(events) => { for event in events { if let Event::PageFlip(event) = event { - if self.active.load(Ordering::SeqCst) { - if self - .backends - .borrow() - .get(&event.crtc) - .iter() - .flat_map(|x| x.upgrade()) - .next() - .is_some() - { - trace!(self.logger, "Handling event for backend {:?}", event.crtc); - if let Some(handler) = self.handler.as_ref() { - handler.borrow_mut().vblank(event.crtc); - } - } else { - self.backends.borrow_mut().remove(&event.crtc); + if self + .backends + .borrow() + .get(&event.crtc) + .iter() + .flat_map(|x| x.upgrade()) + .next() + .is_some() + { + trace!(self.logger, "Handling event for backend {:?}", event.crtc); + if let Some(handler) = self.handler.as_ref() { + handler.borrow_mut().vblank(event.crtc); } } else { - debug!(self.logger, "Device not active. Ignoring PageFlip"); + self.backends.borrow_mut().remove(&event.crtc); } } else { trace!(self.logger, "Unrelated event"); From 7518f8c0f7cd455a175e8b2c2db26a223af566c6 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Fri, 1 May 2020 01:48:52 +0200 Subject: [PATCH 06/25] anvil: retry initial renderings --- anvil/src/glium_drawer.rs | 30 ++++++-- anvil/src/udev.rs | 143 ++++++++++++++++++++++++++++---------- 2 files changed, 132 insertions(+), 41 deletions(-) diff --git a/anvil/src/glium_drawer.rs b/anvil/src/glium_drawer.rs index 25a03d3..53f77b2 100644 --- a/anvil/src/glium_drawer.rs +++ b/anvil/src/glium_drawer.rs @@ -16,12 +16,12 @@ use smithay::backend::egl::display::EGLBufferReader; use smithay::{ backend::{ egl::{BufferAccessError, EGLImages, Format}, - graphics::{ - gl::GLGraphicsBackend, - glium::{Frame, GliumGraphicsBackend}, - }, + graphics::{gl::GLGraphicsBackend, glium::{GliumGraphicsBackend, Frame}, SwapBuffersError}, + }, + reexports::{ + calloop::LoopHandle, + wayland_server::protocol::{wl_buffer, wl_surface}, }, - reexports::wayland_server::protocol::{wl_buffer, wl_surface}, wayland::{ compositor::{roles::Role, SubsurfaceRole, TraversalAction}, data_device::DnDIconRole, @@ -457,3 +457,23 @@ impl GliumDrawer { self.draw_surface_tree(frame, surface, (x, y), token, screen_dimensions); } } + +pub fn schedule_initial_render(renderer: Rc>, evt_handle: &LoopHandle) { + let mut frame = renderer.draw(); + frame.clear_color(0.8, 0.8, 0.9, 1.0); + if let Err(err) = frame.set_finish() { + match err { + SwapBuffersError::AlreadySwapped => {}, + SwapBuffersError::TemporaryFailure(err) => { + // TODO dont reschedule after 3(?) retries + error!( + renderer.log, + "Failed to submit page_flip: {}", err + ); + let handle = evt_handle.clone(); + evt_handle.insert_idle(move |_| schedule_initial_render(renderer, &handle)); + }, + SwapBuffersError::ContextLost(err) => panic!("Rendering loop lost: {}", err), + } + } +} \ No newline at end of file diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 008c44a..b567e77 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -25,21 +25,25 @@ use smithay::{ legacy::LegacyDrmDevice, DevPath, Device, DeviceHandler, Surface, }, - graphics::CursorBackend, + graphics::{CursorBackend, SwapBuffersError}, libinput::{LibinputInputBackend, LibinputSessionInterface}, session::{ auto::{auto_session_bind, AutoSession}, - notify_multiplexer, AsSessionObserver, Session, SessionNotifier, + notify_multiplexer, AsSessionObserver, Session, SessionNotifier, SessionObserver, }, udev::{primary_gpu, UdevBackend, UdevEvent}, }, reexports::{ - calloop::{generic::Generic, EventLoop, LoopHandle, Source}, - drm::control::{ + calloop::{ + generic::Generic, + timer::{Timer, TimerHandle}, + EventLoop, LoopHandle, Source, + }, + drm::{self, control::{ connector::{Info as ConnectorInfo, State as ConnectorState}, crtc, encoder::Info as EncoderInfo, - }, + }}, image::{ImageBuffer, Rgba}, input::Libinput, nix::{fcntl::OFlag, sys::stat::dev_t}, @@ -57,7 +61,7 @@ use smithay::{ }; use crate::buffer_utils::BufferUtils; -use crate::glium_drawer::GliumDrawer; +use crate::glium_drawer::{GliumDrawer, schedule_initial_render}; use crate::shell::{MyWindowMap, Roles}; use crate::state::AnvilState; @@ -242,8 +246,9 @@ pub fn run_udev( struct BackendData { id: S::Id, + restart_id: S::Id, event_source: Source>, - surfaces: Rc>>>, + surfaces: Rc>>>>, } struct UdevHandlerImpl { @@ -270,7 +275,7 @@ impl UdevHandlerImpl { device: &mut RenderDevice, egl_buffer_reader: Rc>>, logger: &::slog::Logger, - ) -> HashMap> { + ) -> HashMap>> { // Get a set of all modesetting resource handles (excluding planes): let res_handles = device.resource_handles().unwrap(); @@ -304,7 +309,7 @@ impl UdevHandlerImpl { logger.clone(), ); - entry.insert(renderer); + entry.insert(Rc::new(renderer)); break; } } @@ -318,7 +323,7 @@ impl UdevHandlerImpl { pub fn scan_connectors( device: &mut RenderDevice, logger: &::slog::Logger, - ) -> HashMap> { + ) -> HashMap>> { // Get a set of all modesetting resource handles (excluding planes): let res_handles = device.resource_handles().unwrap(); @@ -347,7 +352,7 @@ impl UdevHandlerImpl { let renderer = GliumDrawer::init(device.create_surface(crtc).unwrap(), logger.clone()); - backends.insert(crtc, renderer); + backends.insert(crtc, Rc::new(renderer)); break; } } @@ -417,7 +422,7 @@ impl UdevHandlerImpl { // Set the handler. // Note: if you replicate this (very simple) structure, it is rather easy // to introduce reference cycles with Rc. Be sure about your drop order - device.set_handler(DrmHandlerImpl { + let renderer = Rc::new(DrmRenderer { compositor_token: self.compositor_token, backends: backends.clone(), window_map: self.window_map.clone(), @@ -426,6 +431,8 @@ impl UdevHandlerImpl { dnd_icon: self.dnd_icon.clone(), logger: self.logger.clone(), }); + let restart_id = self.notifier.register(DrmRendererSessionListener { renderer: renderer.clone(), loop_handle: self.loop_handle.clone() }); + device.set_handler(DrmHandlerImpl { renderer, loop_handle: self.loop_handle.clone() }); let device_session_id = self.notifier.register(device.observer()); let dev_id = device.device_id(); @@ -441,17 +448,14 @@ impl UdevHandlerImpl { .unwrap(); // render first frame - { - let mut frame = renderer.draw(); - frame.clear_color(0.8, 0.8, 0.9, 1.0); - frame.finish().unwrap(); - } + schedule_initial_render(renderer.clone(), &self.loop_handle); } self.backends.insert( dev_id, BackendData { id: device_session_id, + restart_id, event_source, surfaces: backends, }, @@ -465,6 +469,7 @@ impl UdevHandlerImpl { let logger = &self.logger; let pointer_image = &self.pointer_image; let egl_buffer_reader = self.egl_buffer_reader.clone(); + let loop_handle = self.loop_handle.clone(); self.loop_handle .with_source(&backend_data.event_source, |source| { let mut backends = backend_data.surfaces.borrow_mut(); @@ -486,11 +491,7 @@ impl UdevHandlerImpl { .unwrap(); // render first frame - { - let mut frame = renderer.draw(); - frame.clear_color(0.8, 0.8, 0.9, 1.0); - frame.finish().unwrap(); - } + schedule_initial_render(renderer.clone(), &loop_handle); } }); } @@ -514,14 +515,48 @@ impl UdevHandlerImpl { } self.notifier.unregister(backend_data.id); + self.notifier.unregister(backend_data.restart_id); debug!(self.logger, "Dropping device"); } } } -pub struct DrmHandlerImpl { +pub struct DrmHandlerImpl { + renderer: Rc, + loop_handle: LoopHandle, +} + +impl DeviceHandler for DrmHandlerImpl { + type Device = RenderDevice; + + fn vblank(&mut self, crtc: crtc::Handle) { + self.renderer.clone().render(crtc, None, Some(&self.loop_handle)) + } + + fn error(&mut self, error: ::Error) { + error!(self.renderer.logger, "{:?}", error); + } +} + +pub struct DrmRendererSessionListener { + renderer: Rc, + loop_handle: LoopHandle, +} + +impl SessionObserver for DrmRendererSessionListener { + fn pause(&mut self, _device: Option<(u32, u32)>) {} + fn activate(&mut self, _device: Option<(u32, u32, Option)>) { + // we want to be called, after all session handling is done (TODO this is not so nice) + let renderer = self.renderer.clone(); + let handle = self.loop_handle.clone(); + self.loop_handle.insert_idle(move |_| renderer.render_all(Some(&handle))); + } +} + + +pub struct DrmRenderer { compositor_token: CompositorToken, - backends: Rc>>>, + backends: Rc>>>>, window_map: Rc>, pointer_location: Rc>, cursor_status: Arc>, @@ -529,10 +564,13 @@ pub struct DrmHandlerImpl { logger: ::slog::Logger, } -impl DeviceHandler for DrmHandlerImpl { - type Device = RenderDevice; - - fn vblank(&mut self, crtc: crtc::Handle) { +impl DrmRenderer { + fn render_all(self: Rc, evt_handle: Option<&LoopHandle>) { + for crtc in self.backends.borrow().keys() { + self.clone().render(*crtc, None, evt_handle); + } + } + fn render(self: Rc, crtc: crtc::Handle, timer: Option, crtc::Handle)>>, evt_handle: Option<&LoopHandle>) { if let Some(drawer) = self.backends.borrow().get(&crtc) { { let (x, y) = *self.pointer_location.borrow(); @@ -577,16 +615,49 @@ impl DeviceHandler for DrmHandlerImpl { } } - if let Err(err) = frame.finish() { - error!(self.logger, "Error during rendering: {:?}", err); + let result = frame.finish(); + if result.is_ok() { + // Send frame events so that client start drawing their next frame + self.window_map.borrow().send_frames(SCOUNTER.next_serial()); } - // Send frame events so that client start drawing their next frame - self.window_map.borrow().send_frames(SCOUNTER.next_serial()); + if let Err(err) = result { + error!(self.logger, "Error during rendering: {:?}", err); + let reschedule = match err { + SwapBuffersError::AlreadySwapped => false, + SwapBuffersError::TemporaryFailure(err) => match err.downcast_ref::() { + Some(&smithay::backend::drm::common::Error::DeviceInactive) => false, + Some(&smithay::backend::drm::common::Error::Access { ref source, .. }) if match source.get_ref() { + drm::SystemError::PermissionDenied => true, + _ => false, + } => false, + _ => true + }, + SwapBuffersError::ContextLost(err) => panic!("Rendering loop lost: {}", err), + }; + + if reschedule { + match (timer, evt_handle) { + (Some(handle), _) => { + let _ = handle.add_timeout(Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), (Rc::downgrade(&self), crtc)); + }, + (None, Some(evt_handle)) => { + let timer = Timer::new().unwrap(); + let handle = timer.handle(); + let _ = handle.add_timeout(Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), (Rc::downgrade(&self), crtc)); + evt_handle.insert_source(timer, |(renderer, crtc), handle, _data| { + if let Some(renderer) = renderer.upgrade() { + renderer.render(crtc, Some(handle.clone()), Option::<&LoopHandle>::None); + } + }).unwrap(); + }, + _ => unreachable!(), + } + } + } else { + // Send frame events so that client start drawing their next frame + self.window_map.borrow().send_frames(SCOUNTER.next_serial()); + } } } - - fn error(&mut self, error: ::Error) { - error!(self.logger, "{:?}", error); - } } From 7bca4639345400c07aa74b1579c30d10fa06a365 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 00:22:35 +0200 Subject: [PATCH 07/25] atomic: do not cache cursor fb info --- src/backend/drm/atomic/surface.rs | 127 ++++++++++++++++-------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 9e467ce..e5f4704 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -22,7 +22,7 @@ use crate::backend::graphics::CursorBackend; pub struct CursorState { position: Cell>, hotspot: Cell<(u32, u32)>, - framebuffer: Cell>, + framebuffer: Cell>, } #[derive(Debug, PartialEq, Eq, Clone)] @@ -610,23 +610,17 @@ impl CursorBackend for AtomicDrmSurfaceInternal { trace!(self.logger, "Setting the new imported cursor"); if let Some(fb) = self.cursor.framebuffer.get().take() { - let _ = self.destroy_framebuffer(fb.handle()); + let _ = self.destroy_framebuffer(fb); } self.cursor.framebuffer.set(Some( - self.get_framebuffer(self.add_planar_framebuffer(buffer, &[0; 4], 0).compat().map_err( + self.add_planar_framebuffer(buffer, &[0; 4], 0).compat().map_err( |source| Error::Access { errmsg: "Failed to import cursor", dev: self.dev_path(), source, }, - )?) - .compat() - .map_err(|source| Error::Access { - errmsg: "Failed to get framebuffer info", - dev: self.dev_path(), - source, - })?, + )?, )); self.cursor.hotspot.set(hotspot); @@ -803,58 +797,69 @@ impl AtomicDrmSurfaceInternal { let cursor_fb = self.cursor.framebuffer.get(); if let (Some(pos), Some(fb)) = (cursor_pos, cursor_fb) { - let hotspot = self.cursor.hotspot.get(); + match self.get_framebuffer(fb).compat().map_err(|source| Error::Access { + errmsg: "Error getting cursor fb", + dev: self.dev_path(), + source, + }) { + Ok(cursor_info) => { + let hotspot = self.cursor.hotspot.get(); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "CRTC_ID")?, - property::Value::CRTC(Some(self.crtc)), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "SRC_X")?, - property::Value::UnsignedRange(0), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "SRC_Y")?, - property::Value::UnsignedRange(0), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "SRC_W")?, - property::Value::UnsignedRange((fb.size().0 as u64) << 16), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "SRC_H")?, - property::Value::UnsignedRange((fb.size().1 as u64) << 16), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "CRTC_X")?, - property::Value::SignedRange(pos.0 as i64 - (hotspot.0 as i64)), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "CRTC_Y")?, - property::Value::SignedRange(pos.1 as i64 - (hotspot.1 as i64)), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "CRTC_W")?, - property::Value::UnsignedRange(fb.size().0 as u64), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "CRTC_H")?, - property::Value::UnsignedRange(fb.size().1 as u64), - ); - req.add_property( - planes.cursor, - self.plane_prop_handle(planes.cursor, "FB_ID")?, - property::Value::Framebuffer(Some(fb.handle())), - ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "CRTC_ID")?, + property::Value::CRTC(Some(self.crtc)), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "SRC_X")?, + property::Value::UnsignedRange(0), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "SRC_Y")?, + property::Value::UnsignedRange(0), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "SRC_W")?, + property::Value::UnsignedRange((cursor_info.size().0 as u64) << 16), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "SRC_H")?, + property::Value::UnsignedRange((cursor_info.size().1 as u64) << 16), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "CRTC_X")?, + property::Value::SignedRange(pos.0 as i64 - (hotspot.0 as i64)), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "CRTC_Y")?, + property::Value::SignedRange(pos.1 as i64 - (hotspot.1 as i64)), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "CRTC_W")?, + property::Value::UnsignedRange(cursor_info.size().0 as u64), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "CRTC_H")?, + property::Value::UnsignedRange(cursor_info.size().1 as u64), + ); + req.add_property( + planes.cursor, + self.plane_prop_handle(planes.cursor, "FB_ID")?, + property::Value::Framebuffer(Some(fb)), + ); + }, + Err(err) => { + warn!(self.logger, "Cursor FB invalid: {}. Skipping.", err); + } + } } Ok(req) From 9bbd9edb0c579f5a43ac0d30f1a09138c9880c44 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Mon, 27 Apr 2020 19:05:00 +0200 Subject: [PATCH 08/25] egl: track backends --- src/backend/drm/egl/mod.rs | 9 ++++++- src/backend/drm/egl/session.rs | 15 ++++++++---- src/backend/drm/egl/surface.rs | 43 ++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/backend/drm/egl/mod.rs b/src/backend/drm/egl/mod.rs index 61614a1..ce68d57 100644 --- a/src/backend/drm/egl/mod.rs +++ b/src/backend/drm/egl/mod.rs @@ -11,7 +11,10 @@ use drm::control::{connector, crtc, encoder, framebuffer, plane, Mode, ResourceHandles}; use drm::SystemError as DrmError; use nix::libc::dev_t; +use std::cell::RefCell; +use std::collections::HashMap; use std::os::unix::io::{AsRawFd, RawFd}; +use std::rc::{Rc, Weak}; #[cfg(feature = "use_system_lib")] use wayland_server::Display; @@ -58,6 +61,7 @@ where logger: ::slog::Logger, default_attributes: GlAttributes, default_requirements: PixelFormatRequirements, + backends: Rc::Surface>>>>>, } impl AsRawFd for EglDevice @@ -125,6 +129,7 @@ where dev: EGLDisplay::new(dev, log.clone()).map_err(Error::EGL)?, default_attributes, default_requirements, + backends: Rc::new(RefCell::new(HashMap::new())), logger: log, }) } @@ -208,7 +213,9 @@ where SurfaceCreationError::NativeSurfaceCreationFailed(err) => Error::Underlying(err), })?; - Ok(EglSurface { context, surface }) + let backend = Rc::new(EglSurfaceInternal { context, surface }); + self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); + Ok(EglSurface(backend)) } fn process_events(&mut self) { diff --git a/src/backend/drm/egl/session.rs b/src/backend/drm/egl/session.rs index ff12afe..e6e4dc2 100644 --- a/src/backend/drm/egl/session.rs +++ b/src/backend/drm/egl/session.rs @@ -4,9 +4,12 @@ //! use drm::control::{connector, crtc, Mode}; +use std::cell::RefCell; +use std::collections::HashMap; use std::os::unix::io::RawFd; +use std::rc::{Rc, Weak}; -use super::EglDevice; +use super::{EglDevice, EglSurfaceInternal}; use crate::backend::drm::{Device, Surface}; use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use crate::backend::session::{AsSessionObserver, SessionObserver}; @@ -14,11 +17,12 @@ use crate::backend::session::{AsSessionObserver, SessionObserver}; /// [`SessionObserver`](SessionObserver) /// linked to the [`EglDevice`](EglDevice) it was /// created from. -pub struct EglDeviceObserver { +pub struct EglDeviceObserver { observer: S, + backends: Weak>>>>, } -impl AsSessionObserver> for EglDevice +impl AsSessionObserver::Surface>> for EglDevice where S: SessionObserver + 'static, B: Backend::Surface> + 'static, @@ -31,14 +35,15 @@ where + 'static, ::Surface: NativeSurface, { - fn observer(&mut self) -> EglDeviceObserver { + fn observer(&mut self) -> EglDeviceObserver::Surface> { EglDeviceObserver { observer: self.dev.borrow_mut().observer(), + backends: Rc::downgrade(&self.backends), } } } -impl SessionObserver for EglDeviceObserver { +impl SessionObserver for EglDeviceObserver { fn pause(&mut self, devnum: Option<(u32, u32)>) { self.observer.pause(devnum); } diff --git a/src/backend/drm/egl/surface.rs b/src/backend/drm/egl/surface.rs index 7bb01c0..a6592a3 100644 --- a/src/backend/drm/egl/surface.rs +++ b/src/backend/drm/egl/surface.rs @@ -12,8 +12,12 @@ use crate::backend::graphics::gl::GLGraphicsBackend; use crate::backend::graphics::PixelFormat; use crate::backend::graphics::{CursorBackend, SwapBuffersError}; +use std::rc::Rc; + /// Egl surface for rendering -pub struct EglSurface +pub struct EglSurface(pub(super) Rc>); + +pub(super) struct EglSurfaceInternal where N: native::NativeSurface + Surface, { @@ -29,41 +33,45 @@ where type Error = Error<::Error>; fn crtc(&self) -> crtc::Handle { - (*self.surface).crtc() + (*self.0.surface).crtc() } fn current_connectors(&self) -> Self::Connectors { - self.surface.current_connectors() + self.0.surface.current_connectors() } fn pending_connectors(&self) -> Self::Connectors { - self.surface.pending_connectors() + self.0.surface.pending_connectors() } fn add_connector(&self, connector: connector::Handle) -> Result<(), Self::Error> { - self.surface.add_connector(connector).map_err(Error::Underlying) + self.0.surface.add_connector(connector).map_err(Error::Underlying) } fn remove_connector(&self, connector: connector::Handle) -> Result<(), Self::Error> { - self.surface + self.0 + .surface .remove_connector(connector) .map_err(Error::Underlying) } fn set_connectors(&self, connectors: &[connector::Handle]) -> Result<(), Self::Error> { - self.surface.set_connectors(connectors).map_err(Error::Underlying) + self.0 + .surface + .set_connectors(connectors) + .map_err(Error::Underlying) } fn current_mode(&self) -> Mode { - self.surface.current_mode() + self.0.surface.current_mode() } fn pending_mode(&self) -> Mode { - self.surface.pending_mode() + self.0.surface.pending_mode() } fn use_mode(&self, mode: Mode) -> Result<(), Self::Error> { - self.surface.use_mode(mode).map_err(Error::Underlying) + self.0.surface.use_mode(mode).map_err(Error::Underlying) } } @@ -75,7 +83,7 @@ where type Error = ::Error; fn set_cursor_position(&self, x: u32, y: u32) -> ::std::result::Result<(), Self::Error> { - self.surface.set_cursor_position(x, y) + self.0.surface.set_cursor_position(x, y) } fn set_cursor_representation( @@ -83,7 +91,7 @@ where buffer: &Self::CursorFormat, hotspot: (u32, u32), ) -> ::std::result::Result<(), Self::Error> { - self.surface.set_cursor_representation(buffer, hotspot) + self.0.surface.set_cursor_representation(buffer, hotspot) } } @@ -94,7 +102,7 @@ where ::Error: Into + 'static, { fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> { - if let Err(err) = self.surface.swap_buffers() { + if let Err(err) = self.0.surface.swap_buffers() { Err(match err.try_into() { Ok(x) => x, Err(x) => x.into(), @@ -114,16 +122,17 @@ where } fn is_current(&self) -> bool { - self.context.is_current() && self.surface.is_current() + self.0.context.is_current() && self.0.surface.is_current() } unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> { - self.context - .make_current_with_surface(&self.surface) + self.0 + .context + .make_current_with_surface(&self.0.surface) .map_err(Into::into) } fn get_pixel_format(&self) -> PixelFormat { - self.surface.get_pixel_format() + self.0.surface.get_pixel_format() } } From f3dabe2cea61ce04f31133584263e789c01e4e58 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:54:29 +0200 Subject: [PATCH 09/25] atomic: clear broken resources on resume --- src/backend/drm/atomic/session.rs | 14 +++++++++++++- src/backend/drm/atomic/surface.rs | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/backend/drm/atomic/session.rs b/src/backend/drm/atomic/session.rs index f5f2b03..47dcb58 100644 --- a/src/backend/drm/atomic/session.rs +++ b/src/backend/drm/atomic/session.rs @@ -16,7 +16,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use super::{AtomicDrmDevice, AtomicDrmSurfaceInternal, Dev}; -use crate::backend::drm::{common::Error, DevPath}; +use crate::backend::drm::{common::Error, DevPath, Surface}; use crate::backend::session::{AsSessionObserver, SessionObserver}; /// [`SessionObserver`](SessionObserver) @@ -164,6 +164,18 @@ impl AtomicDrmDeviceObserver { // lets force a non matching state current.connectors.clear(); current.mode = unsafe { std::mem::zeroed() }; + + // recreate property blob + let mode = { + let pending = surface.pending.read().unwrap(); + pending.mode.clone() + }; + surface.use_mode(mode)?; + + // drop cursor state + surface.cursor.position.set(None); + surface.cursor.hotspot.set((0,0)); + surface.cursor.framebuffer.set(None); } } } diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index e5f4704..f68bd1e 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -20,9 +20,9 @@ use crate::backend::graphics::CursorBackend; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CursorState { - position: Cell>, - hotspot: Cell<(u32, u32)>, - framebuffer: Cell>, + pub position: Cell>, + pub hotspot: Cell<(u32, u32)>, + pub framebuffer: Cell>, } #[derive(Debug, PartialEq, Eq, Clone)] From b4cbecd369c44da7f56ede2308e7d6e6317f7efc Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:55:08 +0200 Subject: [PATCH 10/25] atomic: do not set current state if commit fails --- src/backend/drm/atomic/surface.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index f68bd1e..f65a185 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -528,7 +528,6 @@ impl RawSurface for AtomicDrmSurfaceInternal { warn!(self.logger, "Failed to destory old mode property blob: {}", err); } } - *current = pending.clone(); // new config req @@ -536,7 +535,7 @@ impl RawSurface for AtomicDrmSurfaceInternal { }; debug!(self.logger, "Setting screen: {:?}", req); - self.atomic_commit( + let result = self.atomic_commit( &[ AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::AllowModeset, @@ -549,9 +548,13 @@ impl RawSurface for AtomicDrmSurfaceInternal { errmsg: "Error setting crtc", dev: self.dev_path(), source, - })?; + }); - Ok(()) + if result.is_ok() { + *current = pending.clone(); + } + + result } fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> { From 163533a72a7e11c5835737873920c81406e47bcf Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:55:39 +0200 Subject: [PATCH 11/25] atomic: avoid too excessive trace logging --- src/backend/drm/atomic/surface.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index f65a185..273b18d 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -571,7 +571,7 @@ impl RawSurface for AtomicDrmSurfaceInternal { None, )?; - trace!(self.logger, "Queueing page flip: {:#?}", req); + trace!(self.logger, "Queueing page flip: {:?}", req); self.atomic_commit( &[AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::Nonblock], req, From 140185f6f51b1dbfa6a800b5d6f91876b65074f3 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:56:04 +0200 Subject: [PATCH 12/25] atomic: clear invalid cursor buffers --- src/backend/drm/atomic/surface.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 273b18d..900d6bb 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -861,6 +861,7 @@ impl AtomicDrmSurfaceInternal { }, Err(err) => { warn!(self.logger, "Cursor FB invalid: {}. Skipping.", err); + self.cursor.framebuffer.set(None); } } } From a6863af496eb2ca3f63be601ff55b0f7f9bf8931 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:58:01 +0200 Subject: [PATCH 13/25] egl: force surface creation on resume --- src/backend/drm/egl/session.rs | 12 +++++++++++- src/backend/egl/surface.rs | 12 ++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/backend/drm/egl/session.rs b/src/backend/drm/egl/session.rs index e6e4dc2..5a50247 100644 --- a/src/backend/drm/egl/session.rs +++ b/src/backend/drm/egl/session.rs @@ -11,7 +11,7 @@ use std::rc::{Rc, Weak}; use super::{EglDevice, EglSurfaceInternal}; use crate::backend::drm::{Device, Surface}; -use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; +use crate::backend::egl::{ffi, native::{Backend, NativeDisplay, NativeSurface}}; use crate::backend::session::{AsSessionObserver, SessionObserver}; /// [`SessionObserver`](SessionObserver) @@ -50,5 +50,15 @@ impl SessionObserver f fn activate(&mut self, devnum: Option<(u32, u32, Option)>) { self.observer.activate(devnum); + if let Some(backends) = self.backends.upgrade() { + for (_crtc, backend) in backends.borrow().iter() { + if let Some(backend) = backend.upgrade() { + let old_surface = backend.surface.surface.replace(std::ptr::null()); + if !old_surface.is_null() { + unsafe { ffi::egl::DestroySurface(**backend.surface.display, old_surface as *const _); } + } + } + } + } } } diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 4e175d2..7d911fc 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -12,7 +12,7 @@ use std::{ /// EGL surface of a given EGL context for rendering pub struct EGLSurface { - display: Arc, + pub(crate) display: Arc, native: N, pub(crate) surface: Cell, config_id: ffi::egl::types::EGLConfig, @@ -90,9 +90,7 @@ impl EGLSurface { wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) }) .map_err(SwapBuffersError::EGLSwapBuffers) .and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying)) - } else { - Ok(()) - }; + } else { Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) }; // workaround for missing `PartialEq` impl let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result { @@ -117,9 +115,11 @@ impl EGLSurface { }) .map_err(SwapBuffersError::EGLCreateWindowSurface)? }); - } - result + result.map_err(|_| SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) + } else { + result + } } /// Returns true if the OpenGL surface is the current one in the thread. From 44ebed34466c7874237657728a69074a9e2231dc Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 18:00:24 +0200 Subject: [PATCH 14/25] gbm: only clear recreation state on successful commits --- src/backend/drm/gbm/surface.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index 74c4898..b9b1686 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -74,11 +74,15 @@ impl GbmSurfaceInternal { }; self.next_buffer.set(Some(next_bo)); + if cfg!(debug_assertions) { + if let Err(err) = self.crtc.get_framebuffer(fb) { + error!(self.logger, "Cached framebuffer invalid: {:?}: {}", fb, err); + } + } + let result = if self.recreated.get() { debug!(self.logger, "Commiting new state"); - let res = self.crtc.commit(fb).map_err(Error::Underlying); - self.recreated.set(false); - res + self.crtc.commit(fb).map_err(Error::Underlying) } else { trace!(self.logger, "Queueing Page flip"); RawSurface::page_flip(&self.crtc, fb).map_err(Error::Underlying) @@ -86,6 +90,7 @@ impl GbmSurfaceInternal { match result { Ok(_) => { + self.recreated.set(false); self.current_frame_buffer.set(Some(fb)); Ok(()) }, From 12a57f799aacdeb66d6d193554b030835b42bdb9 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 16:12:20 +0200 Subject: [PATCH 15/25] logind: ignore gone events --- src/backend/session/dbus/logind.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/backend/session/dbus/logind.rs b/src/backend/session/dbus/logind.rs index b049e2a..f12ba64 100644 --- a/src/backend/session/dbus/logind.rs +++ b/src/backend/session/dbus/logind.rs @@ -278,21 +278,36 @@ impl LogindSessionImpl { let (major, minor, pause_type) = message.get3::(); let major = major.ok_or(Error::UnexpectedMethodReturn)?; let minor = minor.ok_or(Error::UnexpectedMethodReturn)?; + // From https://www.freedesktop.org/wiki/Software/systemd/logind/: + // `force` means the device got paused by logind already and this is only an + // asynchronous notification. + // `pause` means logind tries to pause the device and grants you limited amount + // of time to pause it. You must respond to this via PauseDeviceComplete(). + // This synchronous pausing-mechanism is used for backwards-compatibility to VTs + // and logind is **free to not make use of it**. + // It is also free to send a forced PauseDevice if you don't respond in a timely manner + // (or for any other reason). let pause_type = pause_type.ok_or(Error::UnexpectedMethodReturn)?; debug!( self.logger, "Request of type \"{}\" to close device ({},{})", pause_type, major, minor ); - for signal in &mut *self.signals.borrow_mut() { - if let Some(ref mut signal) = signal { - signal.pause(Some((major, minor))); + + // gone means the device was unplugged from the system and you will no longer get any + // notifications about it. + // This is handled via udev and is not part of our session api. + if pause_type != "gone" { + for signal in &mut *self.signals.borrow_mut() { + if let Some(ref mut signal) = signal { + signal.pause(Some((major, minor))); + } } } // the other possible types are "force" or "gone" (unplugged), // both expect no acknowledgement (note even this is not *really* necessary, // logind would just timeout and send a "force" event. There is no way to // keep the device.) - if &*pause_type == "pause" { + if pause_type == "pause" { LogindSessionImpl::blocking_call( &*self.conn.borrow(), "org.freedesktop.login1", From a0c65114fbd26326687d883969d41dc04361e259 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 17:56:43 +0200 Subject: [PATCH 16/25] drm: Do not unpack drm-rs errors on conversion --- src/backend/drm/common/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/drm/common/mod.rs b/src/backend/drm/common/mod.rs index c851e40..cac25f5 100644 --- a/src/backend/drm/common/mod.rs +++ b/src/backend/drm/common/mod.rs @@ -76,7 +76,7 @@ impl Into for Error { fn into(self) -> SwapBuffersError { match self { x @ Error::DeviceInactive => SwapBuffersError::TemporaryFailure(Box::new(x)), - Error::Access { source, .. } + Error::Access { errmsg, dev, source, .. } if match source.get_ref() { drm::SystemError::Unknown { errno: nix::errno::Errno::EBUSY, @@ -87,8 +87,8 @@ impl Into for Error { _ => false, } => { - SwapBuffersError::TemporaryFailure(Box::new(source)) - } + SwapBuffersError::TemporaryFailure(Box::new(Error::Access { errmsg, dev, source })) + }, x => SwapBuffersError::ContextLost(Box::new(x)), } } From 25f2610ea6abe5f445e14c1bca46a9df64b7d579 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 18:10:33 +0200 Subject: [PATCH 17/25] gbm: Do not unpack drm-rs errors on conversion --- src/backend/drm/gbm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/drm/gbm/mod.rs b/src/backend/drm/gbm/mod.rs index d4cc66a..2cd9523 100644 --- a/src/backend/drm/gbm/mod.rs +++ b/src/backend/drm/gbm/mod.rs @@ -274,7 +274,7 @@ where _ => false, } => { - SwapBuffersError::TemporaryFailure(Box::new(x)) + SwapBuffersError::TemporaryFailure(Box::new(Error::::FramebufferCreationFailed(x))) } Error::Underlying(x) => x.into(), x => SwapBuffersError::ContextLost(Box::new(x)), From 20b373470fc4fa03cbeeb6e1b3dfb7bfb0494190 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 18:33:25 +0200 Subject: [PATCH 18/25] drm: permission denied is also temporary --- src/backend/drm/common/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/drm/common/mod.rs b/src/backend/drm/common/mod.rs index cac25f5..ce7f8c2 100644 --- a/src/backend/drm/common/mod.rs +++ b/src/backend/drm/common/mod.rs @@ -78,6 +78,7 @@ impl Into for Error { x @ Error::DeviceInactive => SwapBuffersError::TemporaryFailure(Box::new(x)), Error::Access { errmsg, dev, source, .. } if match source.get_ref() { + drm::SystemError::PermissionDenied => true, drm::SystemError::Unknown { errno: nix::errno::Errno::EBUSY, } => true, From f1c40f7306109ff85f68d79ce8b6cc5f3b42053e Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 3 May 2020 20:28:20 +0200 Subject: [PATCH 19/25] lint: fmt & clippy --- anvil/src/glium_drawer.rs | 22 +++++--- anvil/src/udev.rs | 90 ++++++++++++++++++++---------- src/backend/drm/atomic/session.rs | 6 +- src/backend/drm/atomic/surface.rs | 39 ++++++------- src/backend/drm/common/mod.rs | 25 +++++---- src/backend/drm/egl/mod.rs | 3 +- src/backend/drm/egl/session.rs | 9 ++- src/backend/drm/gbm/surface.rs | 2 +- src/backend/egl/display.rs | 10 ++-- src/backend/egl/surface.rs | 4 +- src/backend/session/dbus/logind.rs | 2 +- 11 files changed, 130 insertions(+), 82 deletions(-) diff --git a/anvil/src/glium_drawer.rs b/anvil/src/glium_drawer.rs index 53f77b2..24f449c 100644 --- a/anvil/src/glium_drawer.rs +++ b/anvil/src/glium_drawer.rs @@ -16,7 +16,11 @@ use smithay::backend::egl::display::EGLBufferReader; use smithay::{ backend::{ egl::{BufferAccessError, EGLImages, Format}, - graphics::{gl::GLGraphicsBackend, glium::{GliumGraphicsBackend, Frame}, SwapBuffersError}, + graphics::{ + gl::GLGraphicsBackend, + glium::{Frame, GliumGraphicsBackend}, + SwapBuffersError, + }, }, reexports::{ calloop::LoopHandle, @@ -458,22 +462,22 @@ impl GliumDrawer { } } -pub fn schedule_initial_render(renderer: Rc>, evt_handle: &LoopHandle) { +pub fn schedule_initial_render( + renderer: Rc>, + evt_handle: &LoopHandle, +) { let mut frame = renderer.draw(); frame.clear_color(0.8, 0.8, 0.9, 1.0); if let Err(err) = frame.set_finish() { match err { - SwapBuffersError::AlreadySwapped => {}, + SwapBuffersError::AlreadySwapped => {} SwapBuffersError::TemporaryFailure(err) => { // TODO dont reschedule after 3(?) retries - error!( - renderer.log, - "Failed to submit page_flip: {}", err - ); + error!(renderer.log, "Failed to submit page_flip: {}", err); let handle = evt_handle.clone(); evt_handle.insert_idle(move |_| schedule_initial_render(renderer, &handle)); - }, + } SwapBuffersError::ContextLost(err) => panic!("Rendering loop lost: {}", err), } } -} \ No newline at end of file +} diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index b567e77..3f1b400 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -39,11 +39,14 @@ use smithay::{ timer::{Timer, TimerHandle}, EventLoop, LoopHandle, Source, }, - drm::{self, control::{ - connector::{Info as ConnectorInfo, State as ConnectorState}, - crtc, - encoder::Info as EncoderInfo, - }}, + drm::{ + self, + control::{ + connector::{Info as ConnectorInfo, State as ConnectorState}, + crtc, + encoder::Info as EncoderInfo, + }, + }, image::{ImageBuffer, Rgba}, input::Libinput, nix::{fcntl::OFlag, sys::stat::dev_t}, @@ -61,7 +64,7 @@ use smithay::{ }; use crate::buffer_utils::BufferUtils; -use crate::glium_drawer::{GliumDrawer, schedule_initial_render}; +use crate::glium_drawer::{schedule_initial_render, GliumDrawer}; use crate::shell::{MyWindowMap, Roles}; use crate::state::AnvilState; @@ -431,8 +434,14 @@ impl UdevHandlerImpl { dnd_icon: self.dnd_icon.clone(), logger: self.logger.clone(), }); - let restart_id = self.notifier.register(DrmRendererSessionListener { renderer: renderer.clone(), loop_handle: self.loop_handle.clone() }); - device.set_handler(DrmHandlerImpl { renderer, loop_handle: self.loop_handle.clone() }); + let restart_id = self.notifier.register(DrmRendererSessionListener { + renderer: renderer.clone(), + loop_handle: self.loop_handle.clone(), + }); + device.set_handler(DrmHandlerImpl { + renderer, + loop_handle: self.loop_handle.clone(), + }); let device_session_id = self.notifier.register(device.observer()); let dev_id = device.device_id(); @@ -532,7 +541,7 @@ impl DeviceHandler for DrmHandlerImpl { fn vblank(&mut self, crtc: crtc::Handle) { self.renderer.clone().render(crtc, None, Some(&self.loop_handle)) } - + fn error(&mut self, error: ::Error) { error!(self.renderer.logger, "{:?}", error); } @@ -549,11 +558,11 @@ impl SessionObserver for DrmRendererSessionListener { // we want to be called, after all session handling is done (TODO this is not so nice) let renderer = self.renderer.clone(); let handle = self.loop_handle.clone(); - self.loop_handle.insert_idle(move |_| renderer.render_all(Some(&handle))); + self.loop_handle + .insert_idle(move |_| renderer.render_all(Some(&handle))); } } - pub struct DrmRenderer { compositor_token: CompositorToken, backends: Rc>>>>, @@ -570,7 +579,12 @@ impl DrmRenderer { self.clone().render(*crtc, None, evt_handle); } } - fn render(self: Rc, crtc: crtc::Handle, timer: Option, crtc::Handle)>>, evt_handle: Option<&LoopHandle>) { + fn render( + self: Rc, + crtc: crtc::Handle, + timer: Option, crtc::Handle)>>, + evt_handle: Option<&LoopHandle>, + ) { if let Some(drawer) = self.backends.borrow().get(&crtc) { { let (x, y) = *self.pointer_location.borrow(); @@ -625,32 +639,50 @@ impl DrmRenderer { error!(self.logger, "Error during rendering: {:?}", err); let reschedule = match err { SwapBuffersError::AlreadySwapped => false, - SwapBuffersError::TemporaryFailure(err) => match err.downcast_ref::() { - Some(&smithay::backend::drm::common::Error::DeviceInactive) => false, - Some(&smithay::backend::drm::common::Error::Access { ref source, .. }) if match source.get_ref() { - drm::SystemError::PermissionDenied => true, - _ => false, - } => false, - _ => true - }, + SwapBuffersError::TemporaryFailure(err) => { + match err.downcast_ref::() { + Some(&smithay::backend::drm::common::Error::DeviceInactive) => false, + Some(&smithay::backend::drm::common::Error::Access { ref source, .. }) + if match source.get_ref() { + drm::SystemError::PermissionDenied => true, + _ => false, + } => + { + false + } + _ => true, + } + } SwapBuffersError::ContextLost(err) => panic!("Rendering loop lost: {}", err), }; if reschedule { match (timer, evt_handle) { (Some(handle), _) => { - let _ = handle.add_timeout(Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), (Rc::downgrade(&self), crtc)); - }, + let _ = handle.add_timeout( + Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), + (Rc::downgrade(&self), crtc), + ); + } (None, Some(evt_handle)) => { let timer = Timer::new().unwrap(); let handle = timer.handle(); - let _ = handle.add_timeout(Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), (Rc::downgrade(&self), crtc)); - evt_handle.insert_source(timer, |(renderer, crtc), handle, _data| { - if let Some(renderer) = renderer.upgrade() { - renderer.render(crtc, Some(handle.clone()), Option::<&LoopHandle>::None); - } - }).unwrap(); - }, + let _ = handle.add_timeout( + Duration::from_millis(1000 /*a seconds*/ / 60 /*refresh rate*/), + (Rc::downgrade(&self), crtc), + ); + evt_handle + .insert_source(timer, |(renderer, crtc), handle, _data| { + if let Some(renderer) = renderer.upgrade() { + renderer.render( + crtc, + Some(handle.clone()), + Option::<&LoopHandle>::None, + ); + } + }) + .unwrap(); + } _ => unreachable!(), } } diff --git a/src/backend/drm/atomic/session.rs b/src/backend/drm/atomic/session.rs index 47dcb58..8f15c13 100644 --- a/src/backend/drm/atomic/session.rs +++ b/src/backend/drm/atomic/session.rs @@ -166,15 +166,15 @@ impl AtomicDrmDeviceObserver { current.mode = unsafe { std::mem::zeroed() }; // recreate property blob - let mode = { + let mode = { let pending = surface.pending.read().unwrap(); - pending.mode.clone() + pending.mode }; surface.use_mode(mode)?; // drop cursor state surface.cursor.position.set(None); - surface.cursor.hotspot.set((0,0)); + surface.cursor.hotspot.set((0, 0)); surface.cursor.framebuffer.set(None); } } diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 900d6bb..723844d 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -535,20 +535,21 @@ impl RawSurface for AtomicDrmSurfaceInternal { }; debug!(self.logger, "Setting screen: {:?}", req); - let result = self.atomic_commit( - &[ - AtomicCommitFlags::PageFlipEvent, - AtomicCommitFlags::AllowModeset, - AtomicCommitFlags::Nonblock, - ], - req, - ) - .compat() - .map_err(|source| Error::Access { - errmsg: "Error setting crtc", - dev: self.dev_path(), - source, - }); + let result = self + .atomic_commit( + &[ + AtomicCommitFlags::PageFlipEvent, + AtomicCommitFlags::AllowModeset, + AtomicCommitFlags::Nonblock, + ], + req, + ) + .compat() + .map_err(|source| Error::Access { + errmsg: "Error setting crtc", + dev: self.dev_path(), + source, + }); if result.is_ok() { *current = pending.clone(); @@ -617,13 +618,13 @@ impl CursorBackend for AtomicDrmSurfaceInternal { } self.cursor.framebuffer.set(Some( - self.add_planar_framebuffer(buffer, &[0; 4], 0).compat().map_err( - |source| Error::Access { + self.add_planar_framebuffer(buffer, &[0; 4], 0) + .compat() + .map_err(|source| Error::Access { errmsg: "Failed to import cursor", dev: self.dev_path(), source, - }, - )?, + })?, )); self.cursor.hotspot.set(hotspot); @@ -858,7 +859,7 @@ impl AtomicDrmSurfaceInternal { self.plane_prop_handle(planes.cursor, "FB_ID")?, property::Value::Framebuffer(Some(fb)), ); - }, + } Err(err) => { warn!(self.logger, "Cursor FB invalid: {}. Skipping.", err); self.cursor.framebuffer.set(None); diff --git a/src/backend/drm/common/mod.rs b/src/backend/drm/common/mod.rs index ce7f8c2..3ee2723 100644 --- a/src/backend/drm/common/mod.rs +++ b/src/backend/drm/common/mod.rs @@ -76,20 +76,21 @@ impl Into for Error { fn into(self) -> SwapBuffersError { match self { x @ Error::DeviceInactive => SwapBuffersError::TemporaryFailure(Box::new(x)), - Error::Access { errmsg, dev, source, .. } - if match source.get_ref() { - drm::SystemError::PermissionDenied => true, - drm::SystemError::Unknown { - errno: nix::errno::Errno::EBUSY, - } => true, - drm::SystemError::Unknown { - errno: nix::errno::Errno::EINTR, - } => true, - _ => false, - } => + Error::Access { + errmsg, dev, source, .. + } if match source.get_ref() { + drm::SystemError::PermissionDenied => true, + drm::SystemError::Unknown { + errno: nix::errno::Errno::EBUSY, + } => true, + drm::SystemError::Unknown { + errno: nix::errno::Errno::EINTR, + } => true, + _ => false, + } => { SwapBuffersError::TemporaryFailure(Box::new(Error::Access { errmsg, dev, source })) - }, + } x => SwapBuffersError::ContextLost(Box::new(x)), } } diff --git a/src/backend/drm/egl/mod.rs b/src/backend/drm/egl/mod.rs index ce68d57..e17ead8 100644 --- a/src/backend/drm/egl/mod.rs +++ b/src/backend/drm/egl/mod.rs @@ -47,6 +47,7 @@ pub enum Error); +type BackendRef = Weak::Surface>>; /// Representation of an egl device to create egl rendering surfaces pub struct EglDevice @@ -61,7 +62,7 @@ where logger: ::slog::Logger, default_attributes: GlAttributes, default_requirements: PixelFormatRequirements, - backends: Rc::Surface>>>>>, + backends: Rc>>>, } impl AsRawFd for EglDevice diff --git a/src/backend/drm/egl/session.rs b/src/backend/drm/egl/session.rs index 5a50247..6a6f2e0 100644 --- a/src/backend/drm/egl/session.rs +++ b/src/backend/drm/egl/session.rs @@ -11,7 +11,10 @@ use std::rc::{Rc, Weak}; use super::{EglDevice, EglSurfaceInternal}; use crate::backend::drm::{Device, Surface}; -use crate::backend::egl::{ffi, native::{Backend, NativeDisplay, NativeSurface}}; +use crate::backend::egl::{ + ffi, + native::{Backend, NativeDisplay, NativeSurface}, +}; use crate::backend::session::{AsSessionObserver, SessionObserver}; /// [`SessionObserver`](SessionObserver) @@ -55,7 +58,9 @@ impl SessionObserver f if let Some(backend) = backend.upgrade() { let old_surface = backend.surface.surface.replace(std::ptr::null()); if !old_surface.is_null() { - unsafe { ffi::egl::DestroySurface(**backend.surface.display, old_surface as *const _); } + unsafe { + ffi::egl::DestroySurface(**backend.surface.display, old_surface as *const _); + } } } } diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index b9b1686..2076905 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -93,7 +93,7 @@ impl GbmSurfaceInternal { self.recreated.set(false); self.current_frame_buffer.set(Some(fb)); Ok(()) - }, + } Err(err) => { self.unlock_buffer(); Err(err) diff --git a/src/backend/egl/display.rs b/src/backend/egl/display.rs index 62f7d7c..4c8462c 100644 --- a/src/backend/egl/display.rs +++ b/src/backend/egl/display.rs @@ -485,17 +485,19 @@ impl EGLBufferReader { buffer: WlBuffer, ) -> ::std::result::Result { let mut format: i32 = 0; - if wrap_egl_call(|| unsafe { + let query = wrap_egl_call(|| unsafe { ffi::egl::QueryWaylandBufferWL( **self.display, buffer.as_ref().c_ptr() as _, ffi::egl::EGL_TEXTURE_FORMAT, &mut format, ) - }).map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))? == ffi::egl::FALSE { - return Err(BufferAccessError::NotManaged(buffer.clone(), EGLError::BadParameter)); + }) + .map_err(|source| BufferAccessError::NotManaged(buffer.clone(), source))?; + if query == ffi::egl::FALSE { + return Err(BufferAccessError::NotManaged(buffer, EGLError::BadParameter)); } - + let format = match format { x if x == ffi::egl::TEXTURE_RGB as i32 => Format::RGB, x if x == ffi::egl::TEXTURE_RGBA as i32 => Format::RGBA, diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 7d911fc..da09e8e 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -90,7 +90,9 @@ impl EGLSurface { wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) }) .map_err(SwapBuffersError::EGLSwapBuffers) .and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying)) - } else { Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) }; + } else { + Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) + }; // workaround for missing `PartialEq` impl let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result { diff --git a/src/backend/session/dbus/logind.rs b/src/backend/session/dbus/logind.rs index f12ba64..6473c25 100644 --- a/src/backend/session/dbus/logind.rs +++ b/src/backend/session/dbus/logind.rs @@ -292,7 +292,7 @@ impl LogindSessionImpl { self.logger, "Request of type \"{}\" to close device ({},{})", pause_type, major, minor ); - + // gone means the device was unplugged from the system and you will no longer get any // notifications about it. // This is handled via udev and is not part of our session api. From 7c4ca4e5247b8659e804f0be98177ef8d694942e Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Tue, 5 May 2020 23:50:02 +0200 Subject: [PATCH 20/25] atomic: do not revert on failing state --- src/backend/drm/atomic/surface.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 723844d..1cdbca5 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -454,7 +454,7 @@ impl RawSurface for AtomicDrmSurfaceInternal { } let mut current = self.state.write().unwrap(); - let mut pending = self.pending.write().unwrap(); + let pending = self.pending.write().unwrap(); debug!( self.logger, @@ -510,18 +510,8 @@ impl RawSurface for AtomicDrmSurfaceInternal { self.logger, "New screen configuration invalid!:\n\t{:#?}\n\t{}\n", req, err ); - info!(self.logger, "Reverting back to last know good state"); - - *pending = current.clone(); - - self.build_request( - &mut [].iter(), - &mut [].iter(), - &self.planes, - Some(framebuffer), - Some(current.mode), - Some(current.blob), - )? + + return Err(err); } else { if current.mode != pending.mode { if let Err(err) = self.dev.destroy_property_blob(current.blob.into()) { From bf3e8b4d1069738597fc6264d50cc1924a91aae4 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 10 May 2020 20:06:10 +0200 Subject: [PATCH 21/25] egl: check for surface creation failure --- src/backend/egl/surface.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index da09e8e..422845d 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -72,6 +72,10 @@ impl EGLSurface { ffi::egl::CreateWindowSurface(**display, config, native.ptr(), surface_attributes.as_ptr()) })?; + if surface == ffi::egl::NO_SURFACE { + return Err(EGLError::BadSurface); + } + Ok(EGLSurface { display, native, From 2128f6884762261c0a706e36fd59b98d35d28ce0 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 10 May 2020 20:08:29 +0200 Subject: [PATCH 22/25] egl: log hidden egl errors --- src/backend/egl/surface.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 422845d..3ba5f32 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -18,6 +18,7 @@ pub struct EGLSurface { config_id: ffi::egl::types::EGLConfig, pixel_format: PixelFormat, surface_attributes: Vec, + logger: ::slog::Logger, } impl Deref for EGLSurface { @@ -83,6 +84,7 @@ impl EGLSurface { config_id: config, pixel_format, surface_attributes, + logger: log, }) } @@ -122,7 +124,10 @@ impl EGLSurface { .map_err(SwapBuffersError::EGLCreateWindowSurface)? }); - result.map_err(|_| SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) + result.map_err(|err| { + debug!(self.logger, "Hiding page-flip error *before* recreation: {}", err); + SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface) + }) } else { result } From 9610f31e44da7e62ff7d185548df128ecdfb4173 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Mon, 11 May 2020 22:22:37 +0200 Subject: [PATCH 23/25] drm: log initial surface parameters --- src/backend/drm/atomic/surface.rs | 7 ++++++- src/backend/drm/legacy/surface.rs | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 1cdbca5..347a0ea 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -66,6 +66,11 @@ impl AtomicDrmSurfaceInternal { connectors: &[connector::Handle], logger: ::slog::Logger, ) -> Result { + info!( + logger, + "Initializing drm surface with mode {:?} and connectors {:?}", mode, connectors + ); + let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access { errmsg: "Error loading crtc info", dev: dev.dev_path(), @@ -510,7 +515,7 @@ impl RawSurface for AtomicDrmSurfaceInternal { self.logger, "New screen configuration invalid!:\n\t{:#?}\n\t{}\n", req, err ); - + return Err(err); } else { if current.mode != pending.mode { diff --git a/src/backend/drm/legacy/surface.rs b/src/backend/drm/legacy/surface.rs index de931da..be2f6f9 100644 --- a/src/backend/drm/legacy/surface.rs +++ b/src/backend/drm/legacy/surface.rs @@ -311,6 +311,11 @@ impl LegacyDrmSurfaceInternal { connectors: &[connector::Handle], logger: ::slog::Logger, ) -> Result, Error> { + info!( + logger, + "Initializing drm surface with mode {:?} and connectors {:?}", mode, connectors + ); + // Try to enumarate the current state to set the initial state variable correctly let crtc_info = dev.get_crtc(crtc).compat().map_err(|source| Error::Access { errmsg: "Error loading crtc info", From 64a57a4cc84134b5b59c383191aadc8ca3e74478 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Tue, 12 May 2020 20:00:45 +0200 Subject: [PATCH 24/25] downgrade some recoverable errors to warnings --- anvil/src/glium_drawer.rs | 2 +- anvil/src/udev.rs | 8 ++++---- src/backend/drm/common/fallback.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/anvil/src/glium_drawer.rs b/anvil/src/glium_drawer.rs index 24f449c..49b7301 100644 --- a/anvil/src/glium_drawer.rs +++ b/anvil/src/glium_drawer.rs @@ -473,7 +473,7 @@ pub fn schedule_initial_render( SwapBuffersError::AlreadySwapped => {} SwapBuffersError::TemporaryFailure(err) => { // TODO dont reschedule after 3(?) retries - error!(renderer.log, "Failed to submit page_flip: {}", err); + warn!(renderer.log, "Failed to submit page_flip: {}", err); let handle = evt_handle.clone(); evt_handle.insert_idle(move |_| schedule_initial_render(renderer, &handle)); } diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 3f1b400..6f54a68 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -380,7 +380,7 @@ impl UdevHandlerImpl { |fd| match FallbackDevice::new(SessionFd(fd), true, self.logger.clone()) { Ok(drm) => Some(drm), Err(err) => { - error!(self.logger, "Skipping drm device, because of error: {}", err); + warn!(self.logger, "Skipping drm device, because of error: {}", err); None } }, @@ -388,14 +388,14 @@ impl UdevHandlerImpl { .and_then(|drm| match GbmDevice::new(drm, self.logger.clone()) { Ok(gbm) => Some(gbm), Err(err) => { - error!(self.logger, "Skipping gbm device, because of error: {}", err); + warn!(self.logger, "Skipping gbm device, because of error: {}", err); None } }) .and_then(|gbm| match EglDevice::new(gbm, self.logger.clone()) { Ok(egl) => Some(egl), Err(err) => { - error!(self.logger, "Skipping egl device, because of error: {}", err); + warn!(self.logger, "Skipping egl device, because of error: {}", err); None } }) @@ -636,7 +636,7 @@ impl DrmRenderer { } if let Err(err) = result { - error!(self.logger, "Error during rendering: {:?}", err); + warn!(self.logger, "Error during rendering: {:?}", err); let reschedule = match err { SwapBuffersError::AlreadySwapped => false, SwapBuffersError::TemporaryFailure(err) => { diff --git a/src/backend/drm/common/fallback.rs b/src/backend/drm/common/fallback.rs index e5d666e..6a47b31 100644 --- a/src/backend/drm/common/fallback.rs +++ b/src/backend/drm/common/fallback.rs @@ -191,7 +191,7 @@ impl FallbackDevice, LegacyDrmD match AtomicDrmDevice::new(fd.clone(), disable_connectors, log.clone()) { Ok(dev) => Ok(FallbackDevice::Preference(dev)), Err(err) => { - error!(log, "Failed to initialize preferred AtomicDrmDevice: {}", err); + warn!(log, "Failed to initialize preferred AtomicDrmDevice: {}", err); info!(log, "Falling back to fallback LegacyDrmDevice"); Ok(FallbackDevice::Fallback(LegacyDrmDevice::new( fd, From 0486c567ac93b7a6ac83570895d1e7a7e3e45046 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Wed, 13 May 2020 18:38:02 +0200 Subject: [PATCH 25/25] fix ci --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 435f365..aea1f8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: override: true - name: System dependencies - run: sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev + run: sudo apt-get update; sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev - name: Test features if: matrix.features != 'all' @@ -100,7 +100,7 @@ jobs: override: true - name: System dependencies - run: sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev + run: sudo apt-get update; sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev - name: Test features if: matrix.features != 'all' @@ -128,7 +128,7 @@ jobs: components: rustfmt, clippy - name: System dependencies - run: sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev + run: sudo apt-get update; sudo apt-get install libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libsystemd-dev libdbus-1-dev - name: Cargo fmt run: cargo fmt --all -- --check