From f562f887f0254d584709e1074f581195dbacceb4 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 2 Apr 2024 10:23:55 +0200 Subject: [PATCH] it: use single-pixel buffer instead of shm --- src/it/test_client.rs | 17 +++--- src/it/test_ifs.rs | 4 ++ src/it/test_ifs/test_buffer.rs | 48 +++++++++++++++++ src/it/test_ifs/test_registry.rs | 35 ++++++++++++- src/it/test_ifs/test_shm.rs | 2 + src/it/test_ifs/test_shm_buffer.rs | 42 ++------------- src/it/test_ifs/test_shm_pool.rs | 23 +++++--- .../test_single_pixel_buffer_manager.rs | 44 ++++++++++++++++ src/it/test_ifs/test_viewport.rs | 52 +++++++++++++++++++ src/it/test_ifs/test_viewporter.rs | 39 ++++++++++++++ src/it/test_mem.rs | 3 ++ src/it/test_transport.rs | 2 + src/it/test_utils/test_window.rs | 24 ++++----- src/it/testrun.rs | 2 + src/it/tests/t0007_subsurface.rs | 10 ++-- src/it/tests/t0012_subsurface_focus.rs | 6 ++- src/theme.rs | 3 +- 17 files changed, 280 insertions(+), 76 deletions(-) create mode 100644 src/it/test_ifs/test_buffer.rs create mode 100644 src/it/test_ifs/test_single_pixel_buffer_manager.rs create mode 100644 src/it/test_ifs/test_viewport.rs create mode 100644 src/it/test_ifs/test_viewporter.rs diff --git a/src/it/test_client.rs b/src/it/test_client.rs index e6eb7ced..31580baf 100644 --- a/src/it/test_client.rs +++ b/src/it/test_client.rs @@ -2,7 +2,6 @@ use { crate::{ cli::screenshot::buf_to_qoi, client::Client, - format::ARGB8888, globals::GlobalBase, it::{ test_error::{TestError, TestResult}, @@ -10,14 +9,15 @@ use { test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor, test_keyboard::TestKeyboard, test_pointer::TestPointer, test_registry::TestRegistry, test_seat::TestSeat, test_shm::TestShm, - test_subcompositor::TestSubcompositor, test_xdg_base::TestXdgWmBase, + test_single_pixel_buffer_manager::TestSinglePixelBufferManager, + test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter, + test_xdg_base::TestXdgWmBase, }, test_transport::TestTransport, test_utils::test_window::TestWindow, testrun::TestRun, }, theme::Color, - utils::clonecell::CloneCell, }, std::{cell::Cell, rc::Rc}, }; @@ -31,6 +31,8 @@ pub struct TestClient { pub comp: Rc, pub sub: Rc, pub shm: Rc, + pub spbm: Rc, + pub viewporter: Rc, pub xdg: Rc, } @@ -114,19 +116,18 @@ impl TestClient { pub async fn create_window(&self) -> Result, TestError> { let surface = self.comp.create_surface().await?; - let shm = self.shm.create_pool(0)?; - let buffer = shm.create_buffer(0, 0, 0, 0, ARGB8888)?; + let viewport = self.viewporter.get_viewport(&surface)?; let xdg = self.xdg.create_xdg_surface(surface.id).await?; let tl = xdg.create_toplevel().await?; surface.commit()?; self.sync().await; Ok(Rc::new(TestWindow { surface, + spbm: self.spbm.clone(), + viewport, xdg, tl, - shm, - buffer: CloneCell::new(buffer), - color: Cell::new(Color::from_rgba_straight(0, 0, 0, 0)), + color: Cell::new(Color::SOLID_BLACK), })) } } diff --git a/src/it/test_ifs.rs b/src/it/test_ifs.rs index 58ca7d15..b8440987 100644 --- a/src/it/test_ifs.rs +++ b/src/it/test_ifs.rs @@ -1,3 +1,4 @@ +mod test_buffer; pub mod test_callback; pub mod test_compositor; pub mod test_display; @@ -11,9 +12,12 @@ pub mod test_seat; pub mod test_shm; pub mod test_shm_buffer; pub mod test_shm_pool; +pub mod test_single_pixel_buffer_manager; pub mod test_subcompositor; pub mod test_subsurface; pub mod test_surface; +pub mod test_viewport; +pub mod test_viewporter; pub mod test_xdg_base; pub mod test_xdg_surface; pub mod test_xdg_toplevel; diff --git a/src/it/test_ifs/test_buffer.rs b/src/it/test_ifs/test_buffer.rs new file mode 100644 index 00000000..8ed6fa6b --- /dev/null +++ b/src/it/test_ifs/test_buffer.rs @@ -0,0 +1,48 @@ +use { + crate::{ + it::{ + test_error::TestError, test_object::TestObject, test_transport::TestTransport, + testrun::ParseFull, + }, + utils::buffd::MsgParser, + wire::{wl_buffer::*, WlBufferId}, + }, + std::{cell::Cell, rc::Rc}, +}; + +pub struct TestBuffer { + pub id: WlBufferId, + pub tran: Rc, + pub released: Cell, + pub destroyed: Cell, +} + +impl TestBuffer { + pub fn destroy(&self) -> Result<(), TestError> { + if self.destroyed.replace(true) { + return Ok(()); + } + self.tran.send(Destroy { self_id: self.id })?; + Ok(()) + } + + fn handle_release(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> { + let _ev = Release::parse_full(parser)?; + self.released.set(true); + Ok(()) + } +} + +impl Drop for TestBuffer { + fn drop(&mut self) { + let _ = self.destroy(); + } +} + +test_object! { + TestBuffer, WlBuffer; + + RELEASE => handle_release, +} + +impl TestObject for TestBuffer {} diff --git a/src/it/test_ifs/test_registry.rs b/src/it/test_ifs/test_registry.rs index 824d8dee..3154dee6 100644 --- a/src/it/test_ifs/test_registry.rs +++ b/src/it/test_ifs/test_registry.rs @@ -6,7 +6,8 @@ use { test_error::TestError, test_ifs::{ test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor, - test_shm::TestShm, test_subcompositor::TestSubcompositor, + test_shm::TestShm, test_single_pixel_buffer_manager::TestSinglePixelBufferManager, + test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter, test_xdg_base::TestXdgWmBase, }, test_object::TestObject, @@ -31,6 +32,8 @@ pub struct TestRegistrySingletons { pub wl_subcompositor: u32, pub wl_shm: u32, pub xdg_wm_base: u32, + pub wp_single_pixel_buffer_manager_v1: u32, + pub wp_viewporter: u32, } pub struct TestRegistry { @@ -42,6 +45,8 @@ pub struct TestRegistry { pub compositor: CloneCell>>, pub subcompositor: CloneCell>>, pub shm: CloneCell>>, + pub spbm: CloneCell>>, + pub viewporter: CloneCell>>, pub xdg: CloneCell>>, pub seats: CopyHashMap>, } @@ -90,6 +95,8 @@ impl TestRegistry { wl_subcompositor, wl_shm, xdg_wm_base, + wp_single_pixel_buffer_manager_v1, + wp_viewporter, }; self.singletons.set(Some(singletons.clone())); Ok(singletons) @@ -151,6 +158,32 @@ impl TestRegistry { Ok(jc) } + pub async fn get_spbm(&self) -> Result, TestError> { + singleton!(self.spbm); + let singletons = self.get_singletons().await?; + singleton!(self.spbm); + let jc = Rc::new(TestSinglePixelBufferManager { + id: self.tran.id(), + tran: self.tran.clone(), + }); + self.bind(&jc, singletons.wp_single_pixel_buffer_manager_v1, 1)?; + self.spbm.set(Some(jc.clone())); + Ok(jc) + } + + pub async fn get_viewporter(&self) -> Result, TestError> { + singleton!(self.viewporter); + let singletons = self.get_singletons().await?; + singleton!(self.viewporter); + let jc = Rc::new(TestViewporter { + id: self.tran.id(), + tran: self.tran.clone(), + }); + self.bind(&jc, singletons.wp_viewporter, 1)?; + self.viewporter.set(Some(jc.clone())); + Ok(jc) + } + pub async fn get_xdg(&self) -> Result, TestError> { singleton!(self.xdg); let singletons = self.get_singletons().await?; diff --git a/src/it/test_ifs/test_shm.rs b/src/it/test_ifs/test_shm.rs index d58d3a7e..b78eb862 100644 --- a/src/it/test_ifs/test_shm.rs +++ b/src/it/test_ifs/test_shm.rs @@ -30,6 +30,7 @@ impl TestShm { &self.formats } + #[allow(dead_code)] pub fn create_pool(&self, size: usize) -> Result, TestError> { let mem = TestMem::new(size)?; let pool = Rc::new(TestShmPool { @@ -48,6 +49,7 @@ impl TestShm { Ok(pool) } + #[allow(dead_code)] pub fn create_buffer(&self, width: i32, height: i32) -> TestResult> { let pool = self.create_pool((width * height * 4) as _)?; pool.create_buffer(0, width, height, width * 4, ARGB8888) diff --git a/src/it/test_ifs/test_shm_buffer.rs b/src/it/test_ifs/test_shm_buffer.rs index 0c291faf..93cb7c3f 100644 --- a/src/it/test_ifs/test_shm_buffer.rs +++ b/src/it/test_ifs/test_shm_buffer.rs @@ -1,12 +1,8 @@ use { crate::{ - it::{ - test_error::TestError, test_mem::TestMem, test_object::TestObject, - test_transport::TestTransport, testrun::ParseFull, - }, + it::{test_ifs::test_buffer::TestBuffer, test_mem::TestMem}, theme::Color, - utils::{buffd::MsgParser, windows::WindowsExt}, - wire::{wl_buffer::*, WlBufferId}, + utils::windows::WindowsExt, }, std::{ cell::Cell, @@ -16,15 +12,13 @@ use { }; pub struct TestShmBuffer { - pub id: WlBufferId, - pub tran: Rc, + pub buffer: Rc, pub range: Range, pub mem: Rc, - pub released: Cell, - pub destroyed: Cell, } impl TestShmBuffer { + #[allow(dead_code)] pub fn fill(&self, color: Color) { let [cr, cg, cb, ca] = color.to_rgba_premultiplied(); for [b, g, r, a] in self.deref().array_chunks_ext::<4>() { @@ -34,20 +28,6 @@ impl TestShmBuffer { a.set(ca); } } - - pub fn destroy(&self) -> Result<(), TestError> { - if self.destroyed.replace(true) { - return Ok(()); - } - self.tran.send(Destroy { self_id: self.id })?; - Ok(()) - } - - fn handle_release(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> { - let _ev = Release::parse_full(parser)?; - self.released.set(true); - Ok(()) - } } impl Deref for TestShmBuffer { @@ -57,17 +37,3 @@ impl Deref for TestShmBuffer { &self.mem[self.range.clone()] } } - -impl Drop for TestShmBuffer { - fn drop(&mut self) { - let _ = self.destroy(); - } -} - -test_object! { - TestShmBuffer, WlBuffer; - - RELEASE => handle_release, -} - -impl TestObject for TestShmBuffer {} diff --git a/src/it/test_ifs/test_shm_pool.rs b/src/it/test_ifs/test_shm_pool.rs index 8d4053f1..639a6b4d 100644 --- a/src/it/test_ifs/test_shm_pool.rs +++ b/src/it/test_ifs/test_shm_pool.rs @@ -2,8 +2,11 @@ use { crate::{ format::Format, it::{ - test_error::TestError, test_ifs::test_shm_buffer::TestShmBuffer, test_mem::TestMem, - test_object::TestObject, test_transport::TestTransport, + test_error::TestError, + test_ifs::{test_buffer::TestBuffer, test_shm_buffer::TestShmBuffer}, + test_mem::TestMem, + test_object::TestObject, + test_transport::TestTransport, }, utils::clonecell::CloneCell, wire::{wl_shm_pool::*, WlShmPoolId}, @@ -19,6 +22,7 @@ pub struct TestShmPool { } impl TestShmPool { + #[allow(dead_code)] pub fn create_buffer( &self, offset: i32, @@ -35,17 +39,19 @@ impl TestShmPool { bail!("Out-of-bounds buffer"); } let buffer = Rc::new(TestShmBuffer { - id: self.tran.id(), - tran: self.tran.clone(), + buffer: Rc::new(TestBuffer { + id: self.tran.id(), + tran: self.tran.clone(), + released: Cell::new(true), + destroyed: Cell::new(false), + }), range: start..end, mem, - released: Cell::new(true), - destroyed: Cell::new(false), }); - self.tran.add_obj(buffer.clone())?; + self.tran.add_obj(buffer.buffer.clone())?; self.tran.send(CreateBuffer { self_id: self.id, - id: buffer.id, + id: buffer.buffer.id, offset, width, height, @@ -55,6 +61,7 @@ impl TestShmPool { Ok(buffer) } + #[allow(dead_code)] pub fn resize(&self, size: usize) -> Result<(), TestError> { let mem = self.mem.get().grow(size)?; self.mem.set(mem); diff --git a/src/it/test_ifs/test_single_pixel_buffer_manager.rs b/src/it/test_ifs/test_single_pixel_buffer_manager.rs new file mode 100644 index 00000000..a5652419 --- /dev/null +++ b/src/it/test_ifs/test_single_pixel_buffer_manager.rs @@ -0,0 +1,44 @@ +use { + crate::{ + it::{ + test_error::TestResult, test_ifs::test_buffer::TestBuffer, test_object::TestObject, + test_transport::TestTransport, + }, + theme::Color, + wire::{wp_single_pixel_buffer_manager_v1::*, WpSinglePixelBufferManagerV1Id}, + }, + std::{cell::Cell, rc::Rc}, +}; + +pub struct TestSinglePixelBufferManager { + pub id: WpSinglePixelBufferManagerV1Id, + pub tran: Rc, +} + +impl TestSinglePixelBufferManager { + pub fn create_buffer(&self, color: Color) -> TestResult> { + let obj = Rc::new(TestBuffer { + id: self.tran.id(), + tran: self.tran.clone(), + released: Cell::new(true), + destroyed: Cell::new(false), + }); + let map = |c: f32| (c as f64 * u32::MAX as f64) as u32; + self.tran.send(CreateU32RgbaBuffer { + self_id: self.id, + id: obj.id, + r: map(color.r), + g: map(color.g), + b: map(color.b), + a: map(color.a), + })?; + self.tran.add_obj(obj.clone())?; + Ok(obj) + } +} + +test_object! { + TestSinglePixelBufferManager, WpSinglePixelBufferManagerV1; +} + +impl TestObject for TestSinglePixelBufferManager {} diff --git a/src/it/test_ifs/test_viewport.rs b/src/it/test_ifs/test_viewport.rs new file mode 100644 index 00000000..a22df787 --- /dev/null +++ b/src/it/test_ifs/test_viewport.rs @@ -0,0 +1,52 @@ +use { + crate::{ + fixed::Fixed, + it::{test_error::TestError, test_object::TestObject, test_transport::TestTransport}, + wire::{wp_viewport::*, WpViewportId}, + }, + std::rc::Rc, +}; + +pub struct TestViewport { + pub id: WpViewportId, + pub tran: Rc, +} + +impl TestViewport { + pub fn destroy(&self) -> Result<(), TestError> { + self.tran.send(Destroy { self_id: self.id })?; + Ok(()) + } + + pub fn set_source(&self, x: i32, y: i32, width: i32, height: i32) -> Result<(), TestError> { + self.tran.send(SetSource { + self_id: self.id, + x: Fixed::from_int(x), + y: Fixed::from_int(y), + width: Fixed::from_int(width), + height: Fixed::from_int(height), + })?; + Ok(()) + } + + pub fn set_destination(&self, width: i32, height: i32) -> Result<(), TestError> { + self.tran.send(SetDestination { + self_id: self.id, + width: width.max(1), + height: height.max(1), + })?; + Ok(()) + } +} + +impl Drop for TestViewport { + fn drop(&mut self) { + let _ = self.destroy(); + } +} + +test_object! { + TestViewport, WpViewport; +} + +impl TestObject for TestViewport {} diff --git a/src/it/test_ifs/test_viewporter.rs b/src/it/test_ifs/test_viewporter.rs new file mode 100644 index 00000000..d3023b9e --- /dev/null +++ b/src/it/test_ifs/test_viewporter.rs @@ -0,0 +1,39 @@ +use { + crate::{ + it::{ + test_error::TestResult, + test_ifs::{test_surface::TestSurface, test_viewport::TestViewport}, + test_object::TestObject, + test_transport::TestTransport, + }, + wire::{wp_viewporter::*, WpViewporterId}, + }, + std::rc::Rc, +}; + +pub struct TestViewporter { + pub id: WpViewporterId, + pub tran: Rc, +} + +impl TestViewporter { + pub fn get_viewport(&self, surface: &TestSurface) -> TestResult> { + let obj = Rc::new(TestViewport { + id: self.tran.id(), + tran: self.tran.clone(), + }); + self.tran.send(GetViewport { + self_id: self.id, + id: obj.id, + surface: surface.id, + })?; + self.tran.add_obj(obj.clone())?; + Ok(obj) + } +} + +test_object! { + TestViewporter, WpViewporter; +} + +impl TestObject for TestViewporter {} diff --git a/src/it/test_mem.rs b/src/it/test_mem.rs index 236808b3..fbdd9256 100644 --- a/src/it/test_mem.rs +++ b/src/it/test_mem.rs @@ -13,6 +13,7 @@ pub struct TestMem { } impl TestMem { + #[allow(dead_code)] pub fn new(size: usize) -> Result, TestError> { let fd = uapi::memfd_create("test_pool", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?; uapi::fcntl_add_seals(fd.raw(), c::F_SEAL_SHRINK)?; @@ -24,6 +25,7 @@ impl TestMem { })) } + #[allow(dead_code)] pub fn grow(&self, size: usize) -> Result, TestError> { let cur_len = uapi::fstat(self.fd.raw())?; if size > cur_len.st_size as _ { @@ -45,6 +47,7 @@ impl Deref for TestMem { } } +#[allow(dead_code)] fn map(fd: c::c_int, size: usize) -> Result<*const [Cell], TestError> { if size == 0 { return Ok(&[]); diff --git a/src/it/test_transport.rs b/src/it/test_transport.rs index f9744ae1..d7708da2 100644 --- a/src/it/test_transport.rs +++ b/src/it/test_transport.rs @@ -56,6 +56,8 @@ impl TestTransport { compositor: Default::default(), subcompositor: Default::default(), shm: Default::default(), + spbm: Default::default(), + viewporter: Default::default(), xdg: Default::default(), seats: Default::default(), }); diff --git a/src/it/test_utils/test_window.rs b/src/it/test_utils/test_window.rs index 3f78d3df..20abd167 100644 --- a/src/it/test_utils/test_window.rs +++ b/src/it/test_utils/test_window.rs @@ -1,42 +1,36 @@ use { crate::{ - format::ARGB8888, it::{ test_error::{TestError, TestResult}, test_ifs::{ - test_shm_buffer::TestShmBuffer, test_shm_pool::TestShmPool, - test_surface::TestSurface, test_xdg_surface::TestXdgSurface, - test_xdg_toplevel::TestXdgToplevel, + test_single_pixel_buffer_manager::TestSinglePixelBufferManager, + test_surface::TestSurface, test_viewport::TestViewport, + test_xdg_surface::TestXdgSurface, test_xdg_toplevel::TestXdgToplevel, }, }, theme::Color, - utils::clonecell::CloneCell, }, std::{cell::Cell, rc::Rc}, }; pub struct TestWindow { pub surface: Rc, + pub spbm: Rc, + pub viewport: Rc, pub xdg: Rc, pub tl: Rc, - pub shm: Rc, - pub buffer: CloneCell>, pub color: Cell, } impl TestWindow { pub async fn map(&self) -> Result<(), TestError> { - let width = self.tl.width.get(); - let height = self.tl.height.get(); - let stride = width * 4; - let size = (stride * height) as usize; - self.shm.resize(size)?; - let buffer = self.shm.create_buffer(0, width, height, stride, ARGB8888)?; - buffer.fill(self.color.get()); + let buffer = self.spbm.create_buffer(self.color.get())?; self.surface.attach(buffer.id)?; + self.viewport.set_source(0, 0, 1, 1)?; + self.viewport + .set_destination(self.tl.width.get(), self.tl.height.get())?; self.xdg.ack_configure(self.xdg.last_serial.get())?; self.surface.commit()?; - self.buffer.set(buffer); self.surface.tran.sync().await; Ok(()) } diff --git a/src/it/testrun.rs b/src/it/testrun.rs index 97718e41..81b88db0 100644 --- a/src/it/testrun.rs +++ b/src/it/testrun.rs @@ -83,6 +83,8 @@ impl TestRun { comp: registry.get_compositor().await?, sub: registry.get_subcompositor().await?, shm: registry.get_shm().await?, + spbm: registry.get_spbm().await?, + viewporter: registry.get_viewporter().await?, xdg: registry.get_xdg().await?, registry, })) diff --git a/src/it/tests/t0007_subsurface.rs b/src/it/tests/t0007_subsurface.rs index 93b1a245..34fec5a8 100644 --- a/src/it/tests/t0007_subsurface.rs +++ b/src/it/tests/t0007_subsurface.rs @@ -1,6 +1,5 @@ use { crate::{ - format::ARGB8888, it::{test_error::TestError, testrun::TestRun}, theme::Color, }, @@ -26,17 +25,20 @@ async fn test(run: Rc) -> Result<(), TestError> { parent.set_color(0, 0, 0, 255); let child = client.comp.create_surface().await?; + let child_viewport = client.viewporter.get_viewport(&child)?; let sub = client .sub .get_subsurface(child.id, parent.surface.id) .await?; sub.set_position(100, 100)?; - let pool = client.shm.create_pool(100 * 100 * 4)?; - let buffer = pool.create_buffer(0, 100, 100, 100 * 4, ARGB8888)?; - buffer.fill(Color::from_rgba_straight(255, 255, 255, 255)); + let buffer = client + .spbm + .create_buffer(Color::from_rgba_straight(255, 255, 255, 255))?; child.attach(buffer.id)?; + child_viewport.set_source(0, 0, 1, 1)?; + child_viewport.set_destination(100, 100)?; child.commit()?; parent.map().await?; diff --git a/src/it/tests/t0012_subsurface_focus.rs b/src/it/tests/t0012_subsurface_focus.rs index 4d978603..7fc2ccab 100644 --- a/src/it/tests/t0012_subsurface_focus.rs +++ b/src/it/tests/t0012_subsurface_focus.rs @@ -5,6 +5,7 @@ use { test_error::{TestErrorExt, TestResult}, testrun::TestRun, }, + theme::Color, }, std::rc::Rc, }; @@ -25,10 +26,13 @@ async fn test(run: Rc) -> TestResult { window.map().await?; let ns = client.comp.create_surface().await?; + let nsv = client.viewporter.get_viewport(&ns)?; let nss = client.sub.get_subsurface(ns.id, window.surface.id).await?; nss.set_position(100, 100)?; - let buffer = client.shm.create_buffer(100, 100)?; + let buffer = client.spbm.create_buffer(Color::SOLID_BLACK)?; ns.attach(buffer.id)?; + nsv.set_source(0, 0, 1, 1)?; + nsv.set_destination(100, 100)?; ns.commit()?; run.cfg.set_fullscreen(ds.seat.id(), true)?; diff --git a/src/theme.rs b/src/theme.rs index 35380133..98fd5db1 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -33,6 +33,7 @@ fn to_f32(c: u8) -> f32 { c as f32 / 255f32 } +#[allow(dead_code)] fn to_u8(c: f32) -> u8 { (c * 255f32) as u8 } @@ -87,7 +88,7 @@ impl Color { } } - #[cfg_attr(not(feature = "it"), allow(dead_code))] + #[allow(dead_code)] pub fn to_rgba_premultiplied(self) -> [u8; 4] { [to_u8(self.r), to_u8(self.g), to_u8(self.b), to_u8(self.a)] }