From f17e37465b69b890ad31a4a8d14e29d27d3fa7a3 Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Thu, 22 Nov 2018 10:04:19 +0100 Subject: [PATCH] drm: Remove associated Return type from Device --- src/backend/drm/egl/mod.rs | 51 +++------- src/backend/drm/gbm/egl.rs | 51 +++------- src/backend/drm/gbm/mod.rs | 55 ++++------- src/backend/drm/gbm/session.rs | 17 ++-- src/backend/drm/gbm/surface.rs | 159 ++++++++++++++++++++---------- src/backend/drm/legacy/mod.rs | 21 ++-- src/backend/drm/legacy/session.rs | 4 +- src/backend/drm/legacy/surface.rs | 94 ++++++++++++++++-- src/backend/drm/mod.rs | 13 +-- 9 files changed, 262 insertions(+), 203 deletions(-) diff --git a/src/backend/drm/egl/mod.rs b/src/backend/drm/egl/mod.rs index e4570c4..ccd7fd2 100644 --- a/src/backend/drm/egl/mod.rs +++ b/src/backend/drm/egl/mod.rs @@ -1,8 +1,8 @@ use drm::control::{crtc, Mode}; use std::cell::RefCell; -use std::collections::HashMap; +use std::iter::FromIterator; use std::os::unix::io::{AsRawFd, RawFd}; -use std::rc::{Rc, Weak}; +use std::rc::Rc; use wayland_server::Display; use super::{Device, DeviceHandler, Surface}; @@ -28,7 +28,6 @@ pub struct EglDevice< ::Surface: NativeSurface, { dev: Rc>>, - backends: Rc>>>>, logger: ::slog::Logger, } @@ -85,7 +84,6 @@ where dev: Rc::new(RefCell::new( EGLContext::new(dev, attributes, Default::default(), log.clone()).map_err(Error::from)?, )), - backends: Rc::new(RefCell::new(HashMap::new())), logger: log, }) } @@ -98,36 +96,18 @@ struct InternalDeviceHandler< ::Surface: NativeSurface, { handler: Box> + 'static>, - backends: Weak>>>>, - logger: ::slog::Logger, } impl::Surface> + 'static, D: Device + NativeDisplay + 'static> DeviceHandler for InternalDeviceHandler where - >::Arguments: From<( - crtc::Handle, - Mode, - <::Surface as Surface>::Connectors, - )>, + >::Arguments: From<(crtc::Handle, Mode, Vec)>, ::Surface: NativeSurface, { type Device = D; - fn vblank(&mut self, surface: &::Surface) { - if let Some(backends) = self.backends.upgrade() { - if let Some(surface) = backends.borrow().get(&surface.crtc()) { - if let Some(surface) = surface.upgrade() { - self.handler.vblank(&*surface); - } - } else { - warn!( - self.logger, - "Surface ({:?}) not managed by egl, event not handled.", - surface.crtc() - ); - } - } + fn vblank(&mut self, crtc: crtc::Handle) { + self.handler.vblank(crtc) } fn error(&mut self, error: <::Surface as Surface>::Error) { self.handler @@ -138,21 +118,14 @@ where impl::Surface> + 'static, D: Device + NativeDisplay + 'static> Device for EglDevice where - >::Arguments: From<( - crtc::Handle, - Mode, - <::Surface as Surface>::Connectors, - )>, + >::Arguments: From<(crtc::Handle, Mode, Vec)>, ::Surface: NativeSurface, { type Surface = EglSurface; - type Return = Rc>; fn set_handler(&mut self, handler: impl DeviceHandler + 'static) { self.dev.borrow_mut().set_handler(InternalDeviceHandler { handler: Box::new(handler), - backends: Rc::downgrade(&self.backends), - logger: self.logger.clone(), }); } @@ -164,21 +137,19 @@ where &mut self, crtc: crtc::Handle, mode: Mode, - connectors: impl Into<<::Surface as Surface>::Connectors>, - ) -> Result>> { + connectors: impl IntoIterator, + ) -> Result> { info!(self.logger, "Initializing EglSurface"); let surface = self .dev .borrow_mut() - .create_surface((crtc, mode, connectors.into()).into())?; + .create_surface((crtc, mode, Vec::from_iter(connectors)).into())?; - let backend = Rc::new(EglSurface { + Ok(EglSurface { dev: self.dev.clone(), surface, - }); - self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); - Ok(backend) + }) } fn process_events(&mut self) { diff --git a/src/backend/drm/gbm/egl.rs b/src/backend/drm/gbm/egl.rs index edac7ec..742f66b 100644 --- a/src/backend/drm/gbm/egl.rs +++ b/src/backend/drm/gbm/egl.rs @@ -1,4 +1,4 @@ -use backend::drm::{Device, RawDevice, RawSurface, Surface}; +use backend::drm::{connector, Device, RawDevice, RawSurface, Surface}; use backend::egl::error::Result as EglResult; use backend::egl::ffi; use backend::egl::native::{Backend, NativeDisplay, NativeSurface}; @@ -9,23 +9,17 @@ use super::{GbmDevice, GbmSurface}; use drm::control::{crtc, Device as ControlDevice, Mode}; use gbm::AsRaw; +use std::iter::{FromIterator, IntoIterator}; use std::marker::PhantomData; use std::ptr; -use std::rc::Rc; /// Gbm backend type -pub struct Gbm -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +pub struct Gbm { _userdata: PhantomData, } -impl Backend for Gbm -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ - type Surface = Rc>; +impl Backend for Gbm { + type Surface = GbmSurface; unsafe fn get_display( display: ffi::NativeDisplayType, @@ -52,37 +46,27 @@ where } /// Arguments necessary to construct a `GbmSurface` -pub struct SurfaceArguments -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +pub struct SurfaceArguments { /// Crtc pub crtc: crtc::Handle, /// Mode pub mode: Mode, /// Connectors - pub connectors: as Surface>::Connectors, + pub connectors: Vec, } -impl From<(crtc::Handle, Mode, as Surface>::Connectors)> - for SurfaceArguments -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ - fn from((crtc, mode, connectors): (crtc::Handle, Mode, as Surface>::Connectors)) -> Self { +impl From<(crtc::Handle, Mode, Vec)> for SurfaceArguments { + fn from((crtc, mode, connectors): (crtc::Handle, Mode, Vec)) -> Self { SurfaceArguments { crtc, mode, - connectors, + connectors: Vec::from_iter(connectors), } } } -unsafe impl NativeDisplay> for GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ - type Arguments = SurfaceArguments; +unsafe impl NativeDisplay> for GbmDevice { + type Arguments = SurfaceArguments; type Error = Error; fn is_backend(&self) -> bool { @@ -93,24 +77,21 @@ where Ok(self.dev.borrow().as_raw() as *const _) } - fn create_surface(&mut self, args: SurfaceArguments) -> Result>> { + fn create_surface(&mut self, args: SurfaceArguments) -> Result> { Device::create_surface(self, args.crtc, args.mode, args.connectors) } } -unsafe impl NativeSurface for Rc> -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +unsafe impl NativeSurface for GbmSurface { fn ptr(&self) -> ffi::NativeWindowType { - self.surface.borrow().as_raw() as *const _ + self.0.surface.borrow().as_raw() as *const _ } fn swap_buffers(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError> where F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>, { - if ::std::borrow::Borrow::borrow(&self.crtc).commit_pending() { + if self.0.crtc.commit_pending() { self.recreate(flip).map_err(|_| SwapBuffersError::ContextLost) } else { self.page_flip(flip) diff --git a/src/backend/drm/gbm/mod.rs b/src/backend/drm/gbm/mod.rs index d13f06a..212d8e1 100644 --- a/src/backend/drm/gbm/mod.rs +++ b/src/backend/drm/gbm/mod.rs @@ -1,6 +1,6 @@ use super::{Device, DeviceHandler, RawDevice, Surface}; -use drm::control::{crtc, framebuffer, Device as ControlDevice, Mode}; +use drm::control::{connector, crtc, framebuffer, Device as ControlDevice, Mode}; use gbm::{self, BufferObjectFlags, Format as GbmFormat}; use std::cell::{Cell, RefCell}; @@ -14,6 +14,7 @@ use self::error::*; mod surface; pub use self::surface::GbmSurface; +use self::surface::GbmSurfaceInternal; pub mod egl; @@ -23,19 +24,13 @@ pub mod session; static LOAD: Once = ONCE_INIT; /// Representation of an open gbm device to create rendering backends -pub struct GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +pub struct GbmDevice { pub(self) dev: Rc>>, - backends: Rc>>>>, + backends: Rc>>>>, logger: ::slog::Logger, } -impl GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl GbmDevice { /// Create a new `GbmDevice` from an open drm node /// /// Returns an error if the file is no valid drm node or context creation was not @@ -73,33 +68,26 @@ where } } -struct InternalDeviceHandler -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +struct InternalDeviceHandler { handler: Box> + 'static>, - backends: Weak>>>>, + backends: Weak>>>>, logger: ::slog::Logger, } -impl DeviceHandler for InternalDeviceHandler -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl DeviceHandler for InternalDeviceHandler { type Device = D; - fn vblank(&mut self, surface: &::Surface) { + fn vblank(&mut self, crtc: crtc::Handle) { if let Some(backends) = self.backends.upgrade() { - if let Some(surface) = backends.borrow().get(&surface.crtc()) { + if let Some(surface) = backends.borrow().get(&crtc) { if let Some(surface) = surface.upgrade() { surface.unlock_buffer(); - self.handler.vblank(&*surface); + self.handler.vblank(crtc); } } else { warn!( self.logger, - "Surface ({:?}) not managed by gbm, event not handled.", - surface.crtc() + "Surface ({:?}) not managed by gbm, event not handled.", crtc ); } } @@ -110,12 +98,8 @@ where } } -impl Device for GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl Device for GbmDevice { type Surface = GbmSurface; - type Return = Rc>; fn set_handler(&mut self, handler: impl DeviceHandler + 'static) { self.dev.borrow_mut().set_handler(InternalDeviceHandler { @@ -133,8 +117,8 @@ where &mut self, crtc: crtc::Handle, mode: Mode, - connectors: impl Into<::Connectors>, - ) -> Result>> { + connectors: impl IntoIterator, + ) -> Result> { info!(self.logger, "Initializing GbmSurface"); let (w, h) = mode.size(); @@ -173,7 +157,7 @@ where (0, 0), )); - let backend = Rc::new(GbmSurface { + let backend = Rc::new(GbmSurfaceInternal { dev: self.dev.clone(), surface: RefCell::new(surface), crtc: Device::create_surface(&mut **self.dev.borrow_mut(), crtc, mode, connectors) @@ -185,7 +169,7 @@ where logger: self.logger.new(o!("crtc" => format!("{:?}", crtc))), }); self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); - Ok(backend) + Ok(GbmSurface(backend)) } fn process_events(&mut self) { @@ -193,10 +177,7 @@ where } } -impl AsRawFd for GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl AsRawFd for GbmDevice { fn as_raw_fd(&self) -> RawFd { self.dev.borrow().as_raw_fd() } diff --git a/src/backend/drm/gbm/session.rs b/src/backend/drm/gbm/session.rs index 70b1059..ffb1948 100644 --- a/src/backend/drm/gbm/session.rs +++ b/src/backend/drm/gbm/session.rs @@ -5,26 +5,22 @@ use std::collections::HashMap; use std::os::unix::io::RawFd; use std::rc::{Rc, Weak}; -use super::{GbmDevice, GbmSurface}; -use backend::drm::{Device, RawDevice, RawSurface}; +use super::{GbmDevice, GbmSurfaceInternal}; +use backend::drm::{RawDevice, RawSurface}; use backend::session::{AsSessionObserver, SessionObserver}; /// `SessionObserver` linked to the `DrmDevice` it was created from. pub struct GbmDeviceObserver< S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver + 'static, -> where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +> { observer: S, - backends: Weak>>>>, + backends: Weak>>>>, logger: ::slog::Logger, } impl + 'static> AsSessionObserver> for GbmDevice -where - ::Return: ::std::borrow::Borrow<::Surface>, { fn observer(&mut self) -> GbmDeviceObserver { GbmDeviceObserver { @@ -37,8 +33,6 @@ where impl + 'static> SessionObserver for GbmDeviceObserver -where - ::Return: ::std::borrow::Borrow<::Surface>, { fn pause(&mut self, devnum: Option<(u32, u32)>) { self.observer.pause(devnum); @@ -51,7 +45,8 @@ where for (crtc, backend) in backends.borrow().iter() { if let Some(backend) = backend.upgrade() { // restart rendering loop - if let Err(err) = ::std::borrow::Borrow::borrow(&backend.crtc) + if let Err(err) = &backend + .crtc .page_flip(backend.current_frame_buffer.get().handle()) { warn!(self.logger, "Failed to restart rendering loop. Error: {}", err); diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index f8ab680..bff5f2c 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -1,7 +1,7 @@ use super::super::{Device, RawDevice, RawSurface, Surface}; use super::error::*; -use drm::control::{connector, crtc, framebuffer, Mode, ResourceInfo}; +use drm::control::{connector, crtc, framebuffer, Mode, ResourceHandles, ResourceInfo}; use gbm::{self, BufferObject, BufferObjectFlags, Format as GbmFormat, SurfaceBufferHandle}; use image::{ImageBuffer, Rgba}; @@ -9,17 +9,14 @@ use std::cell::{Cell, RefCell}; use std::os::unix::io::AsRawFd; use std::rc::Rc; -use backend::drm::legacy::{LegacyDrmDevice, LegacyDrmSurface}; +use backend::drm::legacy::LegacyDrmDevice; use backend::graphics::CursorBackend; use backend::graphics::SwapBuffersError; -pub struct GbmSurface -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +pub(super) struct GbmSurfaceInternal { pub(super) dev: Rc>>, pub(super) surface: RefCell>, - pub(super) crtc: ::Return, + pub(super) crtc: ::Surface, pub(super) cursor: Cell<(BufferObject<()>, (u32, u32))>, pub(super) current_frame_buffer: Cell, pub(super) front_buffer: Cell>, @@ -27,10 +24,7 @@ where pub(super) logger: ::slog::Logger, } -impl GbmSurface -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl GbmSurfaceInternal { pub(super) fn unlock_buffer(&self) { // after the page swap is finished we need to release the rendered buffer. // this is called from the PageFlipHandler @@ -79,15 +73,14 @@ where let fb = if let Some(info) = maybe_fb { info } else { - let fb = framebuffer::create(::std::borrow::Borrow::borrow(&self.crtc), &*next_bo) - .map_err(|_| SwapBuffersError::ContextLost)?; + let fb = framebuffer::create(&self.crtc, &*next_bo).map_err(|_| SwapBuffersError::ContextLost)?; next_bo.set_userdata(fb).unwrap(); fb }; self.next_buffer.set(Some(next_bo)); trace!(self.logger, "Queueing Page flip"); - ::std::borrow::Borrow::borrow(&self.crtc).page_flip(fb.handle())?; + self.crtc.page_flip(fb.handle())?; self.current_frame_buffer.set(fb); @@ -119,9 +112,7 @@ where { if let Some(mut old_bo) = self.next_buffer.take() { if let Ok(Some(fb)) = old_bo.take_userdata() { - if let Err(err) = - framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle()) - { + if let Err(err) = framebuffer::destroy(&self.crtc, fb.handle()) { warn!( self.logger, "Error releasing old back_buffer framebuffer: {:?}", err @@ -141,10 +132,10 @@ where debug!(self.logger, "FrontBuffer color format: {:?}", front_bo.format()); // we also need a new framebuffer for the front buffer - let fb = framebuffer::create(::std::borrow::Borrow::borrow(&self.crtc), &*front_bo) + let fb = framebuffer::create(&self.crtc, &*front_bo) .chain_err(|| ErrorKind::UnderlyingBackendError)?; - ::std::borrow::Borrow::borrow(&self.crtc) + self.crtc .commit(fb.handle()) .chain_err(|| ErrorKind::UnderlyingBackendError)?; @@ -152,7 +143,7 @@ where front_bo }); if let Ok(Some(fb)) = old_front_bo.take_userdata() { - if let Err(err) = framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle()) { + if let Err(err) = framebuffer::destroy(&self.crtc, fb.handle()) { warn!( self.logger, "Error releasing old front_buffer framebuffer: {:?}", err @@ -167,47 +158,44 @@ where } } -impl Surface for GbmSurface -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +impl Surface for GbmSurfaceInternal { type Connectors = <::Surface as Surface>::Connectors; type Error = Error; fn crtc(&self) -> crtc::Handle { - ::std::borrow::Borrow::borrow(&self.crtc).crtc() + self.crtc.crtc() } fn current_connectors(&self) -> Self::Connectors { - ::std::borrow::Borrow::borrow(&self.crtc).current_connectors() + self.crtc.current_connectors() } fn pending_connectors(&self) -> Self::Connectors { - ::std::borrow::Borrow::borrow(&self.crtc).pending_connectors() + self.crtc.pending_connectors() } fn add_connector(&self, connector: connector::Handle) -> Result<()> { - ::std::borrow::Borrow::borrow(&self.crtc) + self.crtc .add_connector(connector) .chain_err(|| ErrorKind::UnderlyingBackendError) } fn remove_connector(&self, connector: connector::Handle) -> Result<()> { - ::std::borrow::Borrow::borrow(&self.crtc) + self.crtc .remove_connector(connector) .chain_err(|| ErrorKind::UnderlyingBackendError) } fn current_mode(&self) -> Mode { - ::std::borrow::Borrow::borrow(&self.crtc).current_mode() + self.crtc.current_mode() } fn pending_mode(&self) -> Mode { - ::std::borrow::Borrow::borrow(&self.crtc).pending_mode() + self.crtc.pending_mode() } fn use_mode(&self, mode: Mode) -> Result<()> { - ::std::borrow::Borrow::borrow(&self.crtc) + self.crtc .use_mode(mode) .chain_err(|| ErrorKind::UnderlyingBackendError) } @@ -218,9 +206,8 @@ where // Option 1: When there is GAT support, impl `GraphicsBackend` for `LegacyDrmBackend` // using a new generic `B: Buffer` and use this: /* -impl<'a, D: RawDevice + 'static> CursorBackend<'a> for GbmSurface +impl<'a, D: RawDevice + 'static> CursorBackend<'a> for GbmSurfaceInternal where - ::Return: ::std::borrow::Borrow<::Surface>, ::Surface: CursorBackend<'a>, <::Surface as CursorBackend<'a>>::CursorFormat: Buffer, <::Surface as CursorBackend<'a>>::Error: ::std::error::Error + Send @@ -229,9 +216,8 @@ where // // Option 2: When equality checks in where clauses are supported, we could at least do this: /* -impl<'a, D: RawDevice + 'static> GraphicsBackend<'a> for GbmSurface +impl<'a, D: RawDevice + 'static> GraphicsBackend<'a> for GbmSurfaceInternal where - ::Return: ::std::borrow::Borrow<::Surface>, ::Surface: CursorBackend<'a>, <::Surface as CursorBackend<'a>>::CursorFormat=&'a Buffer, <::Surface as CursorBackend<'a>>::Error: ::std::error::Error + Send @@ -239,15 +225,14 @@ where */ // But for now got to do this: -impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface> { +impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurfaceInternal> { type CursorFormat = &'a ImageBuffer, Vec>; type Error = Error; fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> { - ResultExt::chain_err( - ::std::borrow::Borrow::>>::borrow(&self.crtc).set_cursor_position(x, y), - || ErrorKind::UnderlyingBackendError, - ) + ResultExt::chain_err(self.crtc.set_cursor_position(x, y), || { + ErrorKind::UnderlyingBackendError + }) } fn set_cursor_representation<'b>( @@ -279,11 +264,9 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface>>::borrow(&self.crtc) - .set_cursor_representation(&cursor, hotspot), - || ErrorKind::UnderlyingBackendError, - )?; + ResultExt::chain_err(self.crtc.set_cursor_representation(&cursor, hotspot), || { + ErrorKind::UnderlyingBackendError + })?; // and store it self.cursor.set((cursor, hotspot)); @@ -291,10 +274,7 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface Drop for GbmSurface -where - ::Return: ::std::borrow::Borrow<::Surface>, -{ +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) @@ -308,12 +288,87 @@ where } } { // ignore failure at this point - let _ = framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle()); + let _ = framebuffer::destroy(&self.crtc, fb.handle()); } if let Ok(Some(fb)) = self.front_buffer.get_mut().take_userdata() { // ignore failure at this point - let _ = framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle()); + let _ = framebuffer::destroy(&self.crtc, fb.handle()); } } } + +pub struct GbmSurface(pub(super) Rc>); + +impl GbmSurface { + pub fn page_flip(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError> + where + F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>, + { + self.0.page_flip(flip) + } + + pub fn recreate(&self, flip: F) -> Result<()> + where + F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>, + { + self.0.recreate(flip) + } +} + +impl Surface for GbmSurface { + type Connectors = <::Surface as Surface>::Connectors; + type Error = Error; + + fn crtc(&self) -> crtc::Handle { + self.0.crtc() + } + + fn current_connectors(&self) -> Self::Connectors { + self.0.current_connectors() + } + + fn pending_connectors(&self) -> Self::Connectors { + self.0.pending_connectors() + } + + fn add_connector(&self, connector: connector::Handle) -> Result<()> { + self.0.add_connector(connector) + } + + fn remove_connector(&self, connector: connector::Handle) -> Result<()> { + self.0.remove_connector(connector) + } + + fn current_mode(&self) -> Mode { + self.0.current_mode() + } + + fn pending_mode(&self) -> Mode { + self.0.pending_mode() + } + + fn use_mode(&self, mode: Mode) -> Result<()> { + self.0.use_mode(mode) + } +} + +impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface> { + type CursorFormat = &'a ImageBuffer, Vec>; + type Error = Error; + + fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> { + self.0.set_cursor_position(x, y) + } + + fn set_cursor_representation<'b>( + &'b self, + buffer: &ImageBuffer, Vec>, + hotspot: (u32, u32), + ) -> Result<()> + where + 'a: 'b, + { + self.0.set_cursor_representation(buffer, hotspot) + } +} diff --git a/src/backend/drm/legacy/mod.rs b/src/backend/drm/legacy/mod.rs index 1bea1ad..bb2e50a 100644 --- a/src/backend/drm/legacy/mod.rs +++ b/src/backend/drm/legacy/mod.rs @@ -7,6 +7,7 @@ use nix::sys::stat::fstat; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; +use std::iter::FromIterator; use std::os::unix::io::{AsRawFd, RawFd}; use std::rc::{Rc, Weak}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -14,7 +15,7 @@ use std::sync::{Arc, RwLock}; mod surface; pub use self::surface::LegacyDrmSurface; -use self::surface::State; +use self::surface::{LegacyDrmSurfaceInternal, State}; pub mod error; use self::error::*; @@ -28,7 +29,7 @@ pub struct LegacyDrmDevice { priviledged: bool, active: Arc, old_state: HashMap)>, - backends: Rc>>>>, + backends: Rc>>>>, handler: Option>>>>, logger: ::slog::Logger, } @@ -120,7 +121,6 @@ impl ControlDevice for LegacyDrmDevice {} impl Device for LegacyDrmDevice { type Surface = LegacyDrmSurface; - type Return = Rc>; fn set_handler(&mut self, handler: impl DeviceHandler + 'static) { self.handler = Some(RefCell::new(Box::new(handler))); @@ -134,8 +134,8 @@ impl Device for LegacyDrmDevice { &mut self, crtc: crtc::Handle, mode: Mode, - connectors: impl Into<::Connectors>, - ) -> Result>> { + connectors: impl IntoIterator, + ) -> Result> { if self.backends.borrow().contains_key(&crtc) { bail!(ErrorKind::CrtcAlreadyInUse(crtc)); } @@ -144,7 +144,7 @@ impl Device for LegacyDrmDevice { bail!(ErrorKind::DeviceInactive); } - let connectors: HashSet<_> = connectors.into(); + let connectors = HashSet::from_iter(connectors); // check if we have an encoder for every connector and the mode mode for connector in &connectors { let con_info = connector::Info::load_from_device(self, *connector).chain_err(|| { @@ -184,7 +184,7 @@ impl Device for LegacyDrmDevice { let state = State { mode, connectors }; - let backend = Rc::new(LegacyDrmSurface { + let backend = Rc::new(LegacyDrmSurfaceInternal { dev: self.dev.clone(), crtc, state: RwLock::new(state.clone()), @@ -193,7 +193,7 @@ impl Device for LegacyDrmDevice { }); self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); - Ok(backend) + Ok(LegacyDrmSurface(backend)) } fn process_events(&mut self) { @@ -201,17 +201,18 @@ impl Device for LegacyDrmDevice { Ok(events) => for event in events { if let crtc::Event::PageFlip(event) = event { if self.active.load(Ordering::SeqCst) { - if let Some(backend) = self + 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(&backend); + handler.borrow_mut().vblank(event.crtc); } } else { self.backends.borrow_mut().remove(&event.crtc); diff --git a/src/backend/drm/legacy/session.rs b/src/backend/drm/legacy/session.rs index dc319c0..5d00f0a 100644 --- a/src/backend/drm/legacy/session.rs +++ b/src/backend/drm/legacy/session.rs @@ -9,7 +9,7 @@ use std::rc::{Rc, Weak}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use super::{Dev, LegacyDrmDevice, LegacyDrmSurface}; +use super::{Dev, LegacyDrmDevice, LegacyDrmSurfaceInternal}; use backend::session::{AsSessionObserver, SessionObserver}; /// `SessionObserver` linked to the `DrmDevice` it was created from. @@ -19,7 +19,7 @@ pub struct LegacyDrmDeviceObserver { priviledged: bool, active: Arc, old_state: HashMap)>, - backends: Weak>>>>, + backends: Weak>>>>, logger: ::slog::Logger, } diff --git a/src/backend/drm/legacy/surface.rs b/src/backend/drm/legacy/surface.rs index 6b6d021..36a58d7 100644 --- a/src/backend/drm/legacy/surface.rs +++ b/src/backend/drm/legacy/surface.rs @@ -19,7 +19,7 @@ pub struct State { pub connectors: HashSet, } -pub struct LegacyDrmSurface { +pub(super) struct LegacyDrmSurfaceInternal { pub(super) dev: Rc>, pub(super) crtc: crtc::Handle, pub(super) state: RwLock, @@ -27,16 +27,16 @@ pub struct LegacyDrmSurface { pub(super) logger: ::slog::Logger, } -impl AsRawFd for LegacyDrmSurface { +impl AsRawFd for LegacyDrmSurfaceInternal { fn as_raw_fd(&self) -> RawFd { self.dev.as_raw_fd() } } -impl BasicDevice for LegacyDrmSurface {} -impl ControlDevice for LegacyDrmSurface {} +impl BasicDevice for LegacyDrmSurfaceInternal {} +impl ControlDevice for LegacyDrmSurfaceInternal {} -impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface { +impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurfaceInternal { type CursorFormat = &'a Buffer; type Error = Error; @@ -61,7 +61,7 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface { } } -impl Surface for LegacyDrmSurface { +impl Surface for LegacyDrmSurfaceInternal { type Error = Error; type Connectors = HashSet; @@ -149,7 +149,7 @@ impl Surface for LegacyDrmSurface { } } -impl RawSurface for LegacyDrmSurface { +impl RawSurface for LegacyDrmSurfaceInternal { fn commit_pending(&self) -> bool { *self.pending.read().unwrap() != *self.state.read().unwrap() } @@ -220,9 +220,87 @@ impl RawSurface for LegacyDrmSurface { } } -impl Drop for LegacyDrmSurface { +impl Drop for LegacyDrmSurfaceInternal { fn drop(&mut self) { // ignore failure at this point let _ = crtc::clear_cursor(self, self.crtc); } } + +pub struct LegacyDrmSurface(pub(super) Rc>); + +impl AsRawFd for LegacyDrmSurface { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +impl BasicDevice for LegacyDrmSurface {} +impl ControlDevice for LegacyDrmSurface {} + +impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface { + type CursorFormat = &'a Buffer; + type Error = Error; + + fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> { + self.0.set_cursor_position(x, y) + } + + fn set_cursor_representation<'b>(&'b self, buffer: Self::CursorFormat, hotspot: (u32, u32)) -> Result<()> + where + 'a: 'b, + { + self.0.set_cursor_representation(buffer, hotspot) + } +} + +impl Surface for LegacyDrmSurface { + type Error = Error; + type Connectors = HashSet; + + fn crtc(&self) -> crtc::Handle { + self.0.crtc() + } + + fn current_connectors(&self) -> Self::Connectors { + self.0.current_connectors() + } + + fn pending_connectors(&self) -> Self::Connectors { + self.0.pending_connectors() + } + + fn current_mode(&self) -> Mode { + self.0.current_mode() + } + + fn pending_mode(&self) -> Mode { + self.0.pending_mode() + } + + fn add_connector(&self, connector: connector::Handle) -> Result<()> { + self.0.add_connector(connector) + } + + fn remove_connector(&self, connector: connector::Handle) -> Result<()> { + self.0.remove_connector(connector) + } + + fn use_mode(&self, mode: Mode) -> Result<()> { + self.0.use_mode(mode) + } +} + +impl RawSurface for LegacyDrmSurface { + fn commit_pending(&self) -> bool { + self.0.commit_pending() + } + + fn commit(&self, framebuffer: framebuffer::Handle) -> Result<()> { + self.0.commit(framebuffer) + } + + fn page_flip(&self, framebuffer: framebuffer::Handle) -> ::std::result::Result<(), SwapBuffersError> { + self.0.page_flip(framebuffer) + } +} diff --git a/src/backend/drm/mod.rs b/src/backend/drm/mod.rs index 1a2d05c..0912051 100644 --- a/src/backend/drm/mod.rs +++ b/src/backend/drm/mod.rs @@ -7,6 +7,7 @@ use drm::Device as BasicDevice; use std::borrow::Borrow; use std::error::Error; +use std::iter::IntoIterator; use std::os::unix::io::AsRawFd; use std::path::PathBuf; @@ -26,13 +27,12 @@ pub mod legacy; pub trait DeviceHandler { type Device: Device + ?Sized; - fn vblank(&mut self, surface: &<::Device as Device>::Surface); + fn vblank(&mut self, crtc: crtc::Handle); fn error(&mut self, error: <<::Device as Device>::Surface as Surface>::Error); } pub trait Device: AsRawFd + DevPath { type Surface: Surface; - type Return: Borrow; fn set_handler(&mut self, handler: impl DeviceHandler + 'static); fn clear_handler(&mut self); @@ -40,15 +40,12 @@ pub trait Device: AsRawFd + DevPath { &mut self, ctrc: crtc::Handle, mode: Mode, - connectors: impl Into<::Connectors>, - ) -> Result::Error>; + connectors: impl IntoIterator, + ) -> Result::Error>; fn process_events(&mut self); } -pub trait RawDevice: Device::Surface> -where - ::Return: Borrow<::Surface>, -{ +pub trait RawDevice: Device::Surface> { type Surface: RawSurface; }