egl: track backends

This commit is contained in:
Victor Brekenfeld 2020-04-27 19:05:00 +02:00
parent 7bca463934
commit 9bbd9edb0c
3 changed files with 44 additions and 23 deletions

View File

@ -11,7 +11,10 @@
use drm::control::{connector, crtc, encoder, framebuffer, plane, Mode, ResourceHandles}; use drm::control::{connector, crtc, encoder, framebuffer, plane, Mode, ResourceHandles};
use drm::SystemError as DrmError; use drm::SystemError as DrmError;
use nix::libc::dev_t; use nix::libc::dev_t;
use std::cell::RefCell;
use std::collections::HashMap;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::{Rc, Weak};
#[cfg(feature = "use_system_lib")] #[cfg(feature = "use_system_lib")]
use wayland_server::Display; use wayland_server::Display;
@ -58,6 +61,7 @@ where
logger: ::slog::Logger, logger: ::slog::Logger,
default_attributes: GlAttributes, default_attributes: GlAttributes,
default_requirements: PixelFormatRequirements, default_requirements: PixelFormatRequirements,
backends: Rc<RefCell<HashMap<crtc::Handle, Weak<EglSurfaceInternal<<D as Device>::Surface>>>>>,
} }
impl<B, D> AsRawFd for EglDevice<B, D> impl<B, D> AsRawFd for EglDevice<B, D>
@ -125,6 +129,7 @@ where
dev: EGLDisplay::new(dev, log.clone()).map_err(Error::EGL)?, dev: EGLDisplay::new(dev, log.clone()).map_err(Error::EGL)?,
default_attributes, default_attributes,
default_requirements, default_requirements,
backends: Rc::new(RefCell::new(HashMap::new())),
logger: log, logger: log,
}) })
} }
@ -208,7 +213,9 @@ where
SurfaceCreationError::NativeSurfaceCreationFailed(err) => Error::Underlying(err), 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) { fn process_events(&mut self) {

View File

@ -4,9 +4,12 @@
//! //!
use drm::control::{connector, crtc, Mode}; use drm::control::{connector, crtc, Mode};
use std::cell::RefCell;
use std::collections::HashMap;
use std::os::unix::io::RawFd; 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::drm::{Device, Surface};
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface};
use crate::backend::session::{AsSessionObserver, SessionObserver}; use crate::backend::session::{AsSessionObserver, SessionObserver};
@ -14,11 +17,12 @@ use crate::backend::session::{AsSessionObserver, SessionObserver};
/// [`SessionObserver`](SessionObserver) /// [`SessionObserver`](SessionObserver)
/// linked to the [`EglDevice`](EglDevice) it was /// linked to the [`EglDevice`](EglDevice) it was
/// created from. /// created from.
pub struct EglDeviceObserver<S: SessionObserver + 'static> { pub struct EglDeviceObserver<S: SessionObserver + 'static, N: NativeSurface + Surface> {
observer: S, observer: S,
backends: Weak<RefCell<HashMap<crtc::Handle, Weak<EglSurfaceInternal<N>>>>>,
} }
impl<S, B, D> AsSessionObserver<EglDeviceObserver<S>> for EglDevice<B, D> impl<S, B, D> AsSessionObserver<EglDeviceObserver<S, <D as Device>::Surface>> for EglDevice<B, D>
where where
S: SessionObserver + 'static, S: SessionObserver + 'static,
B: Backend<Surface = <D as Device>::Surface> + 'static, B: Backend<Surface = <D as Device>::Surface> + 'static,
@ -31,14 +35,15 @@ where
+ 'static, + 'static,
<D as Device>::Surface: NativeSurface, <D as Device>::Surface: NativeSurface,
{ {
fn observer(&mut self) -> EglDeviceObserver<S> { fn observer(&mut self) -> EglDeviceObserver<S, <D as Device>::Surface> {
EglDeviceObserver { EglDeviceObserver {
observer: self.dev.borrow_mut().observer(), observer: self.dev.borrow_mut().observer(),
backends: Rc::downgrade(&self.backends),
} }
} }
} }
impl<S: SessionObserver + 'static> SessionObserver for EglDeviceObserver<S> { impl<S: SessionObserver + 'static, N: NativeSurface + Surface> SessionObserver for EglDeviceObserver<S, N> {
fn pause(&mut self, devnum: Option<(u32, u32)>) { fn pause(&mut self, devnum: Option<(u32, u32)>) {
self.observer.pause(devnum); self.observer.pause(devnum);
} }

View File

@ -12,8 +12,12 @@ use crate::backend::graphics::gl::GLGraphicsBackend;
use crate::backend::graphics::PixelFormat; use crate::backend::graphics::PixelFormat;
use crate::backend::graphics::{CursorBackend, SwapBuffersError}; use crate::backend::graphics::{CursorBackend, SwapBuffersError};
use std::rc::Rc;
/// Egl surface for rendering /// Egl surface for rendering
pub struct EglSurface<N> pub struct EglSurface<N: native::NativeSurface + Surface>(pub(super) Rc<EglSurfaceInternal<N>>);
pub(super) struct EglSurfaceInternal<N>
where where
N: native::NativeSurface + Surface, N: native::NativeSurface + Surface,
{ {
@ -29,41 +33,45 @@ where
type Error = Error<<N as Surface>::Error>; type Error = Error<<N as Surface>::Error>;
fn crtc(&self) -> crtc::Handle { fn crtc(&self) -> crtc::Handle {
(*self.surface).crtc() (*self.0.surface).crtc()
} }
fn current_connectors(&self) -> Self::Connectors { fn current_connectors(&self) -> Self::Connectors {
self.surface.current_connectors() self.0.surface.current_connectors()
} }
fn pending_connectors(&self) -> Self::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> { 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> { fn remove_connector(&self, connector: connector::Handle) -> Result<(), Self::Error> {
self.surface self.0
.surface
.remove_connector(connector) .remove_connector(connector)
.map_err(Error::Underlying) .map_err(Error::Underlying)
} }
fn set_connectors(&self, connectors: &[connector::Handle]) -> Result<(), Self::Error> { 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 { fn current_mode(&self) -> Mode {
self.surface.current_mode() self.0.surface.current_mode()
} }
fn pending_mode(&self) -> Mode { fn pending_mode(&self) -> Mode {
self.surface.pending_mode() self.0.surface.pending_mode()
} }
fn use_mode(&self, mode: Mode) -> Result<(), Self::Error> { 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 = <N as CursorBackend>::Error; type Error = <N as CursorBackend>::Error;
fn set_cursor_position(&self, x: u32, y: u32) -> ::std::result::Result<(), Self::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( fn set_cursor_representation(
@ -83,7 +91,7 @@ where
buffer: &Self::CursorFormat, buffer: &Self::CursorFormat,
hotspot: (u32, u32), hotspot: (u32, u32),
) -> ::std::result::Result<(), Self::Error> { ) -> ::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
<N as NativeSurface>::Error: Into<SwapBuffersError> + 'static, <N as NativeSurface>::Error: Into<SwapBuffersError> + 'static,
{ {
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> { 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() { Err(match err.try_into() {
Ok(x) => x, Ok(x) => x,
Err(x) => x.into(), Err(x) => x.into(),
@ -114,16 +122,17 @@ where
} }
fn is_current(&self) -> bool { 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> { unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
self.context self.0
.make_current_with_surface(&self.surface) .context
.make_current_with_surface(&self.0.surface)
.map_err(Into::into) .map_err(Into::into)
} }
fn get_pixel_format(&self) -> PixelFormat { fn get_pixel_format(&self) -> PixelFormat {
self.surface.get_pixel_format() self.0.surface.get_pixel_format()
} }
} }