diff --git a/src/backend/drm/egl/mod.rs b/src/backend/drm/egl/mod.rs index 61614a1..ce68d57 100644 --- a/src/backend/drm/egl/mod.rs +++ b/src/backend/drm/egl/mod.rs @@ -11,7 +11,10 @@ use drm::control::{connector, crtc, encoder, framebuffer, plane, Mode, ResourceHandles}; use drm::SystemError as DrmError; use nix::libc::dev_t; +use std::cell::RefCell; +use std::collections::HashMap; use std::os::unix::io::{AsRawFd, RawFd}; +use std::rc::{Rc, Weak}; #[cfg(feature = "use_system_lib")] use wayland_server::Display; @@ -58,6 +61,7 @@ where logger: ::slog::Logger, default_attributes: GlAttributes, default_requirements: PixelFormatRequirements, + backends: Rc::Surface>>>>>, } impl AsRawFd for EglDevice @@ -125,6 +129,7 @@ where dev: EGLDisplay::new(dev, log.clone()).map_err(Error::EGL)?, default_attributes, default_requirements, + backends: Rc::new(RefCell::new(HashMap::new())), logger: log, }) } @@ -208,7 +213,9 @@ where SurfaceCreationError::NativeSurfaceCreationFailed(err) => Error::Underlying(err), })?; - Ok(EglSurface { context, surface }) + let backend = Rc::new(EglSurfaceInternal { context, surface }); + self.backends.borrow_mut().insert(crtc, Rc::downgrade(&backend)); + Ok(EglSurface(backend)) } fn process_events(&mut self) { diff --git a/src/backend/drm/egl/session.rs b/src/backend/drm/egl/session.rs index ff12afe..e6e4dc2 100644 --- a/src/backend/drm/egl/session.rs +++ b/src/backend/drm/egl/session.rs @@ -4,9 +4,12 @@ //! use drm::control::{connector, crtc, Mode}; +use std::cell::RefCell; +use std::collections::HashMap; use std::os::unix::io::RawFd; +use std::rc::{Rc, Weak}; -use super::EglDevice; +use super::{EglDevice, EglSurfaceInternal}; use crate::backend::drm::{Device, Surface}; use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use crate::backend::session::{AsSessionObserver, SessionObserver}; @@ -14,11 +17,12 @@ use crate::backend::session::{AsSessionObserver, SessionObserver}; /// [`SessionObserver`](SessionObserver) /// linked to the [`EglDevice`](EglDevice) it was /// created from. -pub struct EglDeviceObserver { +pub struct EglDeviceObserver { observer: S, + backends: Weak>>>>, } -impl AsSessionObserver> for EglDevice +impl AsSessionObserver::Surface>> for EglDevice where S: SessionObserver + 'static, B: Backend::Surface> + 'static, @@ -31,14 +35,15 @@ where + 'static, ::Surface: NativeSurface, { - fn observer(&mut self) -> EglDeviceObserver { + fn observer(&mut self) -> EglDeviceObserver::Surface> { EglDeviceObserver { observer: self.dev.borrow_mut().observer(), + backends: Rc::downgrade(&self.backends), } } } -impl SessionObserver for EglDeviceObserver { +impl SessionObserver for EglDeviceObserver { fn pause(&mut self, devnum: Option<(u32, u32)>) { self.observer.pause(devnum); } diff --git a/src/backend/drm/egl/surface.rs b/src/backend/drm/egl/surface.rs index 7bb01c0..a6592a3 100644 --- a/src/backend/drm/egl/surface.rs +++ b/src/backend/drm/egl/surface.rs @@ -12,8 +12,12 @@ use crate::backend::graphics::gl::GLGraphicsBackend; use crate::backend::graphics::PixelFormat; use crate::backend::graphics::{CursorBackend, SwapBuffersError}; +use std::rc::Rc; + /// Egl surface for rendering -pub struct EglSurface +pub struct EglSurface(pub(super) Rc>); + +pub(super) struct EglSurfaceInternal where N: native::NativeSurface + Surface, { @@ -29,41 +33,45 @@ where type Error = Error<::Error>; fn crtc(&self) -> crtc::Handle { - (*self.surface).crtc() + (*self.0.surface).crtc() } fn current_connectors(&self) -> Self::Connectors { - self.surface.current_connectors() + self.0.surface.current_connectors() } fn pending_connectors(&self) -> Self::Connectors { - self.surface.pending_connectors() + self.0.surface.pending_connectors() } fn add_connector(&self, connector: connector::Handle) -> Result<(), Self::Error> { - self.surface.add_connector(connector).map_err(Error::Underlying) + self.0.surface.add_connector(connector).map_err(Error::Underlying) } fn remove_connector(&self, connector: connector::Handle) -> Result<(), Self::Error> { - self.surface + self.0 + .surface .remove_connector(connector) .map_err(Error::Underlying) } fn set_connectors(&self, connectors: &[connector::Handle]) -> Result<(), Self::Error> { - self.surface.set_connectors(connectors).map_err(Error::Underlying) + self.0 + .surface + .set_connectors(connectors) + .map_err(Error::Underlying) } fn current_mode(&self) -> Mode { - self.surface.current_mode() + self.0.surface.current_mode() } fn pending_mode(&self) -> Mode { - self.surface.pending_mode() + self.0.surface.pending_mode() } fn use_mode(&self, mode: Mode) -> Result<(), Self::Error> { - self.surface.use_mode(mode).map_err(Error::Underlying) + self.0.surface.use_mode(mode).map_err(Error::Underlying) } } @@ -75,7 +83,7 @@ where type Error = ::Error; fn set_cursor_position(&self, x: u32, y: u32) -> ::std::result::Result<(), Self::Error> { - self.surface.set_cursor_position(x, y) + self.0.surface.set_cursor_position(x, y) } fn set_cursor_representation( @@ -83,7 +91,7 @@ where buffer: &Self::CursorFormat, hotspot: (u32, u32), ) -> ::std::result::Result<(), Self::Error> { - self.surface.set_cursor_representation(buffer, hotspot) + self.0.surface.set_cursor_representation(buffer, hotspot) } } @@ -94,7 +102,7 @@ where ::Error: Into + 'static, { fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> { - if let Err(err) = self.surface.swap_buffers() { + if let Err(err) = self.0.surface.swap_buffers() { Err(match err.try_into() { Ok(x) => x, Err(x) => x.into(), @@ -114,16 +122,17 @@ where } fn is_current(&self) -> bool { - self.context.is_current() && self.surface.is_current() + self.0.context.is_current() && self.0.surface.is_current() } unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> { - self.context - .make_current_with_surface(&self.surface) + self.0 + .context + .make_current_with_surface(&self.0.surface) .map_err(Into::into) } fn get_pixel_format(&self) -> PixelFormat { - self.surface.get_pixel_format() + self.0.surface.get_pixel_format() } }