drm: Remove associated Return type from Device

This commit is contained in:
Victor Brekenfeld 2018-11-22 10:04:19 +01:00
parent f8499e533a
commit f17e37465b
9 changed files with 262 additions and 203 deletions

View File

@ -1,8 +1,8 @@
use drm::control::{crtc, Mode}; use drm::control::{crtc, Mode};
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::iter::FromIterator;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::{Rc, Weak}; use std::rc::Rc;
use wayland_server::Display; use wayland_server::Display;
use super::{Device, DeviceHandler, Surface}; use super::{Device, DeviceHandler, Surface};
@ -28,7 +28,6 @@ pub struct EglDevice<
<D as Device>::Surface: NativeSurface, <D as Device>::Surface: NativeSurface,
{ {
dev: Rc<RefCell<EGLContext<B, D>>>, dev: Rc<RefCell<EGLContext<B, D>>>,
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<EglSurface<B, D>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
@ -85,7 +84,6 @@ where
dev: Rc::new(RefCell::new( dev: Rc::new(RefCell::new(
EGLContext::new(dev, attributes, Default::default(), log.clone()).map_err(Error::from)?, EGLContext::new(dev, attributes, Default::default(), log.clone()).map_err(Error::from)?,
)), )),
backends: Rc::new(RefCell::new(HashMap::new())),
logger: log, logger: log,
}) })
} }
@ -98,36 +96,18 @@ struct InternalDeviceHandler<
<D as Device>::Surface: NativeSurface, <D as Device>::Surface: NativeSurface,
{ {
handler: Box<DeviceHandler<Device = EglDevice<B, D>> + 'static>, handler: Box<DeviceHandler<Device = EglDevice<B, D>> + 'static>,
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<EglSurface<B, D>>>>>,
logger: ::slog::Logger,
} }
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
DeviceHandler for InternalDeviceHandler<B, D> DeviceHandler for InternalDeviceHandler<B, D>
where where
<D as NativeDisplay<B>>::Arguments: From<( <D as NativeDisplay<B>>::Arguments: From<(crtc::Handle, Mode, Vec<connector::Handle>)>,
crtc::Handle,
Mode,
<<D as Device>::Surface as Surface>::Connectors,
)>,
<D as Device>::Surface: NativeSurface, <D as Device>::Surface: NativeSurface,
{ {
type Device = D; type Device = D;
fn vblank(&mut self, surface: &<D as Device>::Surface) { fn vblank(&mut self, crtc: crtc::Handle) {
if let Some(backends) = self.backends.upgrade() { self.handler.vblank(crtc)
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 error(&mut self, error: <<D as Device>::Surface as Surface>::Error) { fn error(&mut self, error: <<D as Device>::Surface as Surface>::Error) {
self.handler self.handler
@ -138,21 +118,14 @@ where
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Device impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Device
for EglDevice<B, D> for EglDevice<B, D>
where where
<D as NativeDisplay<B>>::Arguments: From<( <D as NativeDisplay<B>>::Arguments: From<(crtc::Handle, Mode, Vec<connector::Handle>)>,
crtc::Handle,
Mode,
<<D as Device>::Surface as Surface>::Connectors,
)>,
<D as Device>::Surface: NativeSurface, <D as Device>::Surface: NativeSurface,
{ {
type Surface = EglSurface<B, D>; type Surface = EglSurface<B, D>;
type Return = Rc<EglSurface<B, D>>;
fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) { fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) {
self.dev.borrow_mut().set_handler(InternalDeviceHandler { self.dev.borrow_mut().set_handler(InternalDeviceHandler {
handler: Box::new(handler), handler: Box::new(handler),
backends: Rc::downgrade(&self.backends),
logger: self.logger.clone(),
}); });
} }
@ -164,21 +137,19 @@ where
&mut self, &mut self,
crtc: crtc::Handle, crtc: crtc::Handle,
mode: Mode, mode: Mode,
connectors: impl Into<<<Self as Device>::Surface as Surface>::Connectors>, connectors: impl IntoIterator<Item = connector::Handle>,
) -> Result<Rc<EglSurface<B, D>>> { ) -> Result<EglSurface<B, D>> {
info!(self.logger, "Initializing EglSurface"); info!(self.logger, "Initializing EglSurface");
let surface = self let surface = self
.dev .dev
.borrow_mut() .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(), dev: self.dev.clone(),
surface, surface,
}); })
self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend));
Ok(backend)
} }
fn process_events(&mut self) { fn process_events(&mut self) {

View File

@ -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::error::Result as EglResult;
use backend::egl::ffi; use backend::egl::ffi;
use backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
@ -9,23 +9,17 @@ use super::{GbmDevice, GbmSurface};
use drm::control::{crtc, Device as ControlDevice, Mode}; use drm::control::{crtc, Device as ControlDevice, Mode};
use gbm::AsRaw; use gbm::AsRaw;
use std::iter::{FromIterator, IntoIterator};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr; use std::ptr;
use std::rc::Rc;
/// Gbm backend type /// Gbm backend type
pub struct Gbm<D: RawDevice + 'static> pub struct Gbm<D: RawDevice + 'static> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
_userdata: PhantomData<D>, _userdata: PhantomData<D>,
} }
impl<D: RawDevice + 'static> Backend for Gbm<D> impl<D: RawDevice + 'static> Backend for Gbm<D> {
where type Surface = GbmSurface<D>;
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
type Surface = Rc<GbmSurface<D>>;
unsafe fn get_display<F>( unsafe fn get_display<F>(
display: ffi::NativeDisplayType, display: ffi::NativeDisplayType,
@ -52,37 +46,27 @@ where
} }
/// Arguments necessary to construct a `GbmSurface` /// Arguments necessary to construct a `GbmSurface`
pub struct SurfaceArguments<D: RawDevice + 'static> pub struct SurfaceArguments {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
/// Crtc /// Crtc
pub crtc: crtc::Handle, pub crtc: crtc::Handle,
/// Mode /// Mode
pub mode: Mode, pub mode: Mode,
/// Connectors /// Connectors
pub connectors: <GbmSurface<D> as Surface>::Connectors, pub connectors: Vec<connector::Handle>,
} }
impl<D: RawDevice + 'static> From<(crtc::Handle, Mode, <GbmSurface<D> as Surface>::Connectors)> impl From<(crtc::Handle, Mode, Vec<connector::Handle>)> for SurfaceArguments {
for SurfaceArguments<D> fn from((crtc, mode, connectors): (crtc::Handle, Mode, Vec<connector::Handle>)) -> Self {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
fn from((crtc, mode, connectors): (crtc::Handle, Mode, <GbmSurface<D> as Surface>::Connectors)) -> Self {
SurfaceArguments { SurfaceArguments {
crtc, crtc,
mode, mode,
connectors, connectors: Vec::from_iter(connectors),
} }
} }
} }
unsafe impl<D: RawDevice + ControlDevice + 'static> NativeDisplay<Gbm<D>> for GbmDevice<D> unsafe impl<D: RawDevice + ControlDevice + 'static> NativeDisplay<Gbm<D>> for GbmDevice<D> {
where type Arguments = SurfaceArguments;
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
type Arguments = SurfaceArguments<D>;
type Error = Error; type Error = Error;
fn is_backend(&self) -> bool { fn is_backend(&self) -> bool {
@ -93,24 +77,21 @@ where
Ok(self.dev.borrow().as_raw() as *const _) Ok(self.dev.borrow().as_raw() as *const _)
} }
fn create_surface(&mut self, args: SurfaceArguments<D>) -> Result<Rc<GbmSurface<D>>> { fn create_surface(&mut self, args: SurfaceArguments) -> Result<GbmSurface<D>> {
Device::create_surface(self, args.crtc, args.mode, args.connectors) Device::create_surface(self, args.crtc, args.mode, args.connectors)
} }
} }
unsafe impl<D: RawDevice + 'static> NativeSurface for Rc<GbmSurface<D>> unsafe impl<D: RawDevice + 'static> NativeSurface for GbmSurface<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
fn ptr(&self) -> ffi::NativeWindowType { fn ptr(&self) -> ffi::NativeWindowType {
self.surface.borrow().as_raw() as *const _ self.0.surface.borrow().as_raw() as *const _
} }
fn swap_buffers<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError> fn swap_buffers<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError>
where where
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>, 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) self.recreate(flip).map_err(|_| SwapBuffersError::ContextLost)
} else { } else {
self.page_flip(flip) self.page_flip(flip)

View File

@ -1,6 +1,6 @@
use super::{Device, DeviceHandler, RawDevice, Surface}; 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 gbm::{self, BufferObjectFlags, Format as GbmFormat};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -14,6 +14,7 @@ use self::error::*;
mod surface; mod surface;
pub use self::surface::GbmSurface; pub use self::surface::GbmSurface;
use self::surface::GbmSurfaceInternal;
pub mod egl; pub mod egl;
@ -23,19 +24,13 @@ pub mod session;
static LOAD: Once = ONCE_INIT; static LOAD: Once = ONCE_INIT;
/// Representation of an open gbm device to create rendering backends /// Representation of an open gbm device to create rendering backends
pub struct GbmDevice<D: RawDevice + ControlDevice + 'static> pub struct GbmDevice<D: RawDevice + ControlDevice + 'static> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
pub(self) dev: Rc<RefCell<gbm::Device<D>>>, pub(self) dev: Rc<RefCell<gbm::Device<D>>>,
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<GbmSurface<D>>>>>, backends: Rc<RefCell<HashMap<crtc::Handle, Weak<GbmSurfaceInternal<D>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
impl<D: RawDevice + ControlDevice + 'static> GbmDevice<D> impl<D: RawDevice + ControlDevice + 'static> GbmDevice<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
/// Create a new `GbmDevice` from an open drm node /// 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 /// Returns an error if the file is no valid drm node or context creation was not
@ -73,33 +68,26 @@ where
} }
} }
struct InternalDeviceHandler<D: RawDevice + ControlDevice + 'static> struct InternalDeviceHandler<D: RawDevice + ControlDevice + 'static> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
handler: Box<DeviceHandler<Device = GbmDevice<D>> + 'static>, handler: Box<DeviceHandler<Device = GbmDevice<D>> + 'static>,
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<GbmSurface<D>>>>>, backends: Weak<RefCell<HashMap<crtc::Handle, Weak<GbmSurfaceInternal<D>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
impl<D: RawDevice + ControlDevice + 'static> DeviceHandler for InternalDeviceHandler<D> impl<D: RawDevice + ControlDevice + 'static> DeviceHandler for InternalDeviceHandler<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
type Device = D; type Device = D;
fn vblank(&mut self, surface: &<D as Device>::Surface) { fn vblank(&mut self, crtc: crtc::Handle) {
if let Some(backends) = self.backends.upgrade() { 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() { if let Some(surface) = surface.upgrade() {
surface.unlock_buffer(); surface.unlock_buffer();
self.handler.vblank(&*surface); self.handler.vblank(crtc);
} }
} else { } else {
warn!( warn!(
self.logger, self.logger,
"Surface ({:?}) not managed by gbm, event not handled.", "Surface ({:?}) not managed by gbm, event not handled.", crtc
surface.crtc()
); );
} }
} }
@ -110,12 +98,8 @@ where
} }
} }
impl<D: RawDevice + ControlDevice + 'static> Device for GbmDevice<D> impl<D: RawDevice + ControlDevice + 'static> Device for GbmDevice<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
type Surface = GbmSurface<D>; type Surface = GbmSurface<D>;
type Return = Rc<GbmSurface<D>>;
fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) { fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) {
self.dev.borrow_mut().set_handler(InternalDeviceHandler { self.dev.borrow_mut().set_handler(InternalDeviceHandler {
@ -133,8 +117,8 @@ where
&mut self, &mut self,
crtc: crtc::Handle, crtc: crtc::Handle,
mode: Mode, mode: Mode,
connectors: impl Into<<Self::Surface as Surface>::Connectors>, connectors: impl IntoIterator<Item = connector::Handle>,
) -> Result<Rc<GbmSurface<D>>> { ) -> Result<GbmSurface<D>> {
info!(self.logger, "Initializing GbmSurface"); info!(self.logger, "Initializing GbmSurface");
let (w, h) = mode.size(); let (w, h) = mode.size();
@ -173,7 +157,7 @@ where
(0, 0), (0, 0),
)); ));
let backend = Rc::new(GbmSurface { let backend = Rc::new(GbmSurfaceInternal {
dev: self.dev.clone(), dev: self.dev.clone(),
surface: RefCell::new(surface), surface: RefCell::new(surface),
crtc: Device::create_surface(&mut **self.dev.borrow_mut(), crtc, mode, connectors) 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))), logger: self.logger.new(o!("crtc" => format!("{:?}", crtc))),
}); });
self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend));
Ok(backend) Ok(GbmSurface(backend))
} }
fn process_events(&mut self) { fn process_events(&mut self) {
@ -193,10 +177,7 @@ where
} }
} }
impl<D: RawDevice + ControlDevice + 'static> AsRawFd for GbmDevice<D> impl<D: RawDevice + ControlDevice + 'static> AsRawFd for GbmDevice<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
fn as_raw_fd(&self) -> RawFd { fn as_raw_fd(&self) -> RawFd {
self.dev.borrow().as_raw_fd() self.dev.borrow().as_raw_fd()
} }

