cargo fmt
This commit is contained in:
parent
bd5690bd77
commit
9ee44672a0
|
@ -1,15 +1,15 @@
|
|||
use drm::control::{crtc, Mode};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::rc::{Rc, Weak};
|
||||
use wayland_server::Display;
|
||||
|
||||
use backend::egl::{EGLContext, EGLGraphicsBackend, EGLDisplay};
|
||||
use super::{Device, DeviceHandler, Surface};
|
||||
use backend::egl::context::GlAttributes;
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::egl::error::Result as EGLResult;
|
||||
use super::{Device, Surface, DeviceHandler};
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::egl::{EGLContext, EGLDisplay, EGLGraphicsBackend};
|
||||
|
||||
pub mod error;
|
||||
use self::error::*;
|
||||
|
@ -21,24 +21,31 @@ pub use self::surface::*;
|
|||
pub mod session;
|
||||
|
||||
/// Representation of an open gbm device to create rendering backends
|
||||
pub struct EglDevice<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
pub struct EglDevice<
|
||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||
D: Device + NativeDisplay<B> + 'static,
|
||||
> where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
dev: Rc<RefCell<EGLContext<B, D>>>,
|
||||
backends: Rc<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> AsRawFd for EglDevice<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> AsRawFd
|
||||
for EglDevice<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.dev.borrow().as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> EglDevice<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
EglDevice<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
/// Create a new `EglGbmDrmDevice` from an open drm node
|
||||
///
|
||||
|
@ -75,12 +82,8 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
debug!(log, "Creating egl context from device");
|
||||
Ok(EglDevice {
|
||||
// Open the gbm device from the drm device and create a context based on that
|
||||
dev: Rc::new(RefCell::new(EGLContext::new(
|
||||
dev,
|
||||
attributes,
|
||||
Default::default(),
|
||||
log.clone(),
|
||||
).map_err(Error::from)?
|
||||
dev: Rc::new(RefCell::new(
|
||||
EGLContext::new(dev, attributes, Default::default(), log.clone()).map_err(Error::from)?,
|
||||
)),
|
||||
backends: Rc::new(RefCell::new(HashMap::new())),
|
||||
logger: log,
|
||||
|
@ -88,20 +91,28 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
}
|
||||
}
|
||||
|
||||
struct InternalDeviceHandler<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
struct InternalDeviceHandler<
|
||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||
D: Device + NativeDisplay<B> + 'static,
|
||||
> where
|
||||
<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> DeviceHandler for InternalDeviceHandler<B, D>
|
||||
where
|
||||
<D as NativeDisplay<B>>::Arguments: From<(crtc::Handle, Mode, <<D as Device>::Surface as Surface>::Connectors)>,
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
DeviceHandler for InternalDeviceHandler<B, D>
|
||||
where
|
||||
<D as NativeDisplay<B>>::Arguments: From<(
|
||||
crtc::Handle,
|
||||
Mode,
|
||||
<<D as Device>::Surface as Surface>::Connectors,
|
||||
)>,
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
type Device=D;
|
||||
type Device = D;
|
||||
|
||||
fn vblank(&mut self, surface: &<D as Device>::Surface) {
|
||||
if let Some(backends) = self.backends.upgrade() {
|
||||
|
@ -110,31 +121,41 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
self.handler.vblank(&*surface);
|
||||
}
|
||||
} else {
|
||||
warn!(self.logger, "Surface ({:?}) not managed by egl, event not handled.", surface.crtc());
|
||||
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) {
|
||||
self.handler.error(ResultExt::<()>::chain_err(Err(error), || ErrorKind::UnderlyingBackendError).unwrap_err())
|
||||
self.handler
|
||||
.error(ResultExt::<()>::chain_err(Err(error), || ErrorKind::UnderlyingBackendError).unwrap_err())
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Device for EglDevice<B, D>
|
||||
where
|
||||
<D as NativeDisplay<B>>::Arguments: From<(crtc::Handle, Mode, <<D as Device>::Surface as Surface>::Connectors)>,
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Device
|
||||
for EglDevice<B, D>
|
||||
where
|
||||
<D as NativeDisplay<B>>::Arguments: From<(
|
||||
crtc::Handle,
|
||||
Mode,
|
||||
<<D as Device>::Surface as Surface>::Connectors,
|
||||
)>,
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
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 {
|
||||
handler: Box::new(handler),
|
||||
backends: Rc::downgrade(&self.backends),
|
||||
logger: self.logger.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
fn clear_handler(&mut self) {
|
||||
self.dev.borrow_mut().clear_handler()
|
||||
}
|
||||
|
@ -147,7 +168,10 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
) -> Result<Rc<EglSurface<B, D>>> {
|
||||
info!(self.logger, "Initializing EglSurface");
|
||||
|
||||
let surface = self.dev.borrow_mut().create_surface((crtc, mode, connectors.into()).into())?;
|
||||
let surface = self
|
||||
.dev
|
||||
.borrow_mut()
|
||||
.create_surface((crtc, mode, connectors.into()).into())?;
|
||||
|
||||
let backend = Rc::new(EglSurface {
|
||||
dev: self.dev.clone(),
|
||||
|
@ -157,16 +181,17 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
Ok(backend)
|
||||
}
|
||||
|
||||
|
||||
fn process_events(&mut self) {
|
||||
self.dev.borrow_mut().process_events()
|
||||
self.dev.borrow_mut().process_events()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> EGLGraphicsBackend for EglDevice<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
EGLGraphicsBackend for EglDevice<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
fn bind_wl_display(&self, display: &Display) -> EGLResult<EGLDisplay> {
|
||||
self.dev.borrow().bind_wl_display(display)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::os::unix::io::RawFd;
|
||||
|
||||
use super::EglDevice;
|
||||
use backend::drm::Device;
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::session::{AsSessionObserver, SessionObserver};
|
||||
use backend::drm::Device;
|
||||
use super::{EglDevice};
|
||||
|
||||
/// `SessionObserver` linked to the `DrmDevice` it was created from.
|
||||
pub struct EglDeviceObserver<S: SessionObserver + 'static> {
|
||||
|
@ -11,11 +11,12 @@ pub struct EglDeviceObserver<S: SessionObserver + 'static> {
|
|||
}
|
||||
|
||||
impl<
|
||||
S: SessionObserver + 'static,
|
||||
B: Backend<Surface=<D as Device>::Surface> + 'static,
|
||||
D: Device + NativeDisplay<B> + AsSessionObserver<S> + 'static,
|
||||
> AsSessionObserver<EglDeviceObserver<S>> for EglDevice<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
S: SessionObserver + 'static,
|
||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||
D: Device + NativeDisplay<B> + AsSessionObserver<S> + 'static,
|
||||
> AsSessionObserver<EglDeviceObserver<S>> for EglDevice<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
fn observer(&mut self) -> EglDeviceObserver<S> {
|
||||
EglDeviceObserver {
|
||||
|
|
|
@ -3,22 +3,27 @@ use nix::libc::c_void;
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use backend::drm::{Device, Surface};
|
||||
use backend::egl::{EGLContext, EGLSurface};
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::graphics::{CursorBackend, SwapBuffersError};
|
||||
use backend::graphics::gl::{GLGraphicsBackend, PixelFormat};
|
||||
use super::error::*;
|
||||
use backend::drm::{Device, Surface};
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::egl::{EGLContext, EGLSurface};
|
||||
use backend::graphics::gl::{GLGraphicsBackend, PixelFormat};
|
||||
use backend::graphics::{CursorBackend, SwapBuffersError};
|
||||
|
||||
pub struct EglSurface<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
pub struct EglSurface<
|
||||
B: Backend<Surface = <D as Device>::Surface> + 'static,
|
||||
D: Device + NativeDisplay<B> + 'static,
|
||||
> where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
pub(in super) dev: Rc<RefCell<EGLContext<B, D>>>,
|
||||
pub(in super) surface: EGLSurface<B::Surface>,
|
||||
pub(super) dev: Rc<RefCell<EGLContext<B, D>>>,
|
||||
pub(super) surface: EGLSurface<B::Surface>,
|
||||
}
|
||||
|
||||
impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Surface for EglSurface<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> Surface
|
||||
for EglSurface<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
type Error = Error;
|
||||
type Connectors = <<D as Device>::Surface as Surface>::Connectors;
|
||||
|
@ -30,36 +35,43 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
fn current_connectors(&self) -> Self::Connectors {
|
||||
self.surface.current_connectors()
|
||||
}
|
||||
|
||||
|
||||
fn pending_connectors(&self) -> Self::Connectors {
|
||||
self.surface.pending_connectors()
|
||||
}
|
||||
|
||||
fn add_connector(&self, connector: connector::Handle) -> Result<()> {
|
||||
self.surface.add_connector(connector).chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
self.surface
|
||||
.add_connector(connector)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
}
|
||||
|
||||
fn remove_connector(&self, connector: connector::Handle) -> Result<()> {
|
||||
self.surface.remove_connector(connector).chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
self.surface
|
||||
.remove_connector(connector)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
}
|
||||
|
||||
|
||||
fn current_mode(&self) -> Mode {
|
||||
self.surface.current_mode()
|
||||
}
|
||||
|
||||
|
||||
fn pending_mode(&self) -> Mode {
|
||||
self.surface.pending_mode()
|
||||
}
|
||||
|
||||
fn use_mode(&self, mode: Mode) -> Result<()> {
|
||||
self.surface.use_mode(mode).chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
self.surface
|
||||
.use_mode(mode)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> CursorBackend<'a> for EglSurface<B, D>
|
||||
where
|
||||
D: CursorBackend<'a>,
|
||||
<D as Device>::Surface: NativeSurface
|
||||
impl<'a, B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
CursorBackend<'a> for EglSurface<B, D>
|
||||
where
|
||||
D: CursorBackend<'a>,
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
type CursorFormat = <D as CursorBackend<'a>>::CursorFormat;
|
||||
type Error = <D as CursorBackend<'a>>::Error;
|
||||
|
@ -73,15 +85,18 @@ impl<'a, B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + Nativ
|
|||
buffer: Self::CursorFormat,
|
||||
hotspot: (u32, u32),
|
||||
) -> ::std::result::Result<(), Self::Error>
|
||||
where 'a: 'b
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let dev = self.dev.borrow();
|
||||
dev.set_cursor_representation(buffer, hotspot)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static> GLGraphicsBackend for EglSurface<B, D>
|
||||
where <D as Device>::Surface: NativeSurface
|
||||
impl<B: Backend<Surface = <D as Device>::Surface> + 'static, D: Device + NativeDisplay<B> + 'static>
|
||||
GLGraphicsBackend for EglSurface<B, D>
|
||||
where
|
||||
<D as Device>::Surface: NativeSurface,
|
||||
{
|
||||
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
||||
self.surface.swap_buffers()
|
||||
|
@ -107,4 +122,4 @@ impl<B: Backend<Surface=<D as Device>::Surface> + 'static, D: Device + NativeDis
|
|||
fn get_pixel_format(&self) -> PixelFormat {
|
||||
self.dev.borrow().get_pixel_format()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
use backend::drm::{RawDevice, Device, RawSurface, Surface};
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::egl::error::{Result as EglResult};
|
||||
use backend::drm::{Device, RawDevice, RawSurface, Surface};
|
||||
use backend::egl::error::Result as EglResult;
|
||||
use backend::egl::ffi;
|
||||
use backend::egl::native::{Backend, NativeDisplay, NativeSurface};
|
||||
use backend::graphics::SwapBuffersError;
|
||||
|
||||
use super::{GbmDevice, GbmSurface};
|
||||
use super::error::{Error, Result};
|
||||
use super::{GbmDevice, GbmSurface};
|
||||
|
||||
use drm::control::{crtc, Device as ControlDevice, Mode};
|
||||
use gbm::AsRaw;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Gbm backend type
|
||||
pub struct Gbm<D: RawDevice + 'static>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
_userdata: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: RawDevice + 'static> Backend for Gbm<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
type Surface = Rc<GbmSurface<D>>;
|
||||
|
||||
|
@ -54,7 +54,7 @@ where
|
|||
/// Arguments necessary to construct a `GbmSurface`
|
||||
pub struct SurfaceArguments<D: RawDevice + 'static>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
/// Crtc
|
||||
pub crtc: crtc::Handle,
|
||||
|
@ -64,9 +64,10 @@ where
|
|||
pub connectors: <GbmSurface<D> as Surface>::Connectors,
|
||||
}
|
||||
|
||||
impl<D: RawDevice + 'static> From<(crtc::Handle, Mode, <GbmSurface<D> as Surface>::Connectors)> for SurfaceArguments<D>
|
||||
impl<D: RawDevice + 'static> From<(crtc::Handle, Mode, <GbmSurface<D> as Surface>::Connectors)>
|
||||
for SurfaceArguments<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<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 {
|
||||
|
@ -79,7 +80,7 @@ where
|
|||
|
||||
unsafe impl<D: RawDevice + ControlDevice + 'static> NativeDisplay<Gbm<D>> for GbmDevice<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
type Arguments = SurfaceArguments<D>;
|
||||
type Error = Error;
|
||||
|
@ -99,7 +100,7 @@ where
|
|||
|
||||
unsafe impl<D: RawDevice + 'static> NativeSurface for Rc<GbmSurface<D>>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
fn ptr(&self) -> ffi::NativeWindowType {
|
||||
self.surface.borrow().as_raw() as *const _
|
||||
|
@ -107,7 +108,7 @@ where
|
|||
|
||||
fn swap_buffers<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError>
|
||||
where
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
|
||||
{
|
||||
if ::std::borrow::Borrow::borrow(&self.crtc).commit_pending() {
|
||||
self.recreate(flip).map_err(|_| SwapBuffersError::ContextLost)
|
||||
|
@ -115,4 +116,4 @@ where
|
|||
self.page_flip(flip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,19 +9,19 @@ error_chain! {
|
|||
description("Creation of gbm device failed"),
|
||||
display("Creation of gbm device failed"),
|
||||
}
|
||||
|
||||
|
||||
#[doc = "Creation of gbm surface failed"]
|
||||
SurfaceCreationFailed {
|
||||
description("Creation of gbm surface failed"),
|
||||
display("Creation of gbm surface failed"),
|
||||
}
|
||||
|
||||
|
||||
#[doc = "Creation of gbm buffer object failed"]
|
||||
BufferCreationFailed {
|
||||
description("Creation of gbm buffer object failed"),
|
||||
display("Creation of gbm buffer object failed"),
|
||||
}
|
||||
|
||||
|
||||
#[doc = "Writing to gbm buffer failed"]
|
||||
BufferWriteFailed {
|
||||
description("Writing to gbm buffer failed"),
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use super::{Device, RawDevice, Surface, DeviceHandler};
|
||||
use super::{Device, DeviceHandler, RawDevice, Surface};
|
||||
|
||||
use drm::control::{crtc, framebuffer, Device as ControlDevice, Mode};
|
||||
use gbm::{self, Format as GbmFormat, BufferObjectFlags};
|
||||
use gbm::{self, BufferObjectFlags, Format as GbmFormat};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
pub mod error;
|
||||
use self::error::*;
|
||||
|
@ -25,16 +25,16 @@ static LOAD: Once = ONCE_INIT;
|
|||
/// Representation of an open gbm device to create rendering backends
|
||||
pub struct GbmDevice<D: RawDevice + ControlDevice + 'static>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
pub(in self) dev: Rc<RefCell<gbm::Device<D>>>,
|
||||
pub(self) dev: Rc<RefCell<gbm::Device<D>>>,
|
||||
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<GbmSurface<D>>>>>,
|
||||
logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
impl<D: RawDevice + ControlDevice + 'static> GbmDevice<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
/// Create a new `GbmDevice` from an open drm node
|
||||
///
|
||||
|
@ -56,7 +56,7 @@ where
|
|||
nix::libc::RTLD_LAZY | nix::libc::RTLD_GLOBAL,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
let log = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_gbm"));
|
||||
|
||||
dev.clear_handler();
|
||||
|
@ -64,7 +64,9 @@ where
|
|||
debug!(log, "Creating gbm device");
|
||||
Ok(GbmDevice {
|
||||
// Open the gbm device from the drm device
|
||||
dev: Rc::new(RefCell::new(gbm::Device::new(dev).chain_err(|| ErrorKind::InitFailed)?)),
|
||||
dev: Rc::new(RefCell::new(
|
||||
gbm::Device::new(dev).chain_err(|| ErrorKind::InitFailed)?,
|
||||
)),
|
||||
backends: Rc::new(RefCell::new(HashMap::new())),
|
||||
logger: log,
|
||||
})
|
||||
|
@ -73,16 +75,16 @@ where
|
|||
|
||||
struct InternalDeviceHandler<D: RawDevice + ControlDevice + 'static>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<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>>>>>,
|
||||
logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
impl<D: RawDevice + ControlDevice + 'static> DeviceHandler for InternalDeviceHandler<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
type Device = D;
|
||||
|
||||
|
@ -94,30 +96,35 @@ where
|
|||
self.handler.vblank(&*surface);
|
||||
}
|
||||
} else {
|
||||
warn!(self.logger, "Surface ({:?}) not managed by gbm, event not handled.", surface.crtc());
|
||||
warn!(
|
||||
self.logger,
|
||||
"Surface ({:?}) not managed by gbm, event not handled.",
|
||||
surface.crtc()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn error(&mut self, error: <<D as Device>::Surface as Surface>::Error) {
|
||||
self.handler.error(ResultExt::<()>::chain_err(Err(error), || ErrorKind::UnderlyingBackendError).unwrap_err())
|
||||
self.handler
|
||||
.error(ResultExt::<()>::chain_err(Err(error), || ErrorKind::UnderlyingBackendError).unwrap_err())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: RawDevice + ControlDevice + 'static> Device for GbmDevice<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
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 {
|
||||
handler: Box::new(handler),
|
||||
backends: Rc::downgrade(&self.backends),
|
||||
logger: self.logger.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
fn clear_handler(&mut self) {
|
||||
self.dev.borrow_mut().clear_handler();
|
||||
}
|
||||
|
@ -126,17 +133,20 @@ where
|
|||
&mut self,
|
||||
crtc: crtc::Handle,
|
||||
mode: Mode,
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>,
|
||||
) -> Result<Rc<GbmSurface<D>>> {
|
||||
info!(self.logger, "Initializing GbmSurface");
|
||||
|
||||
let (w, h) = mode.size();
|
||||
let surface = self.dev.borrow().create_surface(
|
||||
w as u32,
|
||||
h as u32,
|
||||
GbmFormat::XRGB8888,
|
||||
BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
||||
).chain_err(|| ErrorKind::SurfaceCreationFailed)?;
|
||||
let surface = self
|
||||
.dev
|
||||
.borrow()
|
||||
.create_surface(
|
||||
w as u32,
|
||||
h as u32,
|
||||
GbmFormat::XRGB8888,
|
||||
BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
||||
).chain_err(|| ErrorKind::SurfaceCreationFailed)?;
|
||||
|
||||
// init the first screen
|
||||
// (must be done before calling page_flip for the first time)
|
||||
|
@ -147,11 +157,13 @@ where
|
|||
debug!(self.logger, "FrontBuffer color format: {:?}", front_bo.format());
|
||||
|
||||
// we need a framebuffer for the front buffer
|
||||
let fb = framebuffer::create(&*self.dev.borrow(), &*front_bo).chain_err(|| ErrorKind::UnderlyingBackendError)?;
|
||||
let fb = framebuffer::create(&*self.dev.borrow(), &*front_bo)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)?;
|
||||
front_bo.set_userdata(fb).unwrap();
|
||||
|
||||
let cursor = Cell::new((
|
||||
self.dev.borrow()
|
||||
self.dev
|
||||
.borrow()
|
||||
.create_buffer_object(
|
||||
1,
|
||||
1,
|
||||
|
@ -177,15 +189,15 @@ where
|
|||
}
|
||||
|
||||
fn process_events(&mut self) {
|
||||
self.dev.borrow_mut().process_events()
|
||||
self.dev.borrow_mut().process_events()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: RawDevice + ControlDevice + 'static> AsRawFd for GbmDevice<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.dev.borrow().as_raw_fd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,29 @@ use drm::control::{crtc, Device as ControlDevice, ResourceInfo};
|
|||
use gbm::BufferObject;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
use backend::session::{AsSessionObserver, SessionObserver};
|
||||
use backend::drm::{Device, RawDevice, RawSurface};
|
||||
use super::{GbmDevice, GbmSurface};
|
||||
use backend::drm::{Device, RawDevice, RawSurface};
|
||||
use backend::session::{AsSessionObserver, SessionObserver};
|
||||
|
||||
/// `SessionObserver` linked to the `DrmDevice` it was created from.
|
||||
pub struct GbmDeviceObserver<
|
||||
S: SessionObserver + 'static,
|
||||
D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static,
|
||||
>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
> where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
observer: S,
|
||||
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<GbmSurface<D>>>>>,
|
||||
logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
impl<
|
||||
S: SessionObserver + 'static,
|
||||
D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static,
|
||||
> AsSessionObserver<GbmDeviceObserver<S, D>> for GbmDevice<D>
|
||||
impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static>
|
||||
AsSessionObserver<GbmDeviceObserver<S, D>> for GbmDevice<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
fn observer(&mut self) -> GbmDeviceObserver<S, D> {
|
||||
GbmDeviceObserver {
|
||||
|
@ -38,12 +35,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
S: SessionObserver + 'static,
|
||||
D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static,
|
||||
> SessionObserver for GbmDeviceObserver<S, D>
|
||||
impl<S: SessionObserver + 'static, D: RawDevice + ControlDevice + AsSessionObserver<S> + 'static>
|
||||
SessionObserver for GbmDeviceObserver<S, D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
fn pause(&mut self, devnum: Option<(u32, u32)>) {
|
||||
self.observer.pause(devnum);
|
||||
|
@ -56,15 +51,17 @@ where
|
|||
for (crtc, backend) in backends.borrow().iter() {
|
||||
if let Some(backend) = backend.upgrade() {
|
||||
// restart rendering loop
|
||||
if let Err(err) =
|
||||
::std::borrow::Borrow::borrow(&backend.crtc).page_flip(backend.current_frame_buffer.get().handle())
|
||||
if let Err(err) = ::std::borrow::Borrow::borrow(&backend.crtc)
|
||||
.page_flip(backend.current_frame_buffer.get().handle())
|
||||
{
|
||||
warn!(self.logger, "Failed to restart rendering loop. Error: {}", err);
|
||||
}
|
||||
// reset cursor
|
||||
{
|
||||
let &(ref cursor, ref hotspot): &(BufferObject<()>, (u32, u32)) =
|
||||
unsafe { &*backend.cursor.as_ptr() };
|
||||
let &(ref cursor, ref hotspot): &(
|
||||
BufferObject<()>,
|
||||
(u32, u32),
|
||||
) = unsafe { &*backend.cursor.as_ptr() };
|
||||
if crtc::set_cursor2(
|
||||
&*backend.dev.borrow(),
|
||||
*crtc,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use super::super::{Device, RawDevice, RawSurface, Surface};
|
||||
use super::error::*;
|
||||
use super::super::{Device, RawDevice, Surface, RawSurface};
|
||||
|
||||
use drm::control::{crtc, connector, framebuffer, Mode, ResourceInfo};
|
||||
use gbm::{self, SurfaceBufferHandle, Format as GbmFormat, BufferObject, BufferObjectFlags};
|
||||
use drm::control::{connector, crtc, framebuffer, Mode, ResourceInfo};
|
||||
use gbm::{self, BufferObject, BufferObjectFlags, Format as GbmFormat, SurfaceBufferHandle};
|
||||
use image::{ImageBuffer, Rgba};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::rc::Rc;
|
||||
|
||||
use backend::drm::legacy::{LegacyDrmDevice, LegacyDrmSurface};
|
||||
use backend::graphics::CursorBackend;
|
||||
|
@ -15,23 +15,23 @@ use backend::graphics::SwapBuffersError;
|
|||
|
||||
pub struct GbmSurface<D: RawDevice + 'static>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
pub(in super) dev: Rc<RefCell<gbm::Device<D>>>,
|
||||
pub(in super) surface: RefCell<gbm::Surface<framebuffer::Info>>,
|
||||
pub(in super) crtc: <D as Device>::Return,
|
||||
pub(in super) cursor: Cell<(BufferObject<()>, (u32, u32))>,
|
||||
pub(in super) current_frame_buffer: Cell<framebuffer::Info>,
|
||||
pub(in super) front_buffer: Cell<SurfaceBufferHandle<framebuffer::Info>>,
|
||||
pub(in super) next_buffer: Cell<Option<SurfaceBufferHandle<framebuffer::Info>>>,
|
||||
pub(in super) logger: ::slog::Logger,
|
||||
pub(super) dev: Rc<RefCell<gbm::Device<D>>>,
|
||||
pub(super) surface: RefCell<gbm::Surface<framebuffer::Info>>,
|
||||
pub(super) crtc: <D as Device>::Return,
|
||||
pub(super) cursor: Cell<(BufferObject<()>, (u32, u32))>,
|
||||
pub(super) current_frame_buffer: Cell<framebuffer::Info>,
|
||||
pub(super) front_buffer: Cell<SurfaceBufferHandle<framebuffer::Info>>,
|
||||
pub(super) next_buffer: Cell<Option<SurfaceBufferHandle<framebuffer::Info>>>,
|
||||
pub(super) logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
impl<D: RawDevice + 'static> GbmSurface<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
pub(in super) fn unlock_buffer(&self) {
|
||||
pub(super) fn unlock_buffer(&self) {
|
||||
// after the page swap is finished we need to release the rendered buffer.
|
||||
// this is called from the PageFlipHandler
|
||||
if let Some(next_buffer) = self.next_buffer.replace(None) {
|
||||
|
@ -43,7 +43,7 @@ where
|
|||
|
||||
pub fn page_flip<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError>
|
||||
where
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
|
||||
{
|
||||
let res = {
|
||||
let nb = self.next_buffer.take();
|
||||
|
@ -53,10 +53,7 @@ where
|
|||
};
|
||||
if res {
|
||||
// We cannot call lock_front_buffer anymore without releasing the previous buffer, which will happen when the page flip is done
|
||||
warn!(
|
||||
self.logger,
|
||||
"Tried to swap with an already queued flip"
|
||||
);
|
||||
warn!(self.logger, "Tried to swap with an already queued flip");
|
||||
return Err(SwapBuffersError::AlreadySwapped);
|
||||
}
|
||||
|
||||
|
@ -99,16 +96,13 @@ where
|
|||
|
||||
pub fn recreate<F>(&self, flip: F) -> Result<()>
|
||||
where
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
|
||||
{
|
||||
let (w, h) = self.pending_mode().size();
|
||||
|
||||
// Recreate the surface and the related resources to match the new
|
||||
// resolution.
|
||||
debug!(
|
||||
self.logger,
|
||||
"Reinitializing surface for new mode: {}:{}", w, h
|
||||
);
|
||||
debug!(self.logger, "Reinitializing surface for new mode: {}:{}", w, h);
|
||||
let surface = self
|
||||
.dev
|
||||
.borrow_mut()
|
||||
|
@ -125,7 +119,9 @@ where
|
|||
{
|
||||
if let Some(mut old_bo) = self.next_buffer.take() {
|
||||
if let Ok(Some(fb)) = old_bo.take_userdata() {
|
||||
if let Err(err) = framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle()) {
|
||||
if let Err(err) =
|
||||
framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle())
|
||||
{
|
||||
warn!(
|
||||
self.logger,
|
||||
"Error releasing old back_buffer framebuffer: {:?}", err
|
||||
|
@ -142,17 +138,14 @@ where
|
|||
.lock_front_buffer()
|
||||
.chain_err(|| ErrorKind::FrontBufferLockFailed)?;
|
||||
|
||||
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
|
||||
let fb = framebuffer::create(::std::borrow::Borrow::borrow(&self.crtc), &*front_bo)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)?;
|
||||
|
||||
::std::borrow::Borrow::borrow(&self.crtc).commit(fb.handle())
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.commit(fb.handle())
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)?;
|
||||
|
||||
front_bo.set_userdata(fb).unwrap();
|
||||
|
@ -169,31 +162,28 @@ where
|
|||
|
||||
// Drop the old surface after cleanup
|
||||
*self.surface.borrow_mut() = surface;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: RawDevice + 'static> Surface for GbmSurface<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
type Connectors = <<D as Device>::Surface as Surface>::Connectors;
|
||||
type Error = Error;
|
||||
|
||||
fn crtc(&self) -> crtc::Handle {
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.crtc()
|
||||
::std::borrow::Borrow::borrow(&self.crtc).crtc()
|
||||
}
|
||||
|
||||
fn current_connectors(&self) -> Self::Connectors {
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.current_connectors()
|
||||
::std::borrow::Borrow::borrow(&self.crtc).current_connectors()
|
||||
}
|
||||
|
||||
|
||||
fn pending_connectors(&self) -> Self::Connectors {
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.pending_connectors()
|
||||
::std::borrow::Borrow::borrow(&self.crtc).pending_connectors()
|
||||
}
|
||||
|
||||
fn add_connector(&self, connector: connector::Handle) -> Result<()> {
|
||||
|
@ -207,15 +197,13 @@ where
|
|||
.remove_connector(connector)
|
||||
.chain_err(|| ErrorKind::UnderlyingBackendError)
|
||||
}
|
||||
|
||||
|
||||
fn current_mode(&self) -> Mode {
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.current_mode()
|
||||
::std::borrow::Borrow::borrow(&self.crtc).current_mode()
|
||||
}
|
||||
|
||||
|
||||
fn pending_mode(&self) -> Mode {
|
||||
::std::borrow::Borrow::borrow(&self.crtc)
|
||||
.pending_mode()
|
||||
::std::borrow::Borrow::borrow(&self.crtc).pending_mode()
|
||||
}
|
||||
|
||||
fn use_mode(&self, mode: Mode) -> Result<()> {
|
||||
|
@ -257,9 +245,9 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
|
|||
|
||||
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
|
||||
ResultExt::chain_err(
|
||||
::std::borrow::Borrow::<Rc<LegacyDrmSurface<A>>>::borrow(&self.crtc)
|
||||
.set_cursor_position(x, y),
|
||||
|| ErrorKind::UnderlyingBackendError)
|
||||
::std::borrow::Borrow::<Rc<LegacyDrmSurface<A>>>::borrow(&self.crtc).set_cursor_position(x, y),
|
||||
|| ErrorKind::UnderlyingBackendError,
|
||||
)
|
||||
}
|
||||
|
||||
fn set_cursor_representation<'b>(
|
||||
|
@ -267,7 +255,8 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
|
|||
buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>,
|
||||
hotspot: (u32, u32),
|
||||
) -> Result<()>
|
||||
where 'a: 'b
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let (w, h) = buffer.dimensions();
|
||||
debug!(self.logger, "Importing cursor");
|
||||
|
@ -293,7 +282,8 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
|
|||
ResultExt::chain_err(
|
||||
::std::borrow::Borrow::<Rc<LegacyDrmSurface<A>>>::borrow(&self.crtc)
|
||||
.set_cursor_representation(&cursor, hotspot),
|
||||
|| ErrorKind::UnderlyingBackendError)?;
|
||||
|| ErrorKind::UnderlyingBackendError,
|
||||
)?;
|
||||
|
||||
// and store it
|
||||
self.cursor.set((cursor, hotspot));
|
||||
|
@ -303,7 +293,7 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for GbmSurface<LegacyDrmDevice<
|
|||
|
||||
impl<D: RawDevice + 'static> Drop for GbmSurface<D>
|
||||
where
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>
|
||||
<D as Device>::Return: ::std::borrow::Borrow<<D as RawDevice>::Surface>,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
// Drop framebuffers attached to the userdata of the gbm surface buffers.
|
||||
|
@ -326,4 +316,4 @@ where
|
|||
let _ = framebuffer::destroy(::std::borrow::Borrow::borrow(&self.crtc), fb.handle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use super::{Device, RawDevice, Surface, DeviceHandler, DevPath};
|
||||
use super::{DevPath, Device, DeviceHandler, RawDevice, Surface};
|
||||
|
||||
use drm::control::{connector, crtc, encoder, Device as ControlDevice, Mode, ResourceInfo};
|
||||
use drm::Device as BasicDevice;
|
||||
use drm::control::{crtc, connector, encoder, Device as ControlDevice, Mode, ResourceInfo};
|
||||
use nix::libc::dev_t;
|
||||
use nix::sys::stat::fstat;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
mod surface;
|
||||
pub use self::surface::LegacyDrmSurface;
|
||||
|
@ -29,7 +29,7 @@ pub struct LegacyDrmDevice<A: AsRawFd + 'static> {
|
|||
active: Arc<AtomicBool>,
|
||||
old_state: HashMap<crtc::Handle, (crtc::Info, Vec<connector::Handle>)>,
|
||||
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<LegacyDrmSurface<A>>>>>,
|
||||
handler: Option<RefCell<Box<DeviceHandler<Device=LegacyDrmDevice<A>>>>>,
|
||||
handler: Option<RefCell<Box<DeviceHandler<Device = LegacyDrmDevice<A>>>>>,
|
||||
logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
|
@ -122,10 +122,10 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<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)));
|
||||
}
|
||||
|
||||
|
||||
fn clear_handler(&mut self) {
|
||||
let _ = self.handler.take();
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
|||
&mut self,
|
||||
crtc: crtc::Handle,
|
||||
mode: Mode,
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>,
|
||||
) -> Result<Rc<LegacyDrmSurface<A>>> {
|
||||
if self.backends.borrow().contains_key(&crtc) {
|
||||
bail!(ErrorKind::CrtcAlreadyInUse(crtc));
|
||||
|
@ -181,11 +181,8 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
|||
|
||||
// configuration is valid, the kernel will figure out the rest
|
||||
let logger = self.logger.new(o!("crtc" => format!("{:?}", crtc)));
|
||||
|
||||
let state = State {
|
||||
mode,
|
||||
connectors,
|
||||
};
|
||||
|
||||
let state = State { mode, connectors };
|
||||
|
||||
let backend = Rc::new(LegacyDrmSurface {
|
||||
dev: self.dev.clone(),
|
||||
|
@ -194,17 +191,24 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
|||
pending: RwLock::new(state),
|
||||
logger,
|
||||
});
|
||||
|
||||
|
||||
self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend));
|
||||
Ok(backend)
|
||||
}
|
||||
|
||||
|
||||
fn process_events(&mut self) {
|
||||
match crtc::receive_events(self) {
|
||||
Ok(events) => for event in events {
|
||||
if let crtc::Event::PageFlip(event) = event {
|
||||
if self.active.load(Ordering::SeqCst) {
|
||||
if let Some(backend) = self.backends.borrow().get(&event.crtc).iter().flat_map(|x| x.upgrade()).next() {
|
||||
if let Some(backend) = self
|
||||
.backends
|
||||
.borrow()
|
||||
.get(&event.crtc)
|
||||
.iter()
|
||||
.flat_map(|x| x.upgrade())
|
||||
.next()
|
||||
{
|
||||
trace!(self.logger, "Handling event for backend {:?}", event.crtc);
|
||||
if let Some(handler) = self.handler.as_ref() {
|
||||
handler.borrow_mut().vblank(&backend);
|
||||
|
@ -216,10 +220,12 @@ impl<A: AsRawFd + 'static> Device for LegacyDrmDevice<A> {
|
|||
}
|
||||
},
|
||||
Err(err) => if let Some(handler) = self.handler.as_ref() {
|
||||
handler.borrow_mut().error(ResultExt::<()>::chain_err(Err(err), ||
|
||||
ErrorKind::DrmDev(format!("Error processing drm events on {:?}", self.dev_path()))
|
||||
).unwrap_err());
|
||||
}
|
||||
handler.borrow_mut().error(
|
||||
ResultExt::<()>::chain_err(Err(err), || {
|
||||
ErrorKind::DrmDev(format!("Error processing drm events on {:?}", self.dev_path()))
|
||||
}).unwrap_err(),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use drm::control::{connector, crtc, Device as ControlDevice};
|
||||
use drm::Device as BasicDevice;
|
||||
use drm::control::{crtc, connector, Device as ControlDevice};
|
||||
use nix::libc::dev_t;
|
||||
use nix::sys::stat;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{Dev, LegacyDrmDevice, LegacyDrmSurface};
|
||||
use backend::session::{AsSessionObserver, SessionObserver};
|
||||
use super::{LegacyDrmDevice, LegacyDrmSurface, Dev};
|
||||
|
||||
/// `SessionObserver` linked to the `DrmDevice` it was created from.
|
||||
pub struct LegacyDrmDeviceObserver<A: AsRawFd + 'static> {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use drm::Device as BasicDevice;
|
||||
use drm::control::{connector, crtc, encoder, framebuffer, Device as ControlDevice, Mode, ResourceInfo};
|
||||
pub use drm::buffer::Buffer;
|
||||
use drm::control::{connector, crtc, encoder, framebuffer, Device as ControlDevice, Mode, ResourceInfo};
|
||||
use drm::Device as BasicDevice;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::rc::Rc;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use backend::drm::{RawSurface, Surface, DevPath};
|
||||
use backend::drm::{DevPath, RawSurface, Surface};
|
||||
use backend::graphics::CursorBackend;
|
||||
use backend::graphics::SwapBuffersError;
|
||||
|
||||
use super::{Dev, error::*};
|
||||
use super::{error::*, Dev};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct State {
|
||||
|
@ -20,11 +20,11 @@ pub struct State {
|
|||
}
|
||||
|
||||
pub struct LegacyDrmSurface<A: AsRawFd + 'static> {
|
||||
pub(in super) dev: Rc<Dev<A>>,
|
||||
pub(in super) crtc: crtc::Handle,
|
||||
pub(in super) state: RwLock<State>,
|
||||
pub(in super) pending: RwLock<State>,
|
||||
pub(in super) logger: ::slog::Logger,
|
||||
pub(super) dev: Rc<Dev<A>>,
|
||||
pub(super) crtc: crtc::Handle,
|
||||
pub(super) state: RwLock<State>,
|
||||
pub(super) pending: RwLock<State>,
|
||||
pub(super) logger: ::slog::Logger,
|
||||
}
|
||||
|
||||
impl<A: AsRawFd + 'static> AsRawFd for LegacyDrmSurface<A> {
|
||||
|
@ -42,36 +42,19 @@ impl<'a, A: AsRawFd + 'static> CursorBackend<'a> for LegacyDrmSurface<A> {
|
|||
|
||||
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
|
||||
trace!(self.logger, "Move the cursor to {},{}", x, y);
|
||||
crtc::move_cursor(self, self.crtc, (x as i32, y as i32)).chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Error moving cursor on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
})
|
||||
crtc::move_cursor(self, self.crtc, (x as i32, y as i32))
|
||||
.chain_err(|| ErrorKind::DrmDev(format!("Error moving cursor on {:?}", self.dev_path())))
|
||||
}
|
||||
|
||||
fn set_cursor_representation<'b>(
|
||||
&'b self,
|
||||
buffer: Self::CursorFormat,
|
||||
hotspot: (u32, u32),
|
||||
) -> Result<()>
|
||||
where 'a: 'b
|
||||
fn set_cursor_representation<'b>(&'b self, buffer: Self::CursorFormat, hotspot: (u32, u32)) -> Result<()>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
trace!(self.logger, "Setting the new imported cursor");
|
||||
|
||||
if crtc::set_cursor2(
|
||||
self,
|
||||
self.crtc,
|
||||
buffer,
|
||||
(hotspot.0 as i32, hotspot.1 as i32),
|
||||
).is_err()
|
||||
{
|
||||
crtc::set_cursor(self, self.crtc, buffer).chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Failed to set cursor on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
})?;
|
||||
if crtc::set_cursor2(self, self.crtc, buffer, (hotspot.0 as i32, hotspot.1 as i32)).is_err() {
|
||||
crtc::set_cursor(self, self.crtc, buffer)
|
||||
.chain_err(|| ErrorKind::DrmDev(format!("Failed to set cursor on {:?}", self.dev_path())))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -85,11 +68,11 @@ impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
|
|||
fn crtc(&self) -> crtc::Handle {
|
||||
self.crtc
|
||||
}
|
||||
|
||||
|
||||
fn current_connectors(&self) -> Self::Connectors {
|
||||
self.state.read().unwrap().connectors.clone()
|
||||
}
|
||||
|
||||
|
||||
fn pending_connectors(&self) -> Self::Connectors {
|
||||
self.pending.read().unwrap().connectors.clone()
|
||||
}
|
||||
|
@ -104,10 +87,7 @@ impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
|
|||
|
||||
fn add_connector(&self, connector: connector::Handle) -> Result<()> {
|
||||
let info = connector::Info::load_from_device(self, connector).chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Error loading connector info on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
ErrorKind::DrmDev(format!("Error loading connector info on {:?}", self.dev_path()))
|
||||
})?;
|
||||
|
||||
let mut pending = self.pending.write().unwrap();
|
||||
|
@ -120,28 +100,19 @@ impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
|
|||
.iter()
|
||||
.map(|encoder| {
|
||||
encoder::Info::load_from_device(self, *encoder).chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Error loading encoder info on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
ErrorKind::DrmDev(format!("Error loading encoder info on {:?}", self.dev_path()))
|
||||
})
|
||||
}).collect::<Result<Vec<encoder::Info>>>()?;
|
||||
|
||||
// and if any encoder supports the selected crtc
|
||||
let resource_handles = self.resource_handles().chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Error loading resources on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
ErrorKind::DrmDev(format!("Error loading resources on {:?}", self.dev_path()))
|
||||
})?;
|
||||
if !encoders
|
||||
.iter()
|
||||
.map(|encoder| encoder.possible_crtcs())
|
||||
.all(|crtc_list| {
|
||||
resource_handles
|
||||
.filter_crtcs(crtc_list)
|
||||
.contains(&self.crtc)
|
||||
}) {
|
||||
.all(|crtc_list| resource_handles.filter_crtcs(crtc_list).contains(&self.crtc))
|
||||
{
|
||||
bail!(ErrorKind::NoSuitableEncoder(info, self.crtc));
|
||||
}
|
||||
|
||||
|
@ -159,15 +130,12 @@ impl<A: AsRawFd + 'static> Surface for LegacyDrmSurface<A> {
|
|||
|
||||
fn use_mode(&self, mode: Mode) -> Result<()> {
|
||||
let mut pending = self.pending.write().unwrap();
|
||||
|
||||
|
||||
// check the connectors
|
||||
for connector in &pending.connectors {
|
||||
if !connector::Info::load_from_device(self, *connector)
|
||||
.chain_err(|| {
|
||||
ErrorKind::DrmDev(format!(
|
||||
"Error loading connector info on {:?}",
|
||||
self.dev_path()
|
||||
))
|
||||
ErrorKind::DrmDev(format!("Error loading connector info on {:?}", self.dev_path()))
|
||||
})?.modes()
|
||||
.contains(&mode)
|
||||
{
|
||||
|
@ -185,7 +153,7 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
|
|||
fn commit_pending(&self) -> bool {
|
||||
*self.pending.read().unwrap() != *self.state.read().unwrap()
|
||||
}
|
||||
|
||||
|
||||
fn commit(&self, framebuffer: framebuffer::Handle) -> Result<()> {
|
||||
let mut current = self.state.write().unwrap();
|
||||
let pending = self.pending.read().unwrap();
|
||||
|
@ -196,11 +164,7 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
|
|||
|
||||
for conn in removed {
|
||||
if let Ok(info) = connector::Info::load_from_device(self, *conn) {
|
||||
info!(
|
||||
self.logger,
|
||||
"Removing connector: {:?}",
|
||||
info.connector_type()
|
||||
);
|
||||
info!(self.logger, "Removing connector: {:?}", info.connector_type());
|
||||
} else {
|
||||
info!(self.logger, "Removing unknown connector");
|
||||
}
|
||||
|
@ -208,11 +172,7 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
|
|||
|
||||
for conn in added {
|
||||
if let Ok(info) = connector::Info::load_from_device(self, *conn) {
|
||||
info!(
|
||||
self.logger,
|
||||
"Adding connector: {:?}",
|
||||
info.connector_type()
|
||||
);
|
||||
info!(self.logger, "Adding connector: {:?}", info.connector_type());
|
||||
} else {
|
||||
info!(self.logger, "Adding unknown connector");
|
||||
}
|
||||
|
@ -228,7 +188,11 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
|
|||
self,
|
||||
self.crtc,
|
||||
framebuffer,
|
||||
&pending.connectors.iter().map(|x| *x).collect::<Vec<connector::Handle>>(),
|
||||
&pending
|
||||
.connectors
|
||||
.iter()
|
||||
.map(|x| *x)
|
||||
.collect::<Vec<connector::Handle>>(),
|
||||
(0, 0),
|
||||
Some(pending.mode),
|
||||
).chain_err(|| {
|
||||
|
@ -243,7 +207,7 @@ impl<A: AsRawFd + 'static> RawSurface for LegacyDrmSurface<A> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn page_flip(&self, framebuffer: framebuffer::Handle) -> ::std::result::Result<(), SwapBuffersError> {
|
||||
trace!(self.logger, "Queueing Page flip");
|
||||
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
use drm::Device as BasicDevice;
|
||||
use drm::control::Device as ControlDevice;
|
||||
pub use drm::control::crtc;
|
||||
pub use drm::control::connector;
|
||||
pub use drm::control::crtc;
|
||||
pub use drm::control::framebuffer;
|
||||
use drm::control::Device as ControlDevice;
|
||||
pub use drm::control::Mode;
|
||||
use drm::Device as BasicDevice;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use wayland_server::calloop::generic::{EventedFd, Generic};
|
||||
use wayland_server::calloop::{LoopHandle, Source};
|
||||
use wayland_server::calloop::mio::Ready;
|
||||
pub use wayland_server::calloop::InsertError;
|
||||
use wayland_server::calloop::{LoopHandle, Source};
|
||||
|
||||
use super::graphics::SwapBuffersError;
|
||||
|
||||
#[cfg(feature = "backend_drm_legacy")]
|
||||
pub mod legacy;
|
||||
#[cfg(feature = "backend_drm_gbm")]
|
||||
pub mod gbm;
|
||||
#[cfg(feature = "backend_drm_egl")]
|
||||
pub mod egl;
|
||||
#[cfg(feature = "backend_drm_gbm")]
|
||||
pub mod gbm;
|
||||
#[cfg(feature = "backend_drm_legacy")]
|
||||
pub mod legacy;
|
||||
|
||||
pub trait DeviceHandler {
|
||||
type Device: Device + ?Sized;
|
||||
|
@ -34,26 +34,26 @@ pub trait Device: AsRawFd + DevPath {
|
|||
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 create_surface(
|
||||
&mut self,
|
||||
ctrc: crtc::Handle,
|
||||
mode: Mode,
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>
|
||||
connectors: impl Into<<Self::Surface as Surface>::Connectors>,
|
||||
) -> Result<Self::Return, <Self::Surface as Surface>::Error>;
|
||||
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>
|
||||
<Self as Device>::Return: Borrow<<Self as RawDevice>::Surface>,
|
||||
{
|
||||
type Surface: RawSurface;
|
||||
}
|
||||
|
||||
pub trait Surface {
|
||||
type Connectors: IntoIterator<Item=connector::Handle>;
|
||||
type Connectors: IntoIterator<Item = connector::Handle>;
|
||||
type Error: Error + Send;
|
||||
|
||||
fn crtc(&self) -> crtc::Handle;
|
||||
|
@ -70,7 +70,7 @@ pub trait RawSurface: Surface + ControlDevice + BasicDevice {
|
|||
fn commit_pending(&self) -> bool;
|
||||
fn commit(&self, framebuffer: framebuffer::Handle) -> Result<(), <Self as Surface>::Error>;
|
||||
fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), SwapBuffersError>;
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for types representing open devices
|
||||
pub trait DevPath {
|
||||
|
@ -82,7 +82,7 @@ impl<A: AsRawFd> DevPath for A {
|
|||
fn dev_path(&self) -> Option<PathBuf> {
|
||||
use std::fs;
|
||||
|
||||
fs::read_link(format!("/proc/self/fd/{:?}", self.as_raw_fd())).ok()
|
||||
fs::read_link(format!("/proc/self/fd/{:?}", self.as_raw_fd())).ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,14 +52,8 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
|||
{
|
||||
let log = ::slog_or_stdlog(logger.into()).new(o!("smithay_module" => "renderer_egl"));
|
||||
let ptr = native.ptr()?;
|
||||
let (
|
||||
context,
|
||||
display,
|
||||
config_id,
|
||||
surface_attributes,
|
||||
pixel_format,
|
||||
wl_drm_support,
|
||||
) = unsafe { EGLContext::<B, N>::new_internal(ptr, attributes, reqs, log.clone()) }?;
|
||||
let (context, display, config_id, surface_attributes, pixel_format, wl_drm_support) =
|
||||
unsafe { EGLContext::<B, N>::new_internal(ptr, attributes, reqs, log.clone()) }?;
|
||||
|
||||
Ok(EGLContext {
|
||||
native,
|
||||
|
@ -117,15 +111,15 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
|||
bail!(ErrorKind::OpenGlVersionNotSupported(version));
|
||||
}
|
||||
};
|
||||
|
||||
fn constrain<F>(f: F) -> F
|
||||
where
|
||||
F: for<'a> Fn(&'a str) -> *const ::std::os::raw::c_void,
|
||||
{
|
||||
f
|
||||
};
|
||||
|
||||
|
||||
ffi::egl::LOAD.call_once(|| {
|
||||
fn constrain<F>(f: F) -> F
|
||||
where
|
||||
F: for<'a> Fn(&'a str) -> *const ::std::os::raw::c_void,
|
||||
{
|
||||
f
|
||||
};
|
||||
|
||||
ffi::egl::load_with(|sym| {
|
||||
let name = CString::new(sym).unwrap();
|
||||
let symbol = ffi::egl::LIB.get::<*mut c_void>(name.as_bytes());
|
||||
|
@ -144,7 +138,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
|||
ffi::egl::UnbindWaylandDisplayWL::load_with(&proc_address);
|
||||
ffi::egl::QueryWaylandBufferWL::load_with(&proc_address);
|
||||
});
|
||||
|
||||
|
||||
// the first step is to query the list of extensions without any display, if supported
|
||||
let dp_extensions = {
|
||||
let p = ffi::egl::QueryString(ffi::egl::NO_DISPLAY, ffi::egl::EXTENSIONS as i32);
|
||||
|
@ -437,13 +431,11 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
|||
/// Creates a surface for rendering
|
||||
pub fn create_surface(&mut self, args: N::Arguments) -> Result<EGLSurface<B::Surface>> {
|
||||
trace!(self.logger, "Creating EGL window surface.");
|
||||
let surface = self.native
|
||||
.create_surface(args)
|
||||
.chain_err(|| ErrorKind::SurfaceCreationFailed)?;
|
||||
EGLSurface::new(
|
||||
self,
|
||||
surface,
|
||||
).map(|x| {
|
||||
let surface = self
|
||||
.native
|
||||
.create_surface(args)
|
||||
.chain_err(|| ErrorKind::SurfaceCreationFailed)?;
|
||||
EGLSurface::new(self, surface).map(|x| {
|
||||
debug!(self.logger, "EGL surface successfully created");
|
||||
x
|
||||
})
|
||||
|
|
|
@ -181,7 +181,9 @@ impl ::std::error::Error for TextureCreationError {
|
|||
match *self {
|
||||
TextureCreationError::ContextLost => "The context has been lost, it needs to be recreated",
|
||||
TextureCreationError::PlaneIndexOutOfBounds => "This buffer is not managed by EGL",
|
||||
TextureCreationError::GLExtensionNotSupported(_) => "Required OpenGL Extension for texture creation is missing",
|
||||
TextureCreationError::GLExtensionNotSupported(_) => {
|
||||
"Required OpenGL Extension for texture creation is missing"
|
||||
}
|
||||
TextureCreationError::TextureBindingFailed(_) => "Failed to create EGLImages from the buffer",
|
||||
}
|
||||
}
|
||||
|
@ -263,7 +265,7 @@ impl EGLImages {
|
|||
if !self.egl_to_texture_support {
|
||||
return Err(TextureCreationError::GLExtensionNotSupported("GL_OES_EGL_image"));
|
||||
}
|
||||
|
||||
|
||||
let mut old_tex_id: i32 = 0;
|
||||
self.gl.GetIntegerv(gl_ffi::TEXTURE_BINDING_2D, &mut old_tex_id);
|
||||
self.gl.BindTexture(gl_ffi::TEXTURE_2D, tex_id);
|
||||
|
@ -343,11 +345,12 @@ impl EGLDisplay {
|
|||
#[cfg(feature = "renderer_gl")]
|
||||
egl_to_texture_support: {
|
||||
// the list of gl extensions supported by the context
|
||||
let data = unsafe { CStr::from_ptr(gl.GetString(gl_ffi::EXTENSIONS) as *const _ )}
|
||||
let data = unsafe { CStr::from_ptr(gl.GetString(gl_ffi::EXTENSIONS) as *const _) }
|
||||
.to_bytes()
|
||||
.to_vec();
|
||||
let list = String::from_utf8(data).unwrap();
|
||||
list.split(' ').any(|s| s == "GL_OES_EGL_image" || s == "GL_OES_EGL_image_base")
|
||||
list.split(' ')
|
||||
.any(|s| s == "GL_OES_EGL_image" || s == "GL_OES_EGL_image_base")
|
||||
},
|
||||
#[cfg(feature = "renderer_gl")]
|
||||
gl,
|
||||
|
@ -496,4 +499,4 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLGraphicsBackend for EGL
|
|||
}
|
||||
Ok(EGLDisplay::new(self, display.c_ptr()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,9 +169,10 @@ pub unsafe trait NativeSurface {
|
|||
fn ptr(&self) -> ffi::NativeWindowType;
|
||||
/// Adds additional semantics when calling EGLSurface::swap_buffers
|
||||
///
|
||||
/// Only implement if required by the backend, flip must be called during this call.
|
||||
/// Only implement if required by the backend, flip must be called during this call.
|
||||
fn swap_buffers<F>(&self, flip: F) -> ::std::result::Result<(), SwapBuffersError>
|
||||
where F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>
|
||||
where
|
||||
F: FnOnce() -> ::std::result::Result<(), SwapBuffersError>,
|
||||
{
|
||||
flip()
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ impl<N: native::NativeSurface> EGLSurface<N> {
|
|||
err => Err(SwapBuffersError::Unknown(err)),
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Err(SwapBuffersError::ContextLost)
|
||||
|
|
|
@ -29,5 +29,6 @@ pub trait CursorBackend<'a> {
|
|||
cursor: Self::CursorFormat,
|
||||
hotspot: (u32, u32),
|
||||
) -> Result<(), Self::Error>
|
||||
where 'a: 'b;
|
||||
}
|
||||
where
|
||||
'a: 'b;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::fmt;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
/// Error that can happen when swapping buffers.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
@ -43,4 +43,3 @@ impl Error for SwapBuffersError {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,10 +67,10 @@ pub trait GLGraphicsBackend {
|
|||
}
|
||||
|
||||
/// Loads a Raw GLES Interface for a given `GLGraphicsBackend`
|
||||
///
|
||||
///
|
||||
/// This remains valid as long as the underlying `GLGraphicsBackend` is alive
|
||||
/// and may only be used in combination with the backend. Using this with any
|
||||
/// other gl context may cause undefined behavior.
|
||||
pub fn load_raw_gl<B: GLGraphicsBackend>(backend: &B) -> Gles2 {
|
||||
Gles2::load_with(|s| unsafe { backend.get_proc_address(s) as *const _ })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
//! Glium compatibility module
|
||||
|
||||
use backend::graphics::{
|
||||
gl::GLGraphicsBackend,
|
||||
SwapBuffersError,
|
||||
};
|
||||
use backend::graphics::{gl::GLGraphicsBackend, SwapBuffersError};
|
||||
use glium::{
|
||||
backend::{Backend, Context, Facade},
|
||||
debug::DebugCallbackBehavior,
|
||||
|
|
|
@ -16,13 +16,16 @@ use std::{
|
|||
use wayland_server::calloop::{
|
||||
generic::{EventedFd, Generic},
|
||||
mio::Ready,
|
||||
LoopHandle, Source, InsertError,
|
||||
InsertError, LoopHandle, Source,
|
||||
};
|
||||
|
||||
// No idea if this is the same across unix platforms
|
||||
// Lets make this linux exclusive for now, once someone tries to build it for
|
||||
// any BSD-like system, they can verify if this is right and make a PR to change this.
|
||||
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "backend_session"))]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "android"),
|
||||
feature = "backend_session"
|
||||
))]
|
||||
const INPUT_MAJOR: u32 = 13;
|
||||
|
||||
/// Libinput based `InputBackend`.
|
||||
|
@ -600,13 +603,16 @@ impl AsRawFd for LibinputInputBackend {
|
|||
pub fn libinput_bind<Data: 'static>(
|
||||
backend: LibinputInputBackend,
|
||||
handle: LoopHandle<Data>,
|
||||
) -> ::std::result::Result<Source<Generic<EventedFd<LibinputInputBackend>>>, InsertError<Generic<EventedFd<LibinputInputBackend>>>> {
|
||||
) -> ::std::result::Result<
|
||||
Source<Generic<EventedFd<LibinputInputBackend>>>,
|
||||
InsertError<Generic<EventedFd<LibinputInputBackend>>>,
|
||||
> {
|
||||
let mut source = Generic::from_fd_source(backend);
|
||||
source.set_interest(Ready::readable());
|
||||
|
||||
handle.insert_source(source, move |evt, _| {
|
||||
use backend::input::InputBackend;
|
||||
|
||||
|
||||
let mut backend = evt.source.borrow_mut();
|
||||
if let Err(error) = backend.0.dispatch_new_events() {
|
||||
warn!(backend.0.logger, "Libinput errored: {}", error);
|
||||
|
|
|
@ -21,7 +21,7 @@ use udev::{Context, Enumerator, EventType, MonitorBuilder, MonitorSocket, Result
|
|||
use wayland_server::calloop::{
|
||||
generic::{EventedFd, Generic},
|
||||
mio::Ready,
|
||||
LoopHandle, Source, InsertError,
|
||||
InsertError, LoopHandle, Source,
|
||||
};
|
||||
|
||||
/// Backend to monitor available drm devices.
|
||||
|
@ -48,7 +48,7 @@ impl<T: UdevHandler + 'static> UdevBackend<T> {
|
|||
/// ## Arguments
|
||||
/// `context` - An initialized udev context
|
||||
/// `handler` - User-provided handler to respond to any detected changes
|
||||
/// `seat` -
|
||||
/// `seat` -
|
||||
/// `logger` - slog Logger to be used by the backend and its `DrmDevices`.
|
||||
pub fn new<L, S: AsRef<str>>(
|
||||
context: &Context,
|
||||
|
@ -66,15 +66,14 @@ impl<T: UdevHandler + 'static> UdevBackend<T> {
|
|||
// Create devices
|
||||
.flat_map(|path| match stat(&path) {
|
||||
Ok(stat) => {
|
||||
handler.device_added(stat.st_rdev, path);
|
||||
handler.device_added(stat.st_rdev, path);
|
||||
Some(stat.st_rdev)
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(log, "Unable to get id of {:?}, Error: {:?}. Skipping", path, err);
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}).collect();
|
||||
|
||||
let mut builder = MonitorBuilder::new(context)?;
|
||||
builder.match_subsystem("drm")?;
|
||||
|
@ -89,8 +88,7 @@ impl<T: UdevHandler + 'static> UdevBackend<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: UdevHandler + 'static> Drop for UdevBackend<T>
|
||||
{
|
||||
impl<T: UdevHandler + 'static> Drop for UdevBackend<T> {
|
||||
fn drop(&mut self) {
|
||||
for device in &self.devices {
|
||||
self.handler.device_removed(*device);
|
||||
|
@ -105,8 +103,7 @@ impl<T: UdevHandler + 'static> Drop for UdevBackend<T>
|
|||
pub fn udev_backend_bind<T: UdevHandler + 'static, Data: 'static>(
|
||||
handle: &LoopHandle<Data>,
|
||||
udev: UdevBackend<T>,
|
||||
) -> Result<Source<Generic<EventedFd<UdevBackend<T>>>>, InsertError<Generic<EventedFd<UdevBackend<T>>>>>
|
||||
{
|
||||
) -> Result<Source<Generic<EventedFd<UdevBackend<T>>>>, InsertError<Generic<EventedFd<UdevBackend<T>>>>> {
|
||||
let mut source = Generic::from_fd_source(udev);
|
||||
source.set_interest(Ready::readable());
|
||||
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
//! Implementation of backend traits for types provided by `winit`
|
||||
|
||||
use backend::{
|
||||
egl::{
|
||||
context::GlAttributes, error as egl_error, error::Result as EGLResult, native, EGLContext,
|
||||
EGLDisplay, EGLGraphicsBackend, EGLSurface,
|
||||
},
|
||||
graphics::{
|
||||
gl::{GLGraphicsBackend, PixelFormat},
|
||||
CursorBackend,
|
||||
SwapBuffersError,
|
||||
},
|
||||
egl::{
|
||||
context::GlAttributes,
|
||||
error as egl_error,
|
||||
error::Result as EGLResult,
|
||||
native,
|
||||
EGLDisplay, EGLContext, EGLGraphicsBackend, EGLSurface,
|
||||
CursorBackend, SwapBuffersError,
|
||||
},
|
||||
input::{
|
||||
Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
||||
|
@ -246,7 +242,8 @@ impl<'a> CursorBackend<'a> for WinitGraphicsBackend {
|
|||
cursor: Self::CursorFormat,
|
||||
_hotspot: (u32, u32),
|
||||
) -> ::std::result::Result<(), ()>
|
||||
where 'a: 'b
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
|
||||
debug!(self.logger, "Changing cursor representation");
|
||||
|
|
Loading…
Reference in New Issue