anvil: Update to new renderer changes

This commit is contained in:
Victor Brekenfeld 2021-05-13 19:59:47 +02:00
parent f0e7ff3312
commit b4f216d7b8
7 changed files with 118 additions and 292 deletions

View File

@ -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<RefCell<Option<EGLBufferReader>>>,
log: ::slog::Logger,
}
impl BufferUtils {
/// Creates a new `BufferUtils`.
#[cfg(feature = "egl")]
pub fn new(egl_buffer_reader: Rc<RefCell<Option<EGLBufferReader>>>, 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<T>(&self, buffer: WlBuffer) -> Result<BufferTextures<T>, 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<T>(&self, buffer: WlBuffer) -> Result<BufferTextures<T>, WlBuffer> {
Ok(BufferTextures {
buffer,
textures: HashMap::new(),
callbacks: HashMap::new(),
})
}
}
#[cfg(feature = "udev")]
pub struct BufferTextures<T> {
buffer: WlBuffer,
pub textures: HashMap<dev_t, T>,
callbacks: HashMap<dev_t, Sender<T>>,
#[cfg(feature = "egl")]
egl: Option<EGLBuffer>,
}
#[cfg(feature = "udev")]
impl<T: Texture> BufferTextures<T> {
#[cfg(feature = "egl")]
pub fn load_texture<'a, R: Renderer<TextureId = T>>(
&'a mut self,
id: u64,
renderer: &mut R,
texture_destruction_callback: &Sender<T>,
) -> 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<TextureId = T>>(
&'a mut self,
id: u64,
renderer: &mut R,
texture_destruction_callback: &Sender<T>,
) -> 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<TextureId = T>>(
&'a mut self,
id: u64,
renderer: &mut R,
texture_destruction_callback: &Sender<T>,
) -> 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<T> Drop for BufferTextures<T> {
fn drop(&mut self) {
self.buffer.release();
for (id, texture) in self.textures.drain() {
self.callbacks.get(&id).unwrap().send(texture).unwrap();
}
}
}

View File

@ -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<T> {
buffer: wl_buffer::WlBuffer,
texture: T,
}
impl<T> Drop for BufferTextures<T> {
fn drop(&mut self) {
self.buffer.release();
}
}
pub fn draw_cursor<R, E, T>(
renderer: &mut R,
renderer_id: u64,
texture_destruction_callback: &Sender<T>,
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<R, E, T>(
renderer: &mut R,
renderer_id: u64,
texture_destruction_callback: &Sender<T>,
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::<R::TextureId>(buffer) {
Ok(m) => data.texture = Some(Box::new(m) as Box<dyn std::any::Any + 'static>),
match renderer.import_buffer(&buffer, egl_buffer_reader) {
Ok(m) => data.texture = Some(Box::new(BufferTextures { buffer, texture: m }) as Box<dyn std::any::Any + 'static>),
// 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::<RefCell<SurfaceData>>() {
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::<BufferTextures<T>>())
@ -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<R, E, T>(
renderer: &mut R,
renderer_id: u64,
texture_destruction_callback: &Sender<T>,
buffer_utils: &BufferUtils,
egl_buffer_reader: Option<&EGLBufferReader>,
window_map: &MyWindowMap,
output_rect: Option<Rectangle>,
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<R, E, T>(
renderer: &mut R,
renderer_id: u64,
texture_destruction_callback: &Sender<T>,
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,

View File

@ -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;

View File

@ -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<RefCell<MyWindowMap>>,
}
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<RefCell<Option<EGLBufferReader>>>,
log: ::slog::Logger
) -> ShellHandles {
// TODO: this is awkward...
let almost_window_map = Rc::new(RefCell::new(None::<Rc<RefCell<MyWindowMap>>>));
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<Roles>,
buffer_utils: &BufferUtils,
#[cfg(feature = "egl")]
egl_reader: Option<&EGLBufferReader>,
window_map: &RefCell<MyWindowMap>,
) {
#[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) => {

View File

@ -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<RefCell<Display>>,
handle: LoopHandle<AnvilState>,
buffer_utils: BufferUtils,
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
#[cfg(feature = "udev")] session: Option<AutoSession>,
#[cfg(not(feature = "udev"))] _session: Option<()>,
#[cfg(feature = "udev")] output_map: Option<Rc<RefCell<Vec<MyOutput>>>>,
@ -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()

View File

@ -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<Data: 'static> {
compositor_token: CompositorToken<Roles>,
buffer_utils: BufferUtils,
#[cfg(feature = "egl")]
egl_buffer_reader: Rc<RefCell<Option<EGLBufferReader>>>,
session: AutoSession,
backends: HashMap<dev_t, BackendData>,
display: Rc<RefCell<Display>>,
#[cfg(feature = "egl")]
primary_gpu: Option<PathBuf>,
window_map: Rc<RefCell<MyWindowMap>>,
output_map: Rc<RefCell<Vec<MyOutput>>>,
@ -453,10 +450,12 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
}
};
#[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<Data: 'static> UdevHandlerImpl<Data> {
// 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<Data: 'static> UdevHandlerImpl<Data> {
.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<Data: 'static> DrmRendererSessionListener<Data> {
pub struct DrmRenderer {
device_id: dev_t,
buffer_utils: BufferUtils,
#[cfg(feature = "egl")]
egl_buffer_reader: Option<EGLBufferReader>,
compositor_token: CompositorToken<Roles>,
backends: Rc<RefCell<HashMap<crtc::Handle, Rc<RefCell<RenderSurface>>>>>,
texture_destruction_callback: (mpsc::Sender<Gles2Texture>, mpsc::Receiver<Gles2Texture>),
window_map: Rc<RefCell<MyWindowMap>>,
output_map: Rc<RefCell<Vec<MyOutput>>>,
pointer_location: Rc<RefCell<(f64, f64)>>,
@ -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<Gles2Texture>,
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,

View File

@ -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<AnvilState>,
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