diff --git a/anvil/src/buffer_utils.rs b/anvil/src/buffer_utils.rs index e784177..e42b650 100644 --- a/anvil/src/buffer_utils.rs +++ b/anvil/src/buffer_utils.rs @@ -1,14 +1,27 @@ -use std::{cell::RefCell, rc::Rc}; - +use std::collections::HashMap; +#[cfg(feature = "egl")] +use std::{ + cell::RefCell, + rc::Rc, +}; +use glium::texture::Texture2d; +#[cfg(feature = "egl")] +use glium::{ + texture::{MipmapsOption, UncompressedFloatFormat}, + GlObject, +}; use slog::Logger; #[cfg(feature = "egl")] -use smithay::backend::egl::display::EGLBufferReader; +use smithay::backend::egl::{display::EGLBufferReader, EGLImages, BufferAccessError as EGLBufferAccessError, Format}; use smithay::{ + backend::graphics::gl::GLGraphicsBackend, reexports::wayland_server::protocol::wl_buffer::WlBuffer, - wayland::shm::with_buffer_contents as shm_buffer_contents, + wayland::shm::{with_buffer_contents as shm_buffer_contents, BufferAccessError}, }; +use crate::glium_drawer::GliumDrawer; + /// Utilities for working with `WlBuffer`s. #[derive(Clone)] pub struct BufferUtils { @@ -41,22 +54,172 @@ impl BufferUtils { .borrow() .as_ref() .and_then(|display| display.egl_buffer_dimensions(buffer)) - .or_else(|| self.shm_buffer_dimensions(buffer)) + .or_else(|| self.shm_buffer_dimensions(buffer).ok()) } /// Returns the dimensions of an image stored in the buffer. #[cfg(not(feature = "egl"))] pub fn dimensions(&self, buffer: &WlBuffer) -> Option<(i32, i32)> { - self.shm_buffer_dimensions(buffer) + self.shm_buffer_dimensions(buffer).ok() } /// Returns the dimensions of an image stored in the shm buffer. - fn shm_buffer_dimensions(&self, buffer: &WlBuffer) -> Option<(i32, i32)> { + fn shm_buffer_dimensions(&self, buffer: &WlBuffer) -> Result<(i32, i32), BufferAccessError> { shm_buffer_contents(buffer, |_, data| (data.width, data.height)) .map_err(|err| { warn!(self.log, "Unable to load buffer contents"; "err" => format!("{:?}", err)); err }) - .ok() + } + + #[cfg(feature = "egl")] + pub fn load_buffer(&self, buffer: WlBuffer) -> Result { + // try to retrieve the egl contents of this buffer + let images = if let Some(display) = &self.egl_buffer_reader.borrow().as_ref() { + display.egl_buffer_contents(&buffer) + } else { + return Err(buffer); + }; + + match images { + Ok(images) => { + // we have an EGL buffer + Ok(BufferTextures { + buffer, + textures: HashMap::new(), + fragment: crate::shaders::BUFFER_RGBA, + y_inverted: images.y_inverted, + dimensions: (images.width, images.height), + images: Some(images), // I guess we need to keep this alive ? + logger: self.log.clone(), + }) + } + Err(EGLBufferAccessError::NotManaged(_)) => { + // this is not an EGL buffer, try SHM + self.load_shm_buffer(buffer) + } + Err(err) => { + error!(self.log, "EGL error"; "err" => format!("{:?}", err)); + Err(buffer) + } + } + } + + #[cfg(not(feature = "egl"))] + pub fn load_buffer(&self, buffer: WlBuffer) -> Result { + self.load_shm_buffer(buffer) + } + + fn load_shm_buffer(&self, buffer: WlBuffer) -> Result { + let (width, height, format) = match shm_buffer_contents(&buffer, |_, data| (data.width, data.height, data.format)) { + Ok(x) => x, + Err(err) => { + warn!(self.log, "Unable to load buffer contents"; "err" => format!("{:?}", err)); + return Err(buffer); + } + }; + let shader = match crate::shm_load::load_format(format) { + Ok(x) => x.1, + Err(format) => { + warn!(self.log, "Unable to load buffer format: {:?}", format); + return Err(buffer); + } + }; + Ok(BufferTextures { + buffer, + textures: HashMap::new(), + fragment: shader, + y_inverted: false, + dimensions: (width as u32, height as u32), + #[cfg(feature = "egl")] + images: None, + logger: self.log.clone(), + }) } } + +pub struct BufferTextures { + buffer: WlBuffer, + pub textures: HashMap, + pub fragment: usize, + pub y_inverted: bool, + pub dimensions: (u32, u32), + #[cfg(feature = "egl")] + images: Option, + logger: slog::Logger, +} + +impl BufferTextures { + #[cfg(feature = "egl")] + pub fn load_texture<'a, F: GLGraphicsBackend + 'static>(&'a mut self, drawer: &GliumDrawer) -> Result<&'a Texture2d, ()> { + if self.textures.contains_key(&drawer.id) { + return Ok(&self.textures[&drawer.id]); + } + + if let Some(images) = self.images.as_ref() { //EGL buffer + let format = match images.format { + Format::RGB => UncompressedFloatFormat::U8U8U8, + Format::RGBA => UncompressedFloatFormat::U8U8U8U8, + _ => { + warn!(self.logger, "Unsupported EGL buffer format"; "format" => format!("{:?}", images.format)); + return Err(()); + } + }; + + let opengl_texture = Texture2d::empty_with_format( + &drawer.display, + format, + MipmapsOption::NoMipmap, + images.width, + images.height, + ) + .unwrap(); + + unsafe { + images + .bind_to_texture(0, opengl_texture.get_id(), &*drawer.display.borrow()) + .expect("Failed to bind to texture"); + } + + self.textures.insert(drawer.id, opengl_texture); + Ok(&self.textures[&drawer.id]) + } else { + self.load_shm_texture(drawer) + } + } + + #[cfg(not(feature = "egl"))] + pub fn load_texture<'a, F: GLGraphicsBackend + 'static>(&'a mut self, drawer: &GliumDrawer) -> Result<&'a Texture2d, ()> { + if self.textures.contains_key(&drawer.id) { + return Ok(&self.textures[&drawer.id]); + } + + self.load_shm_texture(drawer) + } + + fn load_shm_texture<'a, F: GLGraphicsBackend + 'static>(&'a mut self, drawer: &GliumDrawer) -> Result<&'a Texture2d, ()> { + match shm_buffer_contents(&self.buffer, |slice, data| { + crate::shm_load::load_shm_buffer(data, slice) + .map(|(image, _kind)| Texture2d::new(&drawer.display, image).unwrap()) + }) { + Ok(Ok(texture)) => { + self.textures.insert(drawer.id, texture); + Ok(&self.textures[&drawer.id]) + }, + Ok(Err(format)) => { + warn!(self.logger, "Unsupported SHM buffer format"; "format" => format!("{:?}", format)); + Err(()) + } + Err(err) => { + warn!(self.logger, "Unable to load buffer contents"; "err" => format!("{:?}", err)); + Err(()) + } + } + } +} + +impl Drop for BufferTextures { + fn drop(&mut self) { + self.buffer.release() + } +} \ No newline at end of file diff --git a/anvil/src/glium_drawer.rs b/anvil/src/glium_drawer.rs index 9f436a8..b3d99a6 100644 --- a/anvil/src/glium_drawer.rs +++ b/anvil/src/glium_drawer.rs @@ -7,35 +7,30 @@ use std::{ use glium::{ self, index::PrimitiveType, - texture::{MipmapsOption, Texture2d, UncompressedFloatFormat}, - GlObject, Surface, + texture::Texture2d, + Surface, }; use slog::Logger; -#[cfg(feature = "egl")] -use smithay::backend::egl::display::EGLBufferReader; use smithay::{ - backend::{ - egl::{BufferAccessError, EGLImages, Format}, - graphics::{ - gl::GLGraphicsBackend, - glium::{Frame, GliumGraphicsBackend}, - SwapBuffersError, - }, + backend::graphics::{ + gl::GLGraphicsBackend, + glium::{Frame, GliumGraphicsBackend}, + SwapBuffersError, }, reexports::{ calloop::LoopHandle, - wayland_server::protocol::{wl_buffer, wl_surface}, + wayland_server::protocol::wl_surface, }, utils::Rectangle, wayland::{ compositor::{roles::Role, SubsurfaceRole, TraversalAction}, data_device::DnDIconRole, seat::CursorImageRole, - shm::with_buffer_contents as shm_buffer_contents, }, }; +use crate::buffer_utils::BufferUtils; use crate::shaders; use crate::shell::{MyCompositorToken, MyWindowMap, SurfaceData}; @@ -55,13 +50,12 @@ mod implement_vertex { } pub struct GliumDrawer { - id: usize, - display: GliumGraphicsBackend, + pub id: usize, + pub display: GliumGraphicsBackend, vertex_buffer: glium::VertexBuffer, index_buffer: glium::IndexBuffer, programs: [glium::Program; shaders::FRAGMENT_COUNT], - #[cfg(feature = "egl")] - egl_buffer_reader: Rc>>, + buffer_loader: BufferUtils, log: Logger, } @@ -72,10 +66,9 @@ impl GliumDrawer { } impl> + GLGraphicsBackend + 'static> GliumDrawer { - #[cfg(feature = "egl")] pub fn init( backend: T, - egl_buffer_reader: Rc>>, + buffer_loader: BufferUtils, log: Logger, ) -> GliumDrawer { let display = backend.into(); @@ -116,140 +109,13 @@ impl> + GLGraphicsBackend + 'static> GliumDrawer vertex_buffer, index_buffer, programs, - egl_buffer_reader, - log, - } - } - - #[cfg(not(feature = "egl"))] - pub fn init(backend: T, log: Logger) -> GliumDrawer { - let display = backend.into(); - - // building the vertex buffer, which contains all the vertices that we will draw - let vertex_buffer = glium::VertexBuffer::new( - &display, - &[ - Vertex { - position: [0.0, 0.0], - tex_coords: [0.0, 0.0], - }, - Vertex { - position: [0.0, 1.0], - tex_coords: [0.0, 1.0], - }, - Vertex { - position: [1.0, 1.0], - tex_coords: [1.0, 1.0], - }, - Vertex { - position: [1.0, 0.0], - tex_coords: [1.0, 0.0], - }, - ], - ) - .unwrap(); - - // building the index buffer - let index_buffer = - glium::IndexBuffer::new(&display, PrimitiveType::TriangleStrip, &[1 as u16, 2, 0, 3]).unwrap(); - - let programs = opengl_programs!(&display); - - GliumDrawer { - id: BACKEND_COUNTER.fetch_add(1, Ordering::AcqRel), - display, - vertex_buffer, - index_buffer, - programs, + buffer_loader, log, } } } impl GliumDrawer { - #[cfg(feature = "egl")] - pub fn texture_from_buffer(&self, buffer: wl_buffer::WlBuffer) -> Result { - // try to retrieve the egl contents of this buffer - let images = if let Some(display) = &self.egl_buffer_reader.borrow().as_ref() { - display.egl_buffer_contents(buffer) - } else { - Err(BufferAccessError::NotManaged( - buffer, - smithay::backend::egl::EGLError::BadDisplay, - )) - }; - match images { - Ok(images) => { - // we have an EGL buffer - let format = match images.format { - Format::RGB => UncompressedFloatFormat::U8U8U8, - Format::RGBA => UncompressedFloatFormat::U8U8U8U8, - _ => { - warn!(self.log, "Unsupported EGL buffer format"; "format" => format!("{:?}", images.format)); - return Err(()); - } - }; - let opengl_texture = Texture2d::empty_with_format( - &self.display, - format, - MipmapsOption::NoMipmap, - images.width, - images.height, - ) - .unwrap(); - unsafe { - images - .bind_to_texture(0, opengl_texture.get_id(), &*self.display.borrow()) - .expect("Failed to bind to texture"); - } - Ok(TextureMetadata { - texture: opengl_texture, - fragment: crate::shaders::BUFFER_RGBA, - y_inverted: images.y_inverted, - dimensions: (images.width, images.height), - images: Some(images), // I guess we need to keep this alive ? - }) - } - Err(BufferAccessError::NotManaged(buffer, _)) => { - // this is not an EGL buffer, try SHM - self.texture_from_shm_buffer(buffer) - } - Err(err) => { - error!(self.log, "EGL error"; "err" => format!("{:?}", err)); - Err(()) - } - } - } - - #[cfg(not(feature = "egl"))] - pub fn texture_from_buffer(&self, buffer: wl_buffer::WlBuffer) -> Result { - self.texture_from_shm_buffer(buffer) - } - - fn texture_from_shm_buffer(&self, buffer: wl_buffer::WlBuffer) -> Result { - match shm_buffer_contents(&buffer, |slice, data| { - crate::shm_load::load_shm_buffer(data, slice) - .map(|(image, kind)| (Texture2d::new(&self.display, image).unwrap(), kind, data)) - }) { - Ok(Ok((texture, kind, data))) => Ok(TextureMetadata { - texture, - fragment: kind, - y_inverted: false, - dimensions: (data.width as u32, data.height as u32), - #[cfg(feature = "egl")] - images: None, - }), - Ok(Err(format)) => { - warn!(self.log, "Unsupported SHM buffer format"; "format" => format!("{:?}", format)); - Err(()) - } - Err(err) => { - warn!(self.log, "Unable to load buffer contents"; "err" => format!("{:?}", err)); - Err(()) - } - } - } - pub fn render_texture(&self, target: &mut Frame, spec: RenderTextureSpec<'_>) { let xscale = 2.0 * (spec.surface_dimensions.0 as f32) / (spec.screen_size.0 as f32); let mut yscale = -2.0 * (spec.surface_dimensions.1 as f32) / (spec.screen_size.1 as f32); @@ -302,15 +168,6 @@ pub struct RenderTextureSpec<'a> { blending: glium::Blend, } -pub struct TextureMetadata { - pub texture: Texture2d, - pub fragment: usize, - pub y_inverted: bool, - pub dimensions: (u32, u32), - #[cfg(feature = "egl")] - images: Option, -} - impl GliumDrawer { fn draw_surface_tree( &self, @@ -327,30 +184,18 @@ impl GliumDrawer { // Pull a new buffer if available if let Some(data) = attributes.user_data.get::>() { let mut data = data.borrow_mut(); - if !data.texture.contains_key(&self.id) { + if data.texture.is_none() { if let Some(buffer) = data.current_state.buffer.take() { - if let Ok(m) = self.texture_from_buffer(buffer.clone()) { - // release the buffer if it was an SHM buffer - #[cfg(feature = "egl")] - { - if m.images.is_none() { - buffer.release(); - } - } - #[cfg(not(feature = "egl"))] - { - buffer.release(); - } - data.texture.insert(self.id, m); - } else { + match self.buffer_loader.load_buffer(buffer) { + Ok(m) => data.texture = Some(m), // there was an error reading the buffer, release it, we // already logged the error - buffer.release(); - } + Err(buffer) => buffer.release(), + }; } } // Now, should we be drawn ? - if data.texture.contains_key(&self.id) { + if data.texture.is_some() { // if yes, also process the children if Role::::has(role) { x += data.current_state.sub_location.0; @@ -368,36 +213,42 @@ impl GliumDrawer { }, |_surface, attributes, role, &(mut x, mut y)| { if let Some(ref data) = attributes.user_data.get::>() { - let data = data.borrow(); - if let Some(ref metadata) = data.texture.get(&self.id) { - // we need to re-extract the subsurface offset, as the previous closure - // only passes it to our children - if Role::::has(role) { - x += data.current_state.sub_location.0; - y += data.current_state.sub_location.1; - } - self.render_texture( - frame, - RenderTextureSpec { - texture: &metadata.texture, - texture_kind: metadata.fragment, - y_inverted: metadata.y_inverted, - surface_dimensions: metadata.dimensions, - surface_location: (x, y), - screen_size: screen_dimensions, - blending: ::glium::Blend { - color: ::glium::BlendingFunction::Addition { - source: ::glium::LinearBlendingFactor::One, - destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha, + let mut data = data.borrow_mut(); + let (sub_x, sub_y) = data.current_state.sub_location; + if let Some(buffer_textures) = data.texture.as_mut() { + let texture_kind = buffer_textures.fragment; + let y_inverted = buffer_textures.y_inverted; + let surface_dimensions = buffer_textures.dimensions; + if let Ok(ref texture) = buffer_textures.load_texture(&self) { + // we need to re-extract the subsurface offset, as the previous closure + // only passes it to our children + if Role::::has(role) { + x += sub_x; + y += sub_y; + } + self.render_texture( + frame, + RenderTextureSpec { + texture: &texture, + texture_kind, + y_inverted, + surface_dimensions, + surface_location: (x, y), + screen_size: screen_dimensions, + blending: ::glium::Blend { + color: ::glium::BlendingFunction::Addition { + source: ::glium::LinearBlendingFactor::One, + destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha, + }, + alpha: ::glium::BlendingFunction::Addition { + source: ::glium::LinearBlendingFactor::One, + destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha, + }, + ..Default::default() }, - alpha: ::glium::BlendingFunction::Addition { - source: ::glium::LinearBlendingFactor::One, - destination: ::glium::LinearBlendingFactor::OneMinusSourceAlpha, - }, - ..Default::default() }, - }, - ); + ); + } } } }, diff --git a/anvil/src/input_handler.rs b/anvil/src/input_handler.rs index dfd5d48..17174e1 100644 --- a/anvil/src/input_handler.rs +++ b/anvil/src/input_handler.rs @@ -82,6 +82,7 @@ impl AnvilState { ); } }, + #[cfg(feature = "udev")] KeyAction::Screen(num) => { let output_map = self.output_map .as_ref().unwrap(); diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index a239c97..fe297cf 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -1,6 +1,5 @@ use std::{ cell::RefCell, - collections::HashMap, rc::Rc, sync::{Arc, Mutex}, }; @@ -655,7 +654,7 @@ pub struct CommitedState { #[derive(Default)] pub struct SurfaceData { - pub texture: HashMap, + pub texture: Option, pub geometry: Option, pub resize_state: ResizeState, /// Minimum width and height, as requested by the surface. @@ -674,7 +673,7 @@ impl SurfaceData { /// Apply a next state into the surface current state pub fn apply_state(&mut self, next_state: CommitedState) { if Self::merge_state(&mut self.current_state, next_state) { - self.texture.clear(); + let _ = self.texture.take(); } } diff --git a/anvil/src/shm_load.rs b/anvil/src/shm_load.rs index 1a9f26e..abb41c6 100644 --- a/anvil/src/shm_load.rs +++ b/anvil/src/shm_load.rs @@ -32,13 +32,7 @@ pub fn load_shm_buffer(data: BufferData, pool: &[u8]) -> Result<(RawImage2d<'_, }; // sharders format need to be reversed to account for endianness - let (client_format, fragment) = match data.format { - Format::Argb8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_BGRA), - Format::Xrgb8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_BGRX), - Format::Rgba8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_ABGR), - Format::Rgbx8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_XBGR), - _ => return Err(data.format), - }; + let (client_format, fragment) = load_format(data.format)?; Ok(( RawImage2d { data: slice, @@ -49,3 +43,13 @@ pub fn load_shm_buffer(data: BufferData, pool: &[u8]) -> Result<(RawImage2d<'_, fragment, )) } + +pub fn load_format(format: Format) -> Result<(ClientFormat, usize), Format> { + Ok(match format { + Format::Argb8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_BGRA), + Format::Xrgb8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_BGRX), + Format::Rgba8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_ABGR), + Format::Rgbx8888 => (ClientFormat::U8U8U8U8, crate::shaders::BUFFER_XBGR), + _ => return Err(format), + }) +} diff --git a/anvil/src/state.rs b/anvil/src/state.rs index 37982d5..edc4c62 100644 --- a/anvil/src/state.rs +++ b/anvil/src/state.rs @@ -8,7 +8,6 @@ use std::{ }; use smithay::{ - backend::session::auto::AutoSession, reexports::{ calloop::{ generic::{Fd, Generic}, @@ -25,9 +24,14 @@ use smithay::{ }; #[cfg(feature = "udev")] -use smithay::backend::session::Session; +use smithay::backend::session::{ + auto::AutoSession, + Session, +}; -use crate::{buffer_utils::BufferUtils, shell::init_shell, udev::MyOutput}; +use crate::{buffer_utils::BufferUtils, shell::init_shell}; +#[cfg(feature = "udev")] +use crate::udev::MyOutput; pub struct AnvilState { pub socket_name: String, @@ -129,7 +133,7 @@ impl AnvilState { "anvil".into() }; #[cfg(not(feature = "udev"))] - let seat_name = "anvil".into(); + let seat_name: String = "anvil".into(); let (mut seat, _) = Seat::new( &mut display.borrow_mut(), diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 3febe14..15ae828 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -127,7 +127,7 @@ pub fn run_udev( let mut state = AnvilState::init( display.clone(), event_loop.handle(), - buffer_utils, + buffer_utils.clone(), Some(session), Some(output_map.clone()), log.clone(), @@ -143,6 +143,7 @@ pub fn run_udev( let mut udev_handler = UdevHandlerImpl { compositor_token: state.ctoken, + buffer_utils: buffer_utils, #[cfg(feature = "egl")] egl_buffer_reader, session: state.session.clone().unwrap(), @@ -292,6 +293,7 @@ struct BackendData { struct UdevHandlerImpl { compositor_token: CompositorToken, + buffer_utils: BufferUtils, #[cfg(feature = "egl")] egl_buffer_reader: Rc>>, session: AutoSession, @@ -310,10 +312,9 @@ struct UdevHandlerImpl { } impl UdevHandlerImpl { - #[cfg(feature = "egl")] pub fn scan_connectors( device: &mut RenderDevice, - egl_buffer_reader: Rc>>, + buffer_utils: &BufferUtils, display: &mut Display, output_map: &mut Vec, logger: &::slog::Logger, @@ -347,7 +348,7 @@ impl UdevHandlerImpl { device .create_surface(crtc, connector_info.modes()[0], &[connector_info.handle()]) .unwrap(), - egl_buffer_reader.clone(), + buffer_utils.clone(), logger.clone(), ); output_map.push(MyOutput::new(display, device.device_id(), crtc, connector_info, logger.clone())); @@ -361,52 +362,6 @@ impl UdevHandlerImpl { backends } - - #[cfg(not(feature = "egl"))] - pub fn scan_connectors( - device: &mut RenderDevice, - display: &mut Display, - output_map: &mut Vec, - logger: &::slog::Logger, - ) -> HashMap>> { - // Get a set of all modesetting resource handles (excluding planes): - let res_handles = device.resource_handles().unwrap(); - - // Use first connected connector - let connector_infos: Vec = res_handles - .connectors() - .iter() - .map(|conn| device.get_connector_info(*conn).unwrap()) - .filter(|conn| conn.state() == ConnectorState::Connected) - .inspect(|conn| info!(logger, "Connected: {:?}", conn.interface())) - .collect(); - - let mut backends = HashMap::new(); - - // very naive way of finding good crtc/encoder/connector combinations. This problem is np-complete - for connector_info in connector_infos { - let encoder_infos = connector_info - .encoders() - .iter() - .filter_map(|e| *e) - .flat_map(|encoder_handle| device.get_encoder_info(encoder_handle)) - .collect::>(); - 'outer: for encoder_info in encoder_infos { - for crtc in res_handles.filter_crtcs(encoder_info.possible_crtcs()) { - if !backends.contains_key(&crtc) { - let renderer = - GliumDrawer::init(device.create_surface(crtc).unwrap(), logger.clone()); - output_map.push(MyOutput::new(display, device.device_id(), crtc, connector_info, logger.clone())); - - backends.insert(crtc, Rc::new(renderer)); - break 'outer; - } - } - } - } - - backends - } } impl UdevHandlerImpl { @@ -453,23 +408,15 @@ impl UdevHandlerImpl { #[cfg(feature = "egl")] { if path.canonicalize().ok() == self.primary_gpu { + info!(self.logger, "Initializing EGL Hardware Acceleration via {:?}", path); *self.egl_buffer_reader.borrow_mut() = device.bind_wl_display(&*self.display.borrow()).ok(); } } - #[cfg(feature = "egl")] - let backends = Rc::new(RefCell::new(UdevHandlerImpl::::scan_connectors( - &mut device, - self.egl_buffer_reader.clone(), - &mut *self.display.borrow_mut(), - &mut *self.output_map.borrow_mut(), - &self.logger, - ))); - - #[cfg(not(feature = "egl"))] let backends = Rc::new(RefCell::new(UdevHandlerImpl::::scan_connectors( &mut device, + &self.buffer_utils, &mut *self.display.borrow_mut(), &mut *self.output_map.borrow_mut(), &self.logger, @@ -528,9 +475,9 @@ impl UdevHandlerImpl { fn device_changed(&mut self, device: dev_t) { //quick and dirty, just re-init all backends + let buffer_utils = &self.buffer_utils; if let Some(ref mut backend_data) = self.backends.get_mut(&device) { let logger = &self.logger; - let egl_buffer_reader = self.egl_buffer_reader.clone(); let loop_handle = self.loop_handle.clone(); let mut display = self.display.borrow_mut(); let mut output_map = self.output_map.borrow_mut(); @@ -538,21 +485,13 @@ impl UdevHandlerImpl { self.loop_handle .with_source(&backend_data.event_source, |source| { let mut backends = backend_data.surfaces.borrow_mut(); - #[cfg(feature = "egl")] - let new_backends = + *backends = UdevHandlerImpl::::scan_connectors( &mut source.file, - egl_buffer_reader, + buffer_utils, &mut *display, &mut *output_map, logger); - #[cfg(not(feature = "egl"))] - let new_backends = UdevHandlerImpl::::scan_connectors( - &mut source.file, - &mut *display, - &mut *output_map, - logger); - *backends = new_backends; for renderer in backends.values() { // render first frame diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index be16774..9432d59 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration}; use smithay::{ - backend::{egl::EGLGraphicsBackend, graphics::gl::GLGraphicsBackend, input::InputBackend, winit}, + backend::{graphics::gl::GLGraphicsBackend, input::InputBackend, winit}, reexports::{ calloop::EventLoop, wayland_server::{protocol::wl_output, Display}, @@ -12,6 +12,8 @@ use smithay::{ SERIAL_COUNTER as SCOUNTER, }, }; +#[cfg(feature = "egl")] +use smithay::backend::egl::EGLGraphicsBackend; use slog::Logger; @@ -38,17 +40,14 @@ pub fn run_winit( }, )); - let (w, h) = renderer.get_framebuffer_dimensions(); - #[cfg(feature = "egl")] - let drawer = GliumDrawer::init(renderer, egl_buffer_reader.clone(), log.clone()); - #[cfg(not(feature = "egl"))] - let drawer = GliumDrawer::init(renderer, log.clone()); - #[cfg(feature = "egl")] let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone()); #[cfg(not(feature = "egl"))] let buffer_utils = BufferUtils::new(log.clone()); + let (w, h) = renderer.get_framebuffer_dimensions(); + let drawer = GliumDrawer::init(renderer, buffer_utils.clone(), log.clone()); + /* * Initialize the globals */