View File

@ -5,26 +5,22 @@ use std::collections::HashMap;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use super::{GbmDevice, GbmSurface}; use super::{GbmDevice, GbmSurfaceInternal};
use backend::drm::{Device, RawDevice, RawSurface}; use backend::drm::{RawDevice, RawSurface};
use backend::session::{AsSessionObserver, SessionObserver}; use backend::session::{AsSessionObserver, SessionObserver};
/// `SessionObserver` linked to the `DrmDevice` it was created from. /// `SessionObserver` linked to the `DrmDevice` it was created from.
pub struct GbmDeviceObserver< pub struct GbmDeviceObserver<
S: SessionObserver + 'static, S: SessionObserver + 'static,
D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static,
> where > {
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
observer: S, observer: S,
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<GbmSurface<D>>>>>, backends: Weak<RefCell<HashMap<crtc::Handle, Weak<GbmSurfaceInternal<D>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static> impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static>
AsSessionObserver<GbmDeviceObserver<S, D>> for GbmDevice<D> AsSessionObserver<GbmDeviceObserver<S, D>> for GbmDevice<D>
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{ {
fn observer(&mut self) -> GbmDeviceObserver<S, D> { fn observer(&mut self) -> GbmDeviceObserver<S, D> {
GbmDeviceObserver { GbmDeviceObserver {
@ -37,8 +33,6 @@ where
impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static> impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static>
SessionObserver for GbmDeviceObserver<S, D> SessionObserver for GbmDeviceObserver<S, D>
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{ {
fn pause(&mut self, devnum: Option<(u32, u32)>) { fn pause(&mut self, devnum: Option<(u32, u32)>) {
self.observer.pause(devnum); self.observer.pause(devnum);
@ -51,7 +45,8 @@ where
for (crtc, backend) in backends.borrow().iter() { for (crtc, backend) in backends.borrow().iter() {
if let Some(backend) = backend.upgrade() { if let Some(backend) = backend.upgrade() {
// restart rendering loop // 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()) .page_flip(backend.current_frame_buffer.get().handle())
{ {
warn!(self.logger, "Failed to restart rendering loop. Error: {}", err); warn!(self.logger, "Failed to restart rendering loop. Error: {}", err);

View File

@ -1,7 +1,7 @@
use super::super::{Device, RawDevice, RawSurface, Surface}; use super::super::{Device, RawDevice, RawSurface, Surface};
use super::error::*; 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 gbm::{self, BufferObject, BufferObjectFlags, Format as GbmFormat, SurfaceBufferHandle};
use image::{ImageBuffer, Rgba}; use image::{ImageBuffer, Rgba};
@ -9,17 +9,14 @@ use std::cell::{Cell, RefCell};
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::rc::Rc; use std::rc::Rc;
use backend::drm::legacy::{LegacyDrmDevice, LegacyDrmSurface}; use backend::drm::legacy::LegacyDrmDevice;
use backend::graphics::CursorBackend; use backend::graphics::CursorBackend;
use backend::graphics::SwapBuffersError; use backend::graphics::SwapBuffersError;
pub struct GbmSurface<D: RawDevice + 'static> pub(super) struct GbmSurfaceInternal<D: RawDevice + 'static> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
pub(super) dev: Rc<RefCell<gbm::Device<D>>>, pub(super) dev: Rc<RefCell<gbm::Device<D>>>,
pub(super) surface: RefCell<gbm::Surface<framebuffer::Info>>, pub(super) surface: RefCell<gbm::Surface<framebuffer::Info>>,
pub(super) crtc: <D as Device>::Return, pub(super) crtc: <D as Device>::Surface,
pub(super) cursor: Cell<(BufferObject<()>, (u32, u32))>, pub(super) cursor: Cell<(BufferObject<()>, (u32, u32))>,
pub(super) current_frame_buffer: Cell<framebuffer::Info>, pub(super) current_frame_buffer: Cell<framebuffer::Info>,
pub(super) front_buffer: Cell<SurfaceBufferHandle<framebuffer::Info>>, pub(super) front_buffer: Cell<SurfaceBufferHandle<framebuffer::Info>>,
@ -27,10 +24,7 @@ where
pub(super) logger: ::slog::Logger, pub(super) logger: ::slog::Logger,
} }
impl<D: RawDevice + 'static> GbmSurface<D> impl<D: RawDevice + 'static> GbmSurfaceInternal<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
pub(super) fn unlock_buffer(&self) { pub(super) fn unlock_buffer(&self) {
// after the page swap is finished we need to release the rendered buffer. // after the page swap is finished we need to release the rendered buffer.
// this is called from the PageFlipHandler // this is called from the PageFlipHandler
@ -79,15 +73,14 @@ where
let fb = if let Some(info) = maybe_fb { let fb = if let Some(info) = maybe_fb {
info info
} else { } else {
let fb = framebuffer::create(::std::borrow::Borrow::borrow(&self.crtc), &*next_bo) let fb = framebuffer::create(&self.crtc, &*next_bo).map_err(|_| SwapBuffersError::ContextLost)?;
.map_err(|_| SwapBuffersError::ContextLost)?;
next_bo.set_userdata(fb).unwrap(); next_bo.set_userdata(fb).unwrap();
fb fb
}; };
self.next_buffer.set(Some(next_bo)); self.next_buffer.set(Some(next_bo));
trace!(self.logger, "Queueing Page flip"); 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); self.current_frame_buffer.set(fb);
@ -119,9 +112,7 @@ where
{ {
if let Some(mut old_bo) = self.next_buffer.take() { if let Some(mut old_bo) = self.next_buffer.take() {
if let Ok(Some(fb)) = old_bo.take_userdata() { if let Ok(Some(fb)) = old_bo.take_userdata() {
if let Err(err) = if let Err(err) = framebuffer::destroy(&self.crtc, fb.handle()) {
framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle())
{
warn!( warn!(
self.logger, self.logger,
"Error releasing old back_buffer framebuffer: {:?}", err "Error releasing old back_buffer framebuffer: {:?}", err
@ -141,10 +132,10 @@ where
debug!(self.logger, "FrontBuffer color format: {:?}", front_bo.format()); debug!(self.logger, "FrontBuffer color format: {:?}", front_bo.format());
// we also need a new framebuffer for the front buffer // 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)?; .chain_err(|| ErrorKind::UnderlyingBackendError)?;
::std::borrow::Borrow::borrow(&self.crtc) self.crtc
.commit(fb.handle()) .commit(fb.handle())
.chain_err(|| ErrorKind::UnderlyingBackendError)?; .chain_err(|| ErrorKind::UnderlyingBackendError)?;
@ -152,7 +143,7 @@ where
front_bo front_bo
}); });
if let Ok(Some(fb)) = old_front_bo.take_userdata() { 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!( warn!(
self.logger, self.logger,
"Error releasing old front_buffer framebuffer: {:?}", err "Error releasing old front_buffer framebuffer: {:?}", err
@ -167,47 +158,44 @@ where
} }
} }
impl<D: RawDevice + 'static> Surface for GbmSurface<D> impl<D: RawDevice + 'static> Surface for GbmSurfaceInternal<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
type Connectors = <<D as Device>::Surface as Surface>::Connectors; type Connectors = <<D as Device>::Surface as Surface>::Connectors;
type Error = Error; type Error = Error;
fn crtc(&self) -> crtc::Handle { fn crtc(&self) -> crtc::Handle {
::std::borrow::Borrow::borrow(&self.crtc).crtc() self.crtc.crtc()
} }
fn current_connectors(&self) -> Self::Connectors { fn current_connectors(&self) -> Self::Connectors {
::std::borrow::Borrow::borrow(&self.crtc).current_connectors() self.crtc.current_connectors()
} }
fn pending_connectors(&self) -> Self::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<()> { fn add_connector(&self, connector: connector::Handle) -> Result<()> {
::std::borrow::Borrow::borrow(&self.crtc) self.crtc
.add_connector(connector) .add_connector(connector)
.chain_err(|| ErrorKind::UnderlyingBackendError) .chain_err(|| ErrorKind::UnderlyingBackendError)
} }
fn remove_connector(&self, connector: connector::Handle) -> Result<()> { fn remove_connector(&self, connector: connector::Handle) -> Result<()> {
::std::borrow::Borrow::borrow(&self.crtc) self.crtc
.remove_connector(connector) .remove_connector(connector)
.chain_err(|| ErrorKind::UnderlyingBackendError) .chain_err(|| ErrorKind::UnderlyingBackendError)
} }
fn current_mode(&self) -> Mode { fn current_mode(&self) -> Mode {
::std::borrow::Borrow::borrow(&self.crtc).current_mode() self.crtc.current_mode()
} }
fn pending_mode(&self) -> 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<()> { fn use_mode(&self, mode: Mode) -> Result<()> {
::std::borrow::Borrow::borrow(&self.crtc) self.crtc
.use_mode(mode) .use_mode(mode)
.chain_err(|| ErrorKind::UnderlyingBackendError) .chain_err(|| ErrorKind::UnderlyingBackendError)
} }
@ -218,9 +206,8 @@ where
// Option 1: When there is GAT support, impl `GraphicsBackend` for `LegacyDrmBackend` // Option 1: When there is GAT support, impl `GraphicsBackend` for `LegacyDrmBackend`
// using a new generic `B: Buffer` and use this: // using a new generic `B: Buffer` and use this:
/* /*
impl<'a, D: RawDevice + 'static> CursorBackend<'a> for GbmSurface<D> impl<'a, D: RawDevice + 'static> CursorBackend<'a> for GbmSurfaceInternal<D>
where where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
<D as RawDevice>::Surface: CursorBackend<'a>, <D as RawDevice>::Surface: CursorBackend<'a>,
<<D as RawDevice>::Surface as CursorBackend<'a>>::CursorFormat: Buffer, <<D as RawDevice>::Surface as CursorBackend<'a>>::CursorFormat: Buffer,
<<D as RawDevice>::Surface as CursorBackend<'a>>::Error: ::std::error::Error + Send <<D as RawDevice>::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: // 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<D> impl<'a, D: RawDevice + 'static> GraphicsBackend<'a> for GbmSurfaceInternal<D>
where where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
<D as RawDevice>::Surface: CursorBackend<'a>, <D as RawDevice>::Surface: CursorBackend<'a>,
<<D as RawDevice>::Surface as CursorBackend<'a>>::CursorFormat=&'a Buffer, <<D as RawDevice>::Surface as CursorBackend<'a>>::CursorFormat=&'a Buffer,
<<D as RawDevice>::Surface as CursorBackend<'a>>::Error: ::std::error::Error + Send <<D as RawDevice>::Surface as CursorBackend<'a>>::Error: ::std::error::Error + Send
@ -239,15 +225,14 @@ where
*/ */
// But for now got to do this: // But for now got to do this:
impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<A>> { impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurfaceInternal<LegacyDrmDevice<A>> {
type CursorFormat = &'a ImageBuffer<Rgba<u8>, Vec<u8>>; type CursorFormat = &'a ImageBuffer<Rgba<u8>, Vec<u8>>;
type Error = Error; type Error = Error;
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> { fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
ResultExt::chain_err( ResultExt::chain_err(self.crtc.set_cursor_position(x, y), || {
::std::borrow::Borrow::<Rc<LegacyDrmSurface<A>>>::borrow(&self.crtc).set_cursor_position(x, y), ErrorKind::UnderlyingBackendError
|| ErrorKind::UnderlyingBackendError, })
)
} }
fn set_cursor_representation<'b>( fn set_cursor_representation<'b>(
@ -279,11 +264,9 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
trace!(self.logger, "Setting the new imported cursor"); trace!(self.logger, "Setting the new imported cursor");
ResultExt::chain_err( ResultExt::chain_err(self.crtc.set_cursor_representation(&cursor, hotspot), || {
::std::borrow::Borrow::<Rc<LegacyDrmSurface<A>>>::borrow(&self.crtc) ErrorKind::UnderlyingBackendError
.set_cursor_representation(&cursor, hotspot), })?;
|| ErrorKind::UnderlyingBackendError,
)?;
// and store it // and store it
self.cursor.set((cursor, hotspot)); self.cursor.set((cursor, hotspot));
@ -291,10 +274,7 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
} }
} }
impl<D: RawDevice + 'static> Drop for GbmSurface<D> impl<D: RawDevice + 'static> Drop for GbmSurfaceInternal<D> {
where
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
{
fn drop(&mut self) { fn drop(&mut self) {
// Drop framebuffers attached to the userdata of the gbm surface buffers. // Drop framebuffers attached to the userdata of the gbm surface buffers.
// (They don't implement drop, as they need the device) // (They don't implement drop, as they need the device)
@ -308,12 +288,87 @@ where
} }
} { } {
// ignore failure at this point // 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() { if let Ok(Some(fb)) = self.front_buffer.get_mut().take_userdata() {
// ignore failure at this point // 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<D: RawDevice + 'static>(pub(super) Rc<GbmSurfaceInternal<D>>);
impl<D: RawDevice + 'static> GbmSurface<D> {
pub fn page_flip<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError>
where
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
{
self.0.page_flip(flip)
}
pub fn recreate<F>(&self, flip: F) -> Result<()>
where
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
{
self.0.recreate(flip)
}
}
impl<D: RawDevice + 'static> Surface for GbmSurface<D> {
type Connectors = <<D as Device>::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<LegacyDrmDevice<A>> {
type CursorFormat = &'a ImageBuffer<Rgba<u8>, Vec<u8>>;
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<Rgba<u8>, Vec<u8>>,
hotspot: (u32, u32),
) -> Result<()>
where
'a: 'b,
{
self.0.set_cursor_representation(buffer, hotspot)
}
}

View File

@ -7,6 +7,7 @@ use nix::sys::stat::fstat;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -14,7 +15,7 @@ use std::sync::{Arc, RwLock};
mod surface; mod surface;
pub use self::surface::LegacyDrmSurface; pub use self::surface::LegacyDrmSurface;
use self::surface::State; use self::surface::{LegacyDrmSurfaceInternal, State};
pub mod error; pub mod error;
use self::error::*; use self::error::*;
@ -28,7 +29,7 @@ pub struct LegacyDrmDevice<A: AsRawFd + 'static> {
priviledged: bool, priviledged: bool,
active: Arc<AtomicBool>, active: Arc<AtomicBool>,
old_state: HashMap<crtc::Handle, (crtc::Info, Vec<connector::Handle>)>, old_state: HashMap<crtc::Handle, (crtc::Info, Vec<connector::Handle>)>,
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<LegacyDrmSurface<A>>>>>, backends: Rc<RefCell<HashMap<crtc::Handle, Weak<LegacyDrmSurfaceInternal<A>>>>>,
handler: Option<RefCell<Box<DeviceHandler<Device = LegacyDrmDevice<A>>>>>, handler: Option<RefCell<Box<DeviceHandler<Device = LegacyDrmDevice<A>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
@ -120,7 +121,6 @@ impl<A: AsRawFd + 'static> ControlDevice for LegacyDrmDevice<A> {}
impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> { impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
type Surface = LegacyDrmSurface<A>; type Surface = LegacyDrmSurface<A>;
type Return = Rc<LegacyDrmSurface<A>>;
fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) { fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static) {
self.handler = Some(RefCell::new(Box::new(handler))); self.handler = Some(RefCell::new(Box::new(handler)));
@ -134,8 +134,8 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
&mut self, &mut self,
crtc: crtc::Handle, crtc: crtc::Handle,
mode: Mode, mode: Mode,
connectors: impl Into<<Self::Surface as Surface>::Connectors>, connectors: impl IntoIterator<Item = connector::Handle>,
) -> Result<Rc<LegacyDrmSurface<A>>> { ) -> Result<LegacyDrmSurface<A>> {
if self.backends.borrow().contains_key(&crtc) { if self.backends.borrow().contains_key(&crtc) {
bail!(ErrorKind::CrtcAlreadyInUse(crtc)); bail!(ErrorKind::CrtcAlreadyInUse(crtc));
} }
@ -144,7 +144,7 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
bail!(ErrorKind::DeviceInactive); 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 // check if we have an encoder for every connector and the mode mode
for connector in &connectors { for connector in &connectors {
let con_info = connector::Info::load_from_device(self, *connector).chain_err(|| { let con_info = connector::Info::load_from_device(self, *connector).chain_err(|| {
@ -184,7 +184,7 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
let state = State { mode, connectors }; let state = State { mode, connectors };
let backend = Rc::new(LegacyDrmSurface { let backend = Rc::new(LegacyDrmSurfaceInternal {
dev: self.dev.clone(), dev: self.dev.clone(),
crtc, crtc,
state: RwLock::new(state.clone()), state: RwLock::new(state.clone()),
@ -193,7 +193,7 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
}); });
self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend));
Ok(backend) Ok(LegacyDrmSurface(backend))
} }
fn process_events(&mut self) { fn process_events(&mut self) {
@ -201,17 +201,18 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
Ok(events) => for event in events { Ok(events) => for event in events {
if let crtc::Event::PageFlip(event) = event { if let crtc::Event::PageFlip(event) = event {
if self.active.load(Ordering::SeqCst) { if self.active.load(Ordering::SeqCst) {
if let Some(backend) = self if self
.backends .backends
.borrow() .borrow()
.get(&event.crtc) .get(&event.crtc)
.iter() .iter()
.flat_map(|x| x.upgrade()) .flat_map(|x| x.upgrade())
.next() .next()
.is_some()
{ {
trace!(self.logger, "Handling event for backend {:?}", event.crtc); trace!(self.logger, "Handling event for backend {:?}", event.crtc);
if let Some(handler) = self.handler.as_ref() { if let Some(handler) = self.handler.as_ref() {
handler.borrow_mut().vblank(&backend); handler.borrow_mut().vblank(event.crtc);
} }
} else { } else {
self.backends.borrow_mut().remove(&event.crtc); self.backends.borrow_mut().remove(&event.crtc);

View File

@ -9,7 +9,7 @@ use std::rc::{Rc, Weak};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use super::{Dev, LegacyDrmDevice, LegacyDrmSurface}; use super::{Dev, LegacyDrmDevice, LegacyDrmSurfaceInternal};
use backend::session::{AsSessionObserver, SessionObserver}; use backend::session::{AsSessionObserver, SessionObserver};
/// `SessionObserver` linked to the `DrmDevice` it was created from. /// `SessionObserver` linked to the `DrmDevice` it was created from.
@ -19,7 +19,7 @@ pub struct LegacyDrmDeviceObserver<A: AsRawFd + 'static> {
priviledged: bool, priviledged: bool,
active: Arc<AtomicBool>, active: Arc<AtomicBool>,
old_state: HashMap<crtc::Handle, (crtc::Info, Vec<connector::Handle>)>, old_state: HashMap<crtc::Handle, (crtc::Info, Vec<connector::Handle>)>,
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<LegacyDrmSurface<A>>>>>, backends: Weak<RefCell<HashMap<crtc::Handle, Weak<LegacyDrmSurfaceInternal<A>>>>>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }

View File

@ -19,7 +19,7 @@ pub struct State {
pub connectors: HashSet<connector::Handle>, pub connectors: HashSet<connector::Handle>,
} }
pub struct LegacyDrmSurface<A: AsRawFd + 'static> { pub(super) struct LegacyDrmSurfaceInternal<A: AsRawFd + 'static> {
pub(super) dev: Rc<Dev<A>>, pub(super) dev: Rc<Dev<A>>,
pub(super) crtc: crtc::Handle, pub(super) crtc: crtc::Handle,
pub(super) state: RwLock<State>, pub(super) state: RwLock<State>,
@ -27,16 +27,16 @@ pub struct LegacyDrmSurface<A: AsRawFd + 'static> {
pub(super) logger: ::slog::Logger, pub(super) logger: ::slog::Logger,
} }
impl<A: AsRawFd + 'static> AsRawFd for LegacyDrmSurface<A> { impl<A: AsRawFd + 'static> AsRawFd for LegacyDrmSurfaceInternal<A> {
fn as_raw_fd(&self) -> RawFd { fn as_raw_fd(&self) -> RawFd {
self.dev.as_raw_fd() self.dev.as_raw_fd()
} }
} }
impl<A: AsRawFd + 'static> BasicDevice for LegacyDrmSurface<A> {} impl<A: AsRawFd + 'static> BasicDevice for LegacyDrmSurfaceInternal<A> {}
impl<A: AsRawFd + 'static> ControlDevice for LegacyDrmSurface<A> {} impl<A: AsRawFd + 'static> ControlDevice for LegacyDrmSurfaceInternal<A> {}
impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface<A> { impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurfaceInternal<A> {
type CursorFormat = &'a Buffer; type CursorFormat = &'a Buffer;
type Error = Error; type Error = Error;
@ -61,7 +61,7 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface<A> {
} }
} }
impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> { impl<A: AsRawFd + 'static> Surface for LegacyDrmSurfaceInternal<A> {
type Error = Error; type Error = Error;
type Connectors = HashSet<connector::Handle>; type Connectors = HashSet<connector::Handle>;
@ -149,7 +149,7 @@ impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
} }
} }
impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> { impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurfaceInternal<A> {
fn commit_pending(&self) -> bool { fn commit_pending(&self) -> bool {
*self.pending.read().unwrap() != *self.state.read().unwrap() *self.pending.read().unwrap() != *self.state.read().unwrap()
} }
@ -220,9 +220,87 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
} }
} }
impl<A: AsRawFd + 'static> Drop for LegacyDrmSurface<A> { impl<A: AsRawFd + 'static> Drop for LegacyDrmSurfaceInternal<A> {
fn drop(&mut self) { fn drop(&mut self) {
// ignore failure at this point // ignore failure at this point
let _ = crtc::clear_cursor(self, self.crtc); let _ = crtc::clear_cursor(self, self.crtc);
} }
} }
pub struct LegacyDrmSurface<A: AsRawFd + 'static>(pub(super) Rc<LegacyDrmSurfaceInternal<A>>);
impl<A: AsRawFd + 'static> AsRawFd for LegacyDrmSurface<A> {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl<A: AsRawFd + 'static> BasicDevice for LegacyDrmSurface<A> {}
impl<A: AsRawFd + 'static> ControlDevice for LegacyDrmSurface<A> {}
impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface<A> {
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<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
type Error = Error;
type Connectors = HashSet<connector::Handle>;
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<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
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)
}
}

View File

@ -7,6 +7,7 @@ use drm::Device as BasicDevice;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::error::Error; use std::error::Error;
use std::iter::IntoIterator;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::path::PathBuf; use std::path::PathBuf;
@ -26,13 +27,12 @@ pub mod legacy;
pub trait DeviceHandler { pub trait DeviceHandler {
type Device: Device + ?Sized; type Device: Device + ?Sized;
fn vblank(&mut self, surface: &<<Self as DeviceHandler>::Device as Device>::Surface); fn vblank(&mut self, crtc: crtc::Handle);
fn error(&mut self, error: <<<Self as DeviceHandler>::Device as Device>::Surface as Surface>::Error); fn error(&mut self, error: <<<Self as DeviceHandler>::Device as Device>::Surface as Surface>::Error);
} }
pub trait Device: AsRawFd + DevPath { pub trait Device: AsRawFd + DevPath {
type Surface: Surface; type Surface: Surface;
type Return: Borrow<Self::Surface>;
fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static); fn set_handler(&mut self, handler: impl DeviceHandler<Device = Self> + 'static);
fn clear_handler(&mut self); fn clear_handler(&mut self);
@ -40,15 +40,12 @@ pub trait Device: AsRawFd + DevPath {
&mut self, &mut self,
ctrc: crtc::Handle, ctrc: crtc::Handle,
mode: Mode, mode: Mode,
connectors: impl Into<<Self::Surface as Surface>::Connectors>, connectors: impl IntoIterator<Item = connector::Handle>,
) -> Result<Self::Return, <Self::Surface as Surface>::Error>; ) -> Result<Self::Surface, <Self::Surface as Surface>::Error>;
fn process_events(&mut self); fn process_events(&mut self);
} }
pub trait RawDevice: Device<Surface = <Self as RawDevice>::Surface> pub trait RawDevice: Device<Surface = <Self as RawDevice>::Surface> {
where
<Self as Device>::Return: Borrow<<Self as RawDevice>::Surface>,
{
type Surface: RawSurface; type Surface: RawSurface;
} }