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::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<RefCell<HashMap<crtc::Handle, Weak<EglSurfaceInternal<<D as Device>::Surface>>>>>,
}
impl<B, D> AsRawFd for EglDevice<B, D>
@ -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) {

View File

@ -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<S: SessionObserver + 'static> {
pub struct EglDeviceObserver<S: SessionObserver + 'static, N: NativeSurface + Surface> {
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
S: SessionObserver + 'static,
B: Backend<Surface = <D as Device>::Surface> + 'static,
@ -31,14 +35,15 @@ where
+ 'static,
<D as Device>::Surface: NativeSurface,
{
fn observer(&mut self) -> EglDeviceObserver<S> {
fn observer(&mut self) -> EglDeviceObserver<S, <D as Device>::Surface> {
EglDeviceObserver {
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)>) {
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::{CursorBackend, SwapBuffersError};
use std::rc::Rc;
/// 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
N: native::NativeSurface + Surface,
{
@ -29,41 +33,45 @@ where
type Error = Error<<N as Surface>::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 = <N as CursorBackend>::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
<N as NativeSurface>::Error: Into<SwapBuffersError> + '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()
}
}