diff --git a/anvil/src/buffer_utils.rs b/anvil/src/buffer_utils.rs deleted file mode 100644 index a3704f5..0000000 --- a/anvil/src/buffer_utils.rs +++ /dev/null @@ -1,172 +0,0 @@ -#[cfg(feature = "egl")] -use std::{cell::RefCell, rc::Rc}; -use std::sync::mpsc::Sender; - -#[cfg(feature = "udev")] -use smithay::backend::renderer::{Renderer, Texture}; -#[cfg(feature = "udev")] -use smithay::reexports::nix::libc::dev_t; -#[cfg(feature = "udev")] -use std::collections::HashMap; - -#[cfg(feature = "egl")] -use smithay::backend::egl::{display::EGLBufferReader, BufferAccessError as EGLBufferAccessError, EGLBuffer}; -use smithay::{ - reexports::wayland_server::protocol::wl_buffer::WlBuffer, - wayland::shm::{with_buffer_contents as shm_buffer_contents, BufferAccessError}, -}; - -/// Utilities for working with `WlBuffer`s. -#[derive(Clone)] -pub struct BufferUtils { - #[cfg(feature = "egl")] - egl_buffer_reader: Rc>>, - log: ::slog::Logger, -} - -impl BufferUtils { - /// Creates a new `BufferUtils`. - #[cfg(feature = "egl")] - pub fn new(egl_buffer_reader: Rc>>, log: ::slog::Logger) -> Self { - Self { - egl_buffer_reader, - log, - } - } - - /// Creates a new `BufferUtils`. - #[cfg(not(feature = "egl"))] - pub fn new(log: ::slog::Logger) -> Self { - Self { log } - } - - /// Returns the dimensions of an image stored in the buffer. - #[cfg(feature = "egl")] - pub fn dimensions(&self, buffer: &WlBuffer) -> Option<(i32, i32)> { - // Try to retrieve the EGL dimensions of this buffer, and, if that fails, the shm dimensions. - self.egl_buffer_reader - .borrow() - .as_ref() - .and_then(|display| display.egl_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).ok() - } - - /// Returns the dimensions of an image stored in the shm buffer. - 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 - }) - } - - #[cfg(feature = "egl")] - pub fn load_buffer(&self, buffer: WlBuffer) -> Result, WlBuffer> { - let egl_buffer = if let Some(reader) = &self.egl_buffer_reader.borrow().as_ref() { - match reader.egl_buffer_contents(&buffer) { - Ok(egl) => Some(egl), - Err(EGLBufferAccessError::NotManaged(_)) => None, - Err(err) => { - error!(self.log, "EGL error"; "err" => format!("{:?}", err)); - return Err(buffer); - } - } - } else { None }; - - Ok(BufferTextures { - buffer, - textures: HashMap::new(), - callbacks: HashMap::new(), - egl: egl_buffer, // I guess we need to keep this alive ? - }) - } - - #[cfg(not(feature = "egl"))] - pub fn load_buffer(&self, buffer: WlBuffer) -> Result, WlBuffer> { - Ok(BufferTextures { - buffer, - textures: HashMap::new(), - callbacks: HashMap::new(), - }) - } -} - -#[cfg(feature = "udev")] -pub struct BufferTextures { - buffer: WlBuffer, - pub textures: HashMap, - callbacks: HashMap>, - #[cfg(feature = "egl")] - egl: Option, -} - -#[cfg(feature = "udev")] -impl BufferTextures { - #[cfg(feature = "egl")] - pub fn load_texture<'a, R: Renderer>( - &'a mut self, - id: u64, - renderer: &mut R, - texture_destruction_callback: &Sender, - ) -> Result<&'a T, R::Error> { - if self.textures.contains_key(&id) { - return Ok(&self.textures[&id]); - } - - if let Some(buffer) = self.egl.as_ref() { - //EGL buffer - let texture = renderer.import_egl(&buffer)?; - if let Some(old_texture) = self.textures.insert(id, texture) { - let _ = renderer.destroy_texture(old_texture); - } - self.callbacks.insert(id, texture_destruction_callback.clone()); - Ok(&self.textures[&id]) - } else { - self.load_shm_texture(id, renderer, texture_destruction_callback) - } - } - - #[cfg(not(feature = "egl"))] - pub fn load_texture<'a, R: Renderer>( - &'a mut self, - id: u64, - renderer: &mut R, - texture_destruction_callback: &Sender, - ) -> Result<&'a T, R::Error> { - if self.textures.contains_key(&id) { - return Ok(&self.textures[&id]); - } - - self.load_shm_texture(id, renderer, texture_destruction_callback) - } - - fn load_shm_texture<'a, R: Renderer>( - &'a mut self, - id: u64, - renderer: &mut R, - texture_destruction_callback: &Sender, - ) -> Result<&'a T, R::Error> { - let texture = renderer.import_shm(&self.buffer)?; - - if let Some(old_texture) = self.textures.insert(id, texture) { - let _ = renderer.destroy_texture(old_texture)?; - } - self.callbacks.insert(id, texture_destruction_callback.clone()); - Ok(&self.textures[&id]) - } -} - -#[cfg(feature = "udev")] -impl Drop for BufferTextures { - fn drop(&mut self) { - self.buffer.release(); - for (id, texture) in self.textures.drain() { - self.callbacks.get(&id).unwrap().send(texture).unwrap(); - } - } -} diff --git a/anvil/src/drawing.rs b/anvil/src/drawing.rs index 8e04cc5..17220aa 100644 --- a/anvil/src/drawing.rs +++ b/anvil/src/drawing.rs @@ -1,12 +1,15 @@ #![allow(clippy::too_many_arguments)] -use std::{cell::RefCell, rc::Rc, sync::mpsc::Sender}; +use std::{cell::RefCell, rc::Rc}; use slog::Logger; use smithay::{ - backend::renderer::{Renderer, Texture, Transform}, - backend::SwapBuffersError, - reexports::{calloop::LoopHandle, wayland_server::protocol::wl_surface}, + backend::{ + egl::display::EGLBufferReader, + renderer::{Renderer, Texture, Transform}, + SwapBuffersError, + }, + reexports::{calloop::LoopHandle, wayland_server::protocol::{wl_buffer,wl_surface}}, utils::Rectangle, wayland::{ compositor::{roles::Role, SubsurfaceRole, TraversalAction}, @@ -15,15 +18,23 @@ use smithay::{ }, }; -use crate::buffer_utils::{BufferTextures, BufferUtils}; use crate::shell::{MyCompositorToken, MyWindowMap, SurfaceData}; +struct BufferTextures { + buffer: wl_buffer::WlBuffer, + texture: T, +} + +impl Drop for BufferTextures { + fn drop(&mut self) { + self.buffer.release(); + } +} + pub fn draw_cursor( renderer: &mut R, - renderer_id: u64, - texture_destruction_callback: &Sender, - buffer_utils: &BufferUtils, surface: &wl_surface::WlSurface, + egl_buffer_reader: Option<&EGLBufferReader>, (x, y): (i32, i32), token: MyCompositorToken, log: &Logger, @@ -45,10 +56,8 @@ where }; draw_surface_tree( renderer, - renderer_id, - texture_destruction_callback, - buffer_utils, surface, + egl_buffer_reader, (x - dx, y - dy), token, log, @@ -57,10 +66,8 @@ where fn draw_surface_tree( renderer: &mut R, - renderer_id: u64, - texture_destruction_callback: &Sender, - buffer_utils: &BufferUtils, root: &wl_surface::WlSurface, + egl_buffer_reader: Option<&EGLBufferReader>, location: (i32, i32), compositor_token: MyCompositorToken, log: &Logger, @@ -81,12 +88,13 @@ where let mut data = data.borrow_mut(); if data.texture.is_none() { if let Some(buffer) = data.current_state.buffer.take() { - match buffer_utils.load_buffer::(buffer) { - Ok(m) => data.texture = Some(Box::new(m) as Box), + match renderer.import_buffer(&buffer, egl_buffer_reader) { + Ok(m) => data.texture = Some(Box::new(BufferTextures { buffer, texture: m }) as Box), // there was an error reading the buffer, release it, we // already logged the error Err(err) => { warn!(log, "Error loading buffer: {:?}", err); + buffer.release(); } }; } @@ -135,7 +143,7 @@ where if let Some(ref data) = attributes.user_data.get::>() { let mut data = data.borrow_mut(); let (sub_x, sub_y) = data.current_state.sub_location; - if let Some(buffer_textures) = data + if let Some(texture) = data .texture .as_mut() .and_then(|x| x.downcast_mut::>()) @@ -146,11 +154,8 @@ where x += sub_x; y += sub_y; } - let texture = buffer_textures - .load_texture(renderer_id, renderer, texture_destruction_callback) - .unwrap(); if let Err(err) = - renderer.render_texture_at(texture, (x, y), Transform::Normal /* TODO */, 1.0) + renderer.render_texture_at(&texture.texture, (x, y), Transform::Normal /* TODO */, 1.0) { result = Err(err.into()); } @@ -165,9 +170,7 @@ where pub fn draw_windows( renderer: &mut R, - renderer_id: u64, - texture_destruction_callback: &Sender, - buffer_utils: &BufferUtils, + egl_buffer_reader: Option<&EGLBufferReader>, window_map: &MyWindowMap, output_rect: Option, compositor_token: MyCompositorToken, @@ -193,10 +196,8 @@ where // this surface is a root of a subsurface tree that needs to be drawn if let Err(err) = draw_surface_tree( renderer, - renderer_id, - texture_destruction_callback, - buffer_utils, &wl_surface, + egl_buffer_reader, initial_place, compositor_token, log, @@ -211,10 +212,8 @@ where pub fn draw_dnd_icon( renderer: &mut R, - renderer_id: u64, - texture_destruction_callback: &Sender, - buffer_utils: &BufferUtils, surface: &wl_surface::WlSurface, + egl_buffer_reader: Option<&EGLBufferReader>, (x, y): (i32, i32), token: MyCompositorToken, log: &::slog::Logger, @@ -232,10 +231,8 @@ where } draw_surface_tree( renderer, - renderer_id, - texture_destruction_callback, - buffer_utils, surface, + egl_buffer_reader, (x, y), token, log, diff --git a/anvil/src/main.rs b/anvil/src/main.rs index 20f58bf..e1e72cb 100644 --- a/anvil/src/main.rs +++ b/anvil/src/main.rs @@ -10,7 +10,6 @@ use std::{cell::RefCell, rc::Rc}; use slog::Drain; use smithay::reexports::{calloop::EventLoop, wayland_server::Display}; -mod buffer_utils; mod drawing; mod input_handler; mod shell; diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index c531ecd..e5454c2 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -5,6 +5,7 @@ use std::{ }; use smithay::{ + backend::renderer::buffer_dimensions, reexports::{ wayland_protocols::xdg_shell::server::xdg_toplevel, wayland_server::{ @@ -32,11 +33,10 @@ use smithay::{ Serial, }, }; +#[cfg(feature = "egl")] +use smithay::backend::egl::display::EGLBufferReader; -use crate::{ - buffer_utils::BufferUtils, - window_map::{Kind as SurfaceKind, WindowMap}, -}; +use crate::window_map::{Kind as SurfaceKind, WindowMap}; #[cfg(feature = "xwayland")] use crate::xwayland::X11SurfaceRole; @@ -308,7 +308,12 @@ pub struct ShellHandles { pub window_map: Rc>, } -pub fn init_shell(display: &mut Display, buffer_utils: BufferUtils, log: ::slog::Logger) -> ShellHandles { +pub fn init_shell( + display: &mut Display, + #[cfg(feature = "egl")] + egl_reader: Rc>>, + log: ::slog::Logger +) -> ShellHandles { // TODO: this is awkward... let almost_window_map = Rc::new(RefCell::new(None::>>)); let almost_window_map_compositor = almost_window_map.clone(); @@ -320,7 +325,14 @@ pub fn init_shell(display: &mut Display, buffer_utils: BufferUtils, log: ::slog: SurfaceEvent::Commit => { let window_map = almost_window_map_compositor.borrow(); let window_map = window_map.as_ref().unwrap(); - surface_commit(&surface, ctoken, &buffer_utils, &*window_map) + #[cfg(feature = "egl")] + { + surface_commit(&surface, ctoken, egl_reader.borrow().as_ref(), &*window_map) + } + #[cfg(not(feature = "egl"))] + { + surface_commit(&surface, ctoken, &*window_map) + } } }, log.clone(), @@ -782,7 +794,8 @@ impl SurfaceData { fn surface_commit( surface: &wl_surface::WlSurface, token: CompositorToken, - buffer_utils: &BufferUtils, + #[cfg(feature = "egl")] + egl_reader: Option<&EGLBufferReader>, window_map: &RefCell, ) { #[cfg(feature = "xwayland")] @@ -834,7 +847,14 @@ fn surface_commit( match attributes.buffer.take() { Some(BufferAssignment::NewBuffer { buffer, .. }) => { // new contents - next_state.dimensions = buffer_utils.dimensions(&buffer); + #[cfg(feature = "egl")] + { + next_state.dimensions = buffer_dimensions(&buffer, egl_reader); + } + #[cfg(not(feature = "egl"))] + { + next_state.dimensions = buffer_dimensions(&buffer, None); + } next_state.buffer = Some(buffer); } Some(BufferAssignment::Removed) => { diff --git a/anvil/src/state.rs b/anvil/src/state.rs index e703e4e..9fa7ff7 100644 --- a/anvil/src/state.rs +++ b/anvil/src/state.rs @@ -27,12 +27,14 @@ use smithay::{ use smithay::backend::session::{auto::AutoSession, Session}; #[cfg(feature = "xwayland")] use smithay::xwayland::XWayland; +#[cfg(feature = "egl")] +use smithay::backend::egl::display::EGLBufferReader; #[cfg(feature = "udev")] use crate::udev::MyOutput; #[cfg(feature = "xwayland")] use crate::xwayland::XWm; -use crate::{buffer_utils::BufferUtils, shell::init_shell}; +use crate::shell::init_shell; pub struct AnvilState { pub socket_name: String, @@ -63,7 +65,7 @@ impl AnvilState { pub fn init( display: Rc>, handle: LoopHandle, - buffer_utils: BufferUtils, + #[cfg(feature = "egl")] egl_reader: Rc>>, #[cfg(feature = "udev")] session: Option, #[cfg(not(feature = "udev"))] _session: Option<()>, #[cfg(feature = "udev")] output_map: Option>>>, @@ -96,7 +98,10 @@ impl AnvilState { init_shm_global(&mut display.borrow_mut(), vec![], log.clone()); - let shell_handles = init_shell(&mut display.borrow_mut(), buffer_utils, log.clone()); + #[cfg(feature = "egl")] + let shell_handles = init_shell(&mut display.borrow_mut(), egl_reader, log.clone()); + #[cfg(not(feature = "egl"))] + let shell_handles = init_shell(&mut display.borrow_mut(), log.clone()); let socket_name = display .borrow_mut() diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 8272c83..b64da5a 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -5,7 +5,7 @@ use std::{ os::unix::io::{AsRawFd, RawFd}, path::PathBuf, rc::Rc, - sync::{atomic::Ordering, mpsc, Arc, Mutex}, + sync::{atomic::Ordering, Arc, Mutex}, time::Duration, }; @@ -14,15 +14,15 @@ use slog::Logger; use smithay::{ backend::{ - drm::{device_bind, DevPath, DeviceHandler, DrmDevice, DrmError, DrmRenderSurface}, - egl::{display::EGLBufferReader, EGLContext, EGLDisplay}, + drm::{device_bind, DeviceHandler, DrmDevice, DrmError, DrmRenderSurface}, + egl::{EGLContext, EGLDisplay}, libinput::{LibinputInputBackend, LibinputSessionInterface}, renderer::{ gles2::{Gles2Renderer, Gles2Texture}, Renderer, Transform, }, session::{auto::AutoSession, Session, Signal as SessionSignal}, - udev::{primary_gpu, UdevBackend, UdevEvent}, + udev::{UdevBackend, UdevEvent}, SwapBuffersError, }, reexports::{ @@ -56,8 +56,11 @@ use smithay::{ seat::CursorImageStatus, }, }; +#[cfg(feature = "egl")] +use smithay::{ + backend::{drm::DevPath, egl::display::EGLBufferReader, udev::primary_gpu}, +}; -use crate::buffer_utils::BufferUtils; use crate::drawing::*; use crate::shell::{MyWindowMap, Roles}; use crate::state::AnvilState; @@ -87,11 +90,6 @@ pub fn run_udev( #[cfg(feature = "egl")] let egl_buffer_reader = Rc::new(RefCell::new(None)); - #[cfg(feature = "egl")] - let buffer_utils = BufferUtils::new(egl_buffer_reader.clone(), log.clone()); - #[cfg(not(feature = "egl"))] - let buffer_utils = BufferUtils::new(log.clone()); - let output_map = Rc::new(RefCell::new(Vec::new())); /* @@ -106,7 +104,8 @@ pub fn run_udev( let mut state = AnvilState::init( display.clone(), event_loop.handle(), - buffer_utils.clone(), + #[cfg(feature = "egl")] + egl_buffer_reader.clone(), Some(session), Some(output_map.clone()), log.clone(), @@ -115,21 +114,19 @@ pub fn run_udev( /* * Initialize the udev backend */ - let primary_gpu = primary_gpu(&state.seat_name).unwrap_or_default(); - let bytes = include_bytes!("../resources/cursor2.rgba"); let udev_backend = UdevBackend::new(state.seat_name.clone(), log.clone()).map_err(|_| ())?; let mut udev_handler = UdevHandlerImpl { compositor_token: state.ctoken, - buffer_utils, #[cfg(feature = "egl")] egl_buffer_reader, session: state.session.clone().unwrap(), backends: HashMap::new(), output_map, display: display.clone(), - primary_gpu, + #[cfg(feature = "egl")] + primary_gpu: primary_gpu(&state.seat_name).unwrap_or_default(), window_map: state.window_map.clone(), pointer_location: state.pointer_location.clone(), pointer_image: ImageBuffer::from_raw(64, 64, bytes.to_vec()).unwrap(), @@ -282,12 +279,12 @@ struct BackendData { struct UdevHandlerImpl { compositor_token: CompositorToken, - buffer_utils: BufferUtils, #[cfg(feature = "egl")] egl_buffer_reader: Rc>>, session: AutoSession, backends: HashMap, display: Rc>, + #[cfg(feature = "egl")] primary_gpu: Option, window_map: Rc>, output_map: Rc>>, @@ -453,10 +450,12 @@ impl UdevHandlerImpl { } }; + #[cfg(feature = "egl")] + let is_primary = path.canonicalize().ok() == self.primary_gpu; // init hardware acceleration on the primary gpu. #[cfg(feature = "egl")] { - if path.canonicalize().ok() == self.primary_gpu { + if is_primary { info!( self.logger, "Initializing EGL Hardware Acceleration via {:?}", path @@ -501,10 +500,10 @@ impl UdevHandlerImpl { // to introduce reference cycles with Rc. Be sure about your drop order let renderer = Rc::new(DrmRenderer { device_id, - buffer_utils: self.buffer_utils.clone(), + #[cfg(feature = "egl")] + egl_buffer_reader: if is_primary { self.egl_buffer_reader.borrow().clone() } else { None }, compositor_token: self.compositor_token, backends: backends.clone(), - texture_destruction_callback: mpsc::channel(), window_map: self.window_map.clone(), output_map: self.output_map.clone(), pointer_location: self.pointer_location.clone(), @@ -595,12 +594,12 @@ impl UdevHandlerImpl { .borrow_mut() .retain(|output| output.device_id != device); - let device = self.loop_handle.remove(backend_data.event_source).unwrap(); + let _device = self.loop_handle.remove(backend_data.event_source).unwrap(); // don't use hardware acceleration anymore, if this was the primary gpu #[cfg(feature = "egl")] { - if device.dev_path().and_then(|path| path.canonicalize().ok()) == self.primary_gpu { + if _device.dev_path().and_then(|path| path.canonicalize().ok()) == self.primary_gpu { *self.egl_buffer_reader.borrow_mut() = None; } } @@ -641,10 +640,10 @@ impl DrmRendererSessionListener { pub struct DrmRenderer { device_id: dev_t, - buffer_utils: BufferUtils, + #[cfg(feature = "egl")] + egl_buffer_reader: Option, compositor_token: CompositorToken, backends: Rc>>>>, - texture_destruction_callback: (mpsc::Sender, mpsc::Receiver), window_map: Rc>, output_map: Rc>>, pointer_location: Rc>, @@ -670,8 +669,8 @@ impl DrmRenderer { if let Some(surface) = self.backends.borrow().get(&crtc) { let result = DrmRenderer::render_surface( &mut *surface.borrow_mut(), - &self.texture_destruction_callback.0, - &self.buffer_utils, + #[cfg(feature = "egl")] + self.egl_buffer_reader.as_ref(), self.device_id, crtc, &mut *self.window_map.borrow_mut(), @@ -735,10 +734,6 @@ impl DrmRenderer { self.window_map .borrow() .send_frames(self.start_time.elapsed().as_millis() as u32); - - while let Ok(texture) = self.texture_destruction_callback.1.try_recv() { - let _ = surface.borrow_mut().destroy_texture(texture); - } } } } @@ -746,8 +741,8 @@ impl DrmRenderer { #[allow(clippy::too_many_arguments)] fn render_surface( surface: &mut RenderSurface, - texture_destruction_callback: &mpsc::Sender, - buffer_utils: &BufferUtils, + #[cfg(feature = "egl")] + egl_buffer_reader: Option<&EGLBufferReader>, device_id: dev_t, crtc: crtc::Handle, window_map: &mut MyWindowMap, @@ -759,6 +754,9 @@ impl DrmRenderer { cursor_status: &mut CursorImageStatus, logger: &slog::Logger, ) -> Result<(), SwapBuffersError> { + #[cfg(not(feature = "egl"))] + let egl_buffer_reader = None; + surface.frame_submitted()?; // get output coordinates @@ -778,9 +776,7 @@ impl DrmRenderer { // draw the surfaces draw_windows( surface, - device_id, - texture_destruction_callback, - buffer_utils, + egl_buffer_reader, window_map, Some(Rectangle { x: x as i32, @@ -805,10 +801,8 @@ impl DrmRenderer { if wl_surface.as_ref().is_alive() { draw_dnd_icon( surface, - device_id, - texture_destruction_callback, - buffer_utils, wl_surface, + egl_buffer_reader, (ptr_x, ptr_y), *compositor_token, logger, @@ -830,10 +824,8 @@ impl DrmRenderer { if let CursorImageStatus::Image(ref wl_surface) = *cursor_status { draw_cursor( surface, - device_id, - texture_destruction_callback, - buffer_utils, wl_surface, + egl_buffer_reader, (ptr_x, ptr_y), *compositor_token, logger, diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index daecb36..eb4a15b 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -1,7 +1,5 @@ use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration}; -//#[cfg(feature = "egl")] -//use smithay::backend::egl::EGLGraphicsBackend; use smithay::{ backend::{input::InputBackend, renderer::Renderer, winit, SwapBuffersError}, reexports::{ @@ -16,7 +14,6 @@ use smithay::{ use slog::Logger; -use crate::buffer_utils::BufferUtils; use crate::drawing::*; use crate::state::AnvilState; @@ -25,26 +22,22 @@ pub fn run_winit( event_loop: &mut EventLoop, log: Logger, ) -> Result<(), ()> { - let (mut renderer, mut input) = winit::init(log.clone()).map_err(|err| { + let (renderer, mut input) = winit::init(log.clone()).map_err(|err| { slog::crit!(log, "Failed to initialize Winit backend: {}", err); })?; + let renderer = Rc::new(RefCell::new(renderer)); #[cfg(feature = "egl")] - let egl_buffer_reader = Rc::new(RefCell::new( - if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) { - info!(log, "EGL hardware-acceleration enabled"); - Some(egl_buffer_reader) - } else { - None - }, - )); - - #[cfg(feature = "egl")] - let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone()); + let reader = renderer.borrow().bind_wl_display(&display.borrow()).ok(); #[cfg(not(feature = "egl"))] - let buffer_utils = BufferUtils::new(log.clone()); + let reader = None; - let (w, h): (u32, u32) = renderer.window_size().physical_size.into(); + #[cfg(feature = "egl")] + if reader.is_some() { + info!(log, "EGL hardware-acceleration enabled"); + }; + + let (w, h): (u32, u32) = renderer.borrow().window_size().physical_size.into(); /* * Initialize the globals @@ -53,7 +46,8 @@ pub fn run_winit( let mut state = AnvilState::init( display.clone(), event_loop.handle(), - buffer_utils.clone(), + #[cfg(feature = "egl")] + Rc::new(RefCell::new(reader.clone())), None, None, log.clone(), @@ -91,7 +85,6 @@ pub fn run_winit( info!(log, "Initialization completed, starting the main loop."); - let (texture_send, texture_receive) = std::sync::mpsc::channel(); while state.running.load(Ordering::SeqCst) { if input .dispatch_new_events(|event, _| state.process_input_event(event)) @@ -110,6 +103,8 @@ pub fn run_winit( // drawing logic { + let mut renderer = renderer.borrow_mut(); + renderer.begin().expect("Failed to render frame"); renderer .clear([0.8, 0.8, 0.9, 1.0]) @@ -117,10 +112,8 @@ pub fn run_winit( // draw the windows draw_windows( - &mut renderer, - 0, - &texture_send, - &buffer_utils, + &mut *renderer, + reader.as_ref(), &*state.window_map.borrow(), None, state.ctoken, @@ -135,11 +128,9 @@ pub fn run_winit( if let Some(ref surface) = *guard { if surface.as_ref().is_alive() { draw_dnd_icon( - &mut renderer, - 0, - &texture_send, - &buffer_utils, + &mut *renderer, surface, + reader.as_ref(), (x as i32, y as i32), state.ctoken, &log, @@ -164,11 +155,9 @@ pub fn run_winit( if let CursorImageStatus::Image(ref surface) = *guard { renderer.window().set_cursor_visible(false); draw_cursor( - &mut renderer, - 0, - &texture_send, - &buffer_utils, + &mut *renderer, surface, + reader.as_ref(), (x as i32, y as i32), state.ctoken, &log, @@ -194,10 +183,6 @@ pub fn run_winit( display.borrow_mut().flush_clients(&mut state); state.window_map.borrow_mut().refresh(); } - - while let Ok(texture) = texture_receive.try_recv() { - let _ = renderer.destroy_texture(texture); - } } // Cleanup stuff