drm: Remove associated Return type from Device
This commit is contained in:
parent
f8499e533a
commit
f17e37465b
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue