use memory for system cursor

smithay only considers memory based
cursor elements for scan-out on a
cursor plane.
This commit is contained in:
Christian Meissl 2024-02-12 20:10:44 +01:00 • committed by Victoria Brekenfeld
parent d1aac380ff
commit e74b0dfaaa
2 changed files with 21 additions and 35 deletions

View file

@ -6,8 +6,8 @@ use smithay::{
allocator::Fourcc, allocator::Fourcc,
renderer::{ renderer::{
element::{ element::{
memory::{MemoryRenderBuffer, MemoryRenderBufferRenderElement},
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement}, surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
texture::{TextureBuffer, TextureRenderElement},
Kind, Kind,
}, },
ImportAll, ImportMem, Renderer, ImportAll, ImportMem, Renderer,
@ -22,14 +22,7 @@ use smithay::{
utils::{IsAlive, Logical, Monotonic, Point, Scale, Time, Transform}, utils::{IsAlive, Logical, Monotonic, Point, Scale, Time, Transform},
wayland::compositor::{get_role, with_states}, wayland::compositor::{get_role, with_states},
}; };
use std::{ use std::{cell::RefCell, collections::HashMap, io::Read, sync::Mutex, time::Duration};
any::{Any, TypeId},
cell::RefCell,
collections::HashMap,
io::Read,
sync::Mutex,
time::Duration,
};
use tracing::warn; use tracing::warn;
use xcursor::{ use xcursor::{
parser::{parse_xcursor, Image}, parser::{parse_xcursor, Image},
@ -137,8 +130,8 @@ fn load_icon(theme: &CursorTheme, shape: CursorShape) -> Result<Vec<Image>, Erro
} }
render_elements! { render_elements! {
pub CursorRenderElement<R> where R: ImportAll; pub CursorRenderElement<R> where R: ImportAll + ImportMem;
Static=TextureRenderElement<<R as Renderer>::TextureId>, Static=MemoryRenderBufferRenderElement<R>,
Surface=WaylandSurfaceRenderElement<R>, Surface=WaylandSurfaceRenderElement<R>,
} }
@ -209,7 +202,7 @@ pub struct CursorState {
current_cursor: RefCell<CursorShape>, current_cursor: RefCell<CursorShape>,
pub cursors: HashMap<CursorShape, Cursor>, pub cursors: HashMap<CursorShape, Cursor>,
current_image: RefCell<Option<Image>>, current_image: RefCell<Option<Image>>,
image_cache: RefCell<HashMap<(TypeId, usize), Vec<(Image, Box<dyn Any + 'static>)>>>, image_cache: RefCell<Vec<(Image, MemoryRenderBuffer)>>,
} }
impl CursorState { impl CursorState {
@ -255,7 +248,7 @@ impl Default for CursorState {
map map
}, },
current_image: RefCell::new(None), current_image: RefCell::new(None),
image_cache: RefCell::new(HashMap::new()), image_cache: RefCell::new(Vec::new()),
} }
} }
} }
@ -307,34 +300,25 @@ where
Into::<Duration>::into(time).as_millis() as u32, Into::<Duration>::into(time).as_millis() as u32,
); );
let mut cache = state.image_cache.borrow_mut(); let mut pointer_images = state.image_cache.borrow_mut();
let pointer_images = cache
.entry((TypeId::of::<TextureBuffer<R::TextureId>>(), renderer.id()))
.or_default();
let maybe_image = pointer_images let maybe_image =
.iter() pointer_images
.find_map(|(image, texture)| if image == &frame { Some(texture) } else { None }) .iter()
.and_then(|texture| texture.downcast_ref::<TextureBuffer<R::TextureId>>()); .find_map(|(image, texture)| if image == &frame { Some(texture) } else { None });
let pointer_image = match maybe_image { let pointer_image = match maybe_image {
Some(image) => image, Some(image) => image,
None => { None => {
let texture = TextureBuffer::from_memory( let buffer = MemoryRenderBuffer::from_slice(
renderer,
&frame.pixels_rgba, &frame.pixels_rgba,
Fourcc::Abgr8888, Fourcc::Argb8888,
(frame.width as i32, frame.height as i32), (frame.width as i32, frame.height as i32),
false,
integer_scale as i32, integer_scale as i32,
Transform::Normal, Transform::Normal,
None, None,
) );
.expect("Failed to import cursor bitmap"); pointer_images.push((frame.clone(), buffer));
pointer_images.push((frame.clone(), Box::new(texture.clone()))); pointer_images.last().map(|(_, i)| i).unwrap()
pointer_images
.last()
.and_then(|(_, i)| i.downcast_ref::<TextureBuffer<R::TextureId>>())
.unwrap()
} }
}; };
@ -342,14 +326,16 @@ where
*state.current_image.borrow_mut() = Some(frame); *state.current_image.borrow_mut() = Some(frame);
return vec![CursorRenderElement::Static( return vec![CursorRenderElement::Static(
TextureRenderElement::from_texture_buffer( MemoryRenderBufferRenderElement::from_buffer(
renderer,
(location - hotspot).to_physical(scale), (location - hotspot).to_physical(scale),
pointer_image, pointer_image,
None, None,
None, None,
None, None,
Kind::Cursor, Kind::Cursor,
), )
.expect("Failed to import cursor bitmap"),
)]; )];
} else { } else {
Vec::new() Vec::new()

View file

@ -909,7 +909,7 @@ pub fn render_workspace_to_buffer(
} }
smithay::render_elements! { smithay::render_elements! {
pub WindowCaptureElement<R> where R: ImportAll; pub WindowCaptureElement<R> where R: ImportAll + ImportMem;
WaylandElement=WaylandSurfaceRenderElement<R>, WaylandElement=WaylandSurfaceRenderElement<R>,
CursorElement=cursor::CursorRenderElement<R>, CursorElement=cursor::CursorRenderElement<R>,
} }