use pixman for cursor plane rendering

This commit is contained in:
Christian Meissl 2024-01-23 20:44:47 +01:00 committed by Ivan Molodetskikh
parent 5f99eb13ab
commit 73f3c160b2
4 changed files with 53 additions and 48 deletions

25
Cargo.lock generated
View File

@ -2122,6 +2122,12 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]] [[package]]
name = "peeking_take_while" name = "peeking_take_while"
version = "0.1.2" version = "0.1.2"
@ -2185,6 +2191,24 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "pixman"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d24a24da0bec14f4e43a495c1837a3c358b87532e7fe66bd75c348b89f0451b6"
dependencies = [
"drm-fourcc",
"paste",
"pixman-sys",
"thiserror",
]
[[package]]
name = "pixman-sys"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a0483e89e81d7915defe83c51f23f6800594d64f6f4a21253ce87fd8444ada"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.29" version = "0.3.29"
@ -2714,6 +2738,7 @@ dependencies = [
"libloading", "libloading",
"libseat", "libseat",
"once_cell", "once_cell",
"pixman",
"pkg-config", "pkg-config",
"profiling", "profiling",
"rand", "rand",

View File

@ -80,6 +80,7 @@ features = [
"backend_winit", "backend_winit",
"desktop", "desktop",
"renderer_gl", "renderer_gl",
"renderer_pixman",
"renderer_multi", "renderer_multi",
"use_system_lib", "use_system_lib",
"wayland_frontend", "wayland_frontend",

View File

@ -8,8 +8,7 @@ use std::sync::Mutex;
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use smithay::backend::allocator::Fourcc; use smithay::backend::allocator::Fourcc;
use smithay::backend::renderer::element::texture::TextureBuffer; use smithay::backend::renderer::element::memory::MemoryRenderBuffer;
use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus}; use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus};
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{IsAlive, Logical, Physical, Point, Transform}; use smithay::utils::{IsAlive, Logical, Physical, Point, Transform};
@ -224,7 +223,7 @@ pub enum RenderCursor {
}, },
} }
type TextureCache = HashMap<(CursorIcon, i32), Vec<Option<TextureBuffer<GlesTexture>>>>; type TextureCache = HashMap<(CursorIcon, i32), Vec<MemoryRenderBuffer>>;
#[derive(Default)] #[derive(Default)]
pub struct CursorTextureCache { pub struct CursorTextureCache {
@ -238,12 +237,11 @@ impl CursorTextureCache {
pub fn get( pub fn get(
&self, &self,
renderer: &mut GlesRenderer,
icon: CursorIcon, icon: CursorIcon,
scale: i32, scale: i32,
cursor: &XCursor, cursor: &XCursor,
idx: usize, idx: usize,
) -> Option<TextureBuffer<GlesTexture>> { ) -> MemoryRenderBuffer {
self.cache self.cache
.borrow_mut() .borrow_mut()
.entry((icon, scale)) .entry((icon, scale))
@ -252,26 +250,14 @@ impl CursorTextureCache {
.frames() .frames()
.iter() .iter()
.map(|frame| { .map(|frame| {
let _span = tracy_client::span!("create TextureBuffer"); MemoryRenderBuffer::from_slice(
let buffer = TextureBuffer::from_memory(
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,
scale, scale,
Transform::Normal, Transform::Normal,
None, None,
); )
match buffer {
Ok(x) => Some(x),
Err(err) => {
warn!("error creating a cursor texture: {err:?}");
None
}
}
}) })
.collect() .collect()
})[idx] })[idx]

View File

@ -13,11 +13,11 @@ use anyhow::Context;
use calloop::futures::Scheduler; use calloop::futures::Scheduler;
use niri_config::{Config, TrackLayout}; use niri_config::{Config, TrackLayout};
use smithay::backend::allocator::Fourcc; use smithay::backend::allocator::Fourcc;
use smithay::backend::renderer::element::memory::MemoryRenderBufferRenderElement;
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement}; use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
use smithay::backend::renderer::element::surface::{ use smithay::backend::renderer::element::surface::{
render_elements_from_surface_tree, WaylandSurfaceRenderElement, render_elements_from_surface_tree, WaylandSurfaceRenderElement,
}; };
use smithay::backend::renderer::element::texture::TextureRenderElement;
use smithay::backend::renderer::element::utils::select_dmabuf_feedback; use smithay::backend::renderer::element::utils::select_dmabuf_feedback;
use smithay::backend::renderer::element::{ use smithay::backend::renderer::element::{
default_primary_scanout_output_compare, AsRenderElements, Element, Id, Kind, RenderElement, default_primary_scanout_output_compare, AsRenderElements, Element, Id, Kind, RenderElement,
@ -106,7 +106,7 @@ use crate::input::{apply_libinput_settings, TabletData};
use crate::ipc::server::IpcServer; use crate::ipc::server::IpcServer;
use crate::layout::{Layout, MonitorRenderElement}; use crate::layout::{Layout, MonitorRenderElement};
use crate::pw_utils::{Cast, PipeWire}; use crate::pw_utils::{Cast, PipeWire};
use crate::render_helpers::{NiriRenderer, PrimaryGpuTextureRenderElement}; use crate::render_helpers::NiriRenderer;
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement}; use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
use crate::utils::{ use crate::utils::{
center, get_monotonic_time, make_screenshot_path, output_size, write_png_rgba8, center, get_monotonic_time, make_screenshot_path, output_size, write_png_rgba8,
@ -1670,26 +1670,25 @@ impl Niri {
let pointer_pos = let pointer_pos =
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale); (pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
let texture = self.cursor_texture_cache.get( let texture = self.cursor_texture_cache.get(icon, scale, &cursor, idx);
renderer.as_gles_renderer(),
icon,
scale,
&cursor,
idx,
);
let mut pointer_elements = vec![]; let mut pointer_elements = vec![];
if let Some(texture) = texture { let pointer_element = match MemoryRenderBufferRenderElement::from_buffer(
pointer_elements.push(OutputRenderElements::NamedPointer( renderer,
PrimaryGpuTextureRenderElement(TextureRenderElement::from_texture_buffer( pointer_pos.to_f64(),
pointer_pos.to_f64(), &texture,
&texture, None,
None, None,
None, None,
None, Kind::Cursor,
Kind::Cursor, ) {
)), Ok(element) => Some(element),
)); Err(err) => {
warn!("error importing a cursor texture: {err:?}");
None
}
};
if let Some(element) = pointer_element {
pointer_elements.push(OutputRenderElements::NamedPointer(element));
} }
(pointer_elements, pointer_pos) (pointer_elements, pointer_pos)
@ -2931,7 +2930,7 @@ fn render_to_dmabuf(
pub enum OutputRenderElements<R: NiriRenderer> { pub enum OutputRenderElements<R: NiriRenderer> {
Monitor(MonitorRenderElement<R>), Monitor(MonitorRenderElement<R>),
Wayland(WaylandSurfaceRenderElement<R>), Wayland(WaylandSurfaceRenderElement<R>),
NamedPointer(PrimaryGpuTextureRenderElement), NamedPointer(MemoryRenderBufferRenderElement<R>),
SolidColor(SolidColorRenderElement), SolidColor(SolidColorRenderElement),
ScreenshotUi(ScreenshotUiRenderElement), ScreenshotUi(ScreenshotUiRenderElement),
ConfigErrorNotification(ConfigErrorNotificationRenderElement<R>), ConfigErrorNotification(ConfigErrorNotificationRenderElement<R>),
@ -3131,12 +3130,6 @@ impl<R: NiriRenderer> From<WaylandSurfaceRenderElement<R>> for OutputRenderEleme
} }
} }
impl<R: NiriRenderer> From<PrimaryGpuTextureRenderElement> for OutputRenderElements<R> {
fn from(x: PrimaryGpuTextureRenderElement) -> Self {
Self::NamedPointer(x)
}
}
impl<R: NiriRenderer> From<SolidColorRenderElement> for OutputRenderElements<R> { impl<R: NiriRenderer> From<SolidColorRenderElement> for OutputRenderElements<R> {
fn from(x: SolidColorRenderElement) -> Self { fn from(x: SolidColorRenderElement) -> Self {
Self::SolidColor(x) Self::SolidColor(x)