anvil/udev: do not upload a cursor every frame

This commit is contained in:
Victor Brekenfeld 2020-06-12 21:19:57 +02:00
parent 7e75a68e57
commit f84d6cb180
1 changed files with 13 additions and 10 deletions

View File

@ -5,7 +5,7 @@ use std::{
os::unix::io::{AsRawFd, RawFd}, os::unix::io::{AsRawFd, RawFd},
path::PathBuf, path::PathBuf,
rc::Rc, rc::Rc,
sync::{atomic::Ordering, Arc, Mutex}, sync::{atomic::{Ordering, AtomicBool}, Arc, Mutex},
time::Duration, time::Duration,
}; };
@ -488,6 +488,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
pointer_image: self.pointer_image.clone(), pointer_image: self.pointer_image.clone(),
cursor_status: self.cursor_status.clone(), cursor_status: self.cursor_status.clone(),
dnd_icon: self.dnd_icon.clone(), dnd_icon: self.dnd_icon.clone(),
hardware_cursor: AtomicBool::new(false),
logger: self.logger.clone(), logger: self.logger.clone(),
}); });
let mut listener = DrmRendererSessionListener { let mut listener = DrmRendererSessionListener {
@ -626,6 +627,7 @@ pub struct DrmRenderer {
pointer_image: ImageBuffer<Rgba<u8>, Vec<u8>>, pointer_image: ImageBuffer<Rgba<u8>, Vec<u8>>,
cursor_status: Arc<Mutex<CursorImageStatus>>, cursor_status: Arc<Mutex<CursorImageStatus>>,
dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>, dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>,
hardware_cursor: AtomicBool,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
@ -681,7 +683,7 @@ impl DrmRenderer {
.borrow() .borrow()
.set_cursor_position(ptr_x as u32, ptr_y as u32); .set_cursor_position(ptr_x as u32, ptr_y as u32);
let mut software_cursor = false; let mut needs_software_cursor = false;
// draw the dnd icon if applicable // draw the dnd icon if applicable
{ {
@ -694,7 +696,7 @@ impl DrmRenderer {
(ptr_x, ptr_y), (ptr_x, ptr_y),
self.compositor_token, self.compositor_token,
); );
software_cursor = true; //needs_software_cursor = true;
} }
} }
} }
@ -711,25 +713,26 @@ impl DrmRenderer {
} }
if let CursorImageStatus::Image(ref surface) = *guard { if let CursorImageStatus::Image(ref surface) = *guard {
drawer.draw_cursor(&mut frame, surface, (ptr_x, ptr_y), self.compositor_token); drawer.draw_cursor(&mut frame, surface, (ptr_x, ptr_y), self.compositor_token);
software_cursor = true; needs_software_cursor = true;
} }
} }
// TODO: this is wasteful, only do this on change (cache previous software cursor state) if needs_software_cursor && self.hardware_cursor.swap(false, Ordering::AcqRel) {
if software_cursor { if let Err(err) = drawer.borrow().set_cursor_representation(&empty, (0, 0)) {
if let Err(err) = drawer.borrow().set_cursor_representation(&empty, (2, 2)) {
error!(self.logger, "Error setting cursor: {}", err); error!(self.logger, "Error setting cursor: {}", err);
} }
} else { } else if !needs_software_cursor && !self.hardware_cursor.swap(true, Ordering::AcqRel) {
if let Err(err) = drawer.borrow().set_cursor_representation(&self.pointer_image, (2, 2)) { if let Err(err) = drawer.borrow().set_cursor_representation(&self.pointer_image, (2, 2)) {
error!(self.logger, "Error setting cursor: {}", err); error!(self.logger, "Error setting cursor: {}", err);
} }
} }
} else { } else {
if let Err(err) = drawer.borrow().set_cursor_representation(&empty, (2, 2)) { if self.hardware_cursor.swap(false, Ordering::AcqRel) {
if let Err(err) = drawer.borrow().set_cursor_representation(&empty, (0, 0)) {
error!(self.logger, "Error setting cursor: {}", err); error!(self.logger, "Error setting cursor: {}", err);
} }
} }
}
if let Err(err) = frame.finish() { if let Err(err) = frame.finish() {
warn!(self.logger, "Error during rendering: {:?}", err); warn!(self.logger, "Error during rendering: {:?}", err);