it: use single-pixel buffer instead of shm
This commit is contained in:
parent
aaed003ec8
commit
f562f887f0
17 changed files with 280 additions and 76 deletions
|
|
@ -2,7 +2,6 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
cli::screenshot::buf_to_qoi,
|
cli::screenshot::buf_to_qoi,
|
||||||
client::Client,
|
client::Client,
|
||||||
format::ARGB8888,
|
|
||||||
globals::GlobalBase,
|
globals::GlobalBase,
|
||||||
it::{
|
it::{
|
||||||
test_error::{TestError, TestResult},
|
test_error::{TestError, TestResult},
|
||||||
|
|
@ -10,14 +9,15 @@ use {
|
||||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
||||||
test_keyboard::TestKeyboard, test_pointer::TestPointer,
|
test_keyboard::TestKeyboard, test_pointer::TestPointer,
|
||||||
test_registry::TestRegistry, test_seat::TestSeat, test_shm::TestShm,
|
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_transport::TestTransport,
|
||||||
test_utils::test_window::TestWindow,
|
test_utils::test_window::TestWindow,
|
||||||
testrun::TestRun,
|
testrun::TestRun,
|
||||||
},
|
},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
utils::clonecell::CloneCell,
|
|
||||||
},
|
},
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
@ -31,6 +31,8 @@ pub struct TestClient {
|
||||||
pub comp: Rc<TestCompositor>,
|
pub comp: Rc<TestCompositor>,
|
||||||
pub sub: Rc<TestSubcompositor>,
|
pub sub: Rc<TestSubcompositor>,
|
||||||
pub shm: Rc<TestShm>,
|
pub shm: Rc<TestShm>,
|
||||||
|
pub spbm: Rc<TestSinglePixelBufferManager>,
|
||||||
|
pub viewporter: Rc<TestViewporter>,
|
||||||
pub xdg: Rc<TestXdgWmBase>,
|
pub xdg: Rc<TestXdgWmBase>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,19 +116,18 @@ impl TestClient {
|
||||||
|
|
||||||
pub async fn create_window(&self) -> Result<Rc<TestWindow>, TestError> {
|
pub async fn create_window(&self) -> Result<Rc<TestWindow>, TestError> {
|
||||||
let surface = self.comp.create_surface().await?;
|
let surface = self.comp.create_surface().await?;
|
||||||
let shm = self.shm.create_pool(0)?;
|
let viewport = self.viewporter.get_viewport(&surface)?;
|
||||||
let buffer = shm.create_buffer(0, 0, 0, 0, ARGB8888)?;
|
|
||||||
let xdg = self.xdg.create_xdg_surface(surface.id).await?;
|
let xdg = self.xdg.create_xdg_surface(surface.id).await?;
|
||||||
let tl = xdg.create_toplevel().await?;
|
let tl = xdg.create_toplevel().await?;
|
||||||
surface.commit()?;
|
surface.commit()?;
|
||||||
self.sync().await;
|
self.sync().await;
|
||||||
Ok(Rc::new(TestWindow {
|
Ok(Rc::new(TestWindow {
|
||||||
surface,
|
surface,
|
||||||
|
spbm: self.spbm.clone(),
|
||||||
|
viewport,
|
||||||
xdg,
|
xdg,
|
||||||
tl,
|
tl,
|
||||||
shm,
|
color: Cell::new(Color::SOLID_BLACK),
|
||||||
buffer: CloneCell::new(buffer),
|
|
||||||
color: Cell::new(Color::from_rgba_straight(0, 0, 0, 0)),
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod test_buffer;
|
||||||
pub mod test_callback;
|
pub mod test_callback;
|
||||||
pub mod test_compositor;
|
pub mod test_compositor;
|
||||||
pub mod test_display;
|
pub mod test_display;
|
||||||
|
|
@ -11,9 +12,12 @@ pub mod test_seat;
|
||||||
pub mod test_shm;
|
pub mod test_shm;
|
||||||
pub mod test_shm_buffer;
|
pub mod test_shm_buffer;
|
||||||
pub mod test_shm_pool;
|
pub mod test_shm_pool;
|
||||||
|
pub mod test_single_pixel_buffer_manager;
|
||||||
pub mod test_subcompositor;
|
pub mod test_subcompositor;
|
||||||
pub mod test_subsurface;
|
pub mod test_subsurface;
|
||||||
pub mod test_surface;
|
pub mod test_surface;
|
||||||
|
pub mod test_viewport;
|
||||||
|
pub mod test_viewporter;
|
||||||
pub mod test_xdg_base;
|
pub mod test_xdg_base;
|
||||||
pub mod test_xdg_surface;
|
pub mod test_xdg_surface;
|
||||||
pub mod test_xdg_toplevel;
|
pub mod test_xdg_toplevel;
|
||||||
|
|
|
||||||
48
src/it/test_ifs/test_buffer.rs
Normal file
48
src/it/test_ifs/test_buffer.rs
Normal file
|
|
@ -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<TestTransport>,
|
||||||
|
pub released: Cell<bool>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {}
|
||||||
|
|
@ -6,7 +6,8 @@ use {
|
||||||
test_error::TestError,
|
test_error::TestError,
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
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_xdg_base::TestXdgWmBase,
|
||||||
},
|
},
|
||||||
test_object::TestObject,
|
test_object::TestObject,
|
||||||
|
|
@ -31,6 +32,8 @@ pub struct TestRegistrySingletons {
|
||||||
pub wl_subcompositor: u32,
|
pub wl_subcompositor: u32,
|
||||||
pub wl_shm: u32,
|
pub wl_shm: u32,
|
||||||
pub xdg_wm_base: u32,
|
pub xdg_wm_base: u32,
|
||||||
|
pub wp_single_pixel_buffer_manager_v1: u32,
|
||||||
|
pub wp_viewporter: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestRegistry {
|
pub struct TestRegistry {
|
||||||
|
|
@ -42,6 +45,8 @@ pub struct TestRegistry {
|
||||||
pub compositor: CloneCell<Option<Rc<TestCompositor>>>,
|
pub compositor: CloneCell<Option<Rc<TestCompositor>>>,
|
||||||
pub subcompositor: CloneCell<Option<Rc<TestSubcompositor>>>,
|
pub subcompositor: CloneCell<Option<Rc<TestSubcompositor>>>,
|
||||||
pub shm: CloneCell<Option<Rc<TestShm>>>,
|
pub shm: CloneCell<Option<Rc<TestShm>>>,
|
||||||
|
pub spbm: CloneCell<Option<Rc<TestSinglePixelBufferManager>>>,
|
||||||
|
pub viewporter: CloneCell<Option<Rc<TestViewporter>>>,
|
||||||
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
||||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +95,8 @@ impl TestRegistry {
|
||||||
wl_subcompositor,
|
wl_subcompositor,
|
||||||
wl_shm,
|
wl_shm,
|
||||||
xdg_wm_base,
|
xdg_wm_base,
|
||||||
|
wp_single_pixel_buffer_manager_v1,
|
||||||
|
wp_viewporter,
|
||||||
};
|
};
|
||||||
self.singletons.set(Some(singletons.clone()));
|
self.singletons.set(Some(singletons.clone()));
|
||||||
Ok(singletons)
|
Ok(singletons)
|
||||||
|
|
@ -151,6 +158,32 @@ impl TestRegistry {
|
||||||
Ok(jc)
|
Ok(jc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_spbm(&self) -> Result<Rc<TestSinglePixelBufferManager>, 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<Rc<TestViewporter>, 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<Rc<TestXdgWmBase>, TestError> {
|
pub async fn get_xdg(&self) -> Result<Rc<TestXdgWmBase>, TestError> {
|
||||||
singleton!(self.xdg);
|
singleton!(self.xdg);
|
||||||
let singletons = self.get_singletons().await?;
|
let singletons = self.get_singletons().await?;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ impl TestShm {
|
||||||
&self.formats
|
&self.formats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn create_pool(&self, size: usize) -> Result<Rc<TestShmPool>, TestError> {
|
pub fn create_pool(&self, size: usize) -> Result<Rc<TestShmPool>, TestError> {
|
||||||
let mem = TestMem::new(size)?;
|
let mem = TestMem::new(size)?;
|
||||||
let pool = Rc::new(TestShmPool {
|
let pool = Rc::new(TestShmPool {
|
||||||
|
|
@ -48,6 +49,7 @@ impl TestShm {
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn create_buffer(&self, width: i32, height: i32) -> TestResult<Rc<TestShmBuffer>> {
|
pub fn create_buffer(&self, width: i32, height: i32) -> TestResult<Rc<TestShmBuffer>> {
|
||||||
let pool = self.create_pool((width * height * 4) as _)?;
|
let pool = self.create_pool((width * height * 4) as _)?;
|
||||||
pool.create_buffer(0, width, height, width * 4, ARGB8888)
|
pool.create_buffer(0, width, height, width * 4, ARGB8888)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
it::{
|
it::{test_ifs::test_buffer::TestBuffer, test_mem::TestMem},
|
||||||
test_error::TestError, test_mem::TestMem, test_object::TestObject,
|
|
||||||
test_transport::TestTransport, testrun::ParseFull,
|
|
||||||
},
|
|
||||||
theme::Color,
|
theme::Color,
|
||||||
utils::{buffd::MsgParser, windows::WindowsExt},
|
utils::windows::WindowsExt,
|
||||||
wire::{wl_buffer::*, WlBufferId},
|
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
|
|
@ -16,15 +12,13 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TestShmBuffer {
|
pub struct TestShmBuffer {
|
||||||
pub id: WlBufferId,
|
pub buffer: Rc<TestBuffer>,
|
||||||
pub tran: Rc<TestTransport>,
|
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
pub mem: Rc<TestMem>,
|
pub mem: Rc<TestMem>,
|
||||||
pub released: Cell<bool>,
|
|
||||||
pub destroyed: Cell<bool>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestShmBuffer {
|
impl TestShmBuffer {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn fill(&self, color: Color) {
|
pub fn fill(&self, color: Color) {
|
||||||
let [cr, cg, cb, ca] = color.to_rgba_premultiplied();
|
let [cr, cg, cb, ca] = color.to_rgba_premultiplied();
|
||||||
for [b, g, r, a] in self.deref().array_chunks_ext::<4>() {
|
for [b, g, r, a] in self.deref().array_chunks_ext::<4>() {
|
||||||
|
|
@ -34,20 +28,6 @@ impl TestShmBuffer {
|
||||||
a.set(ca);
|
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 {
|
impl Deref for TestShmBuffer {
|
||||||
|
|
@ -57,17 +37,3 @@ impl Deref for TestShmBuffer {
|
||||||
&self.mem[self.range.clone()]
|
&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 {}
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
format::Format,
|
format::Format,
|
||||||
it::{
|
it::{
|
||||||
test_error::TestError, test_ifs::test_shm_buffer::TestShmBuffer, test_mem::TestMem,
|
test_error::TestError,
|
||||||
test_object::TestObject, test_transport::TestTransport,
|
test_ifs::{test_buffer::TestBuffer, test_shm_buffer::TestShmBuffer},
|
||||||
|
test_mem::TestMem,
|
||||||
|
test_object::TestObject,
|
||||||
|
test_transport::TestTransport,
|
||||||
},
|
},
|
||||||
utils::clonecell::CloneCell,
|
utils::clonecell::CloneCell,
|
||||||
wire::{wl_shm_pool::*, WlShmPoolId},
|
wire::{wl_shm_pool::*, WlShmPoolId},
|
||||||
|
|
@ -19,6 +22,7 @@ pub struct TestShmPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestShmPool {
|
impl TestShmPool {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn create_buffer(
|
pub fn create_buffer(
|
||||||
&self,
|
&self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
|
|
@ -35,17 +39,19 @@ impl TestShmPool {
|
||||||
bail!("Out-of-bounds buffer");
|
bail!("Out-of-bounds buffer");
|
||||||
}
|
}
|
||||||
let buffer = Rc::new(TestShmBuffer {
|
let buffer = Rc::new(TestShmBuffer {
|
||||||
id: self.tran.id(),
|
buffer: Rc::new(TestBuffer {
|
||||||
tran: self.tran.clone(),
|
id: self.tran.id(),
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
released: Cell::new(true),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
}),
|
||||||
range: start..end,
|
range: start..end,
|
||||||
mem,
|
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.tran.send(CreateBuffer {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
id: buffer.id,
|
id: buffer.buffer.id,
|
||||||
offset,
|
offset,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
|
@ -55,6 +61,7 @@ impl TestShmPool {
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn resize(&self, size: usize) -> Result<(), TestError> {
|
pub fn resize(&self, size: usize) -> Result<(), TestError> {
|
||||||
let mem = self.mem.get().grow(size)?;
|
let mem = self.mem.get().grow(size)?;
|
||||||
self.mem.set(mem);
|
self.mem.set(mem);
|
||||||
|
|
|
||||||
44
src/it/test_ifs/test_single_pixel_buffer_manager.rs
Normal file
44
src/it/test_ifs/test_single_pixel_buffer_manager.rs
Normal file
|
|
@ -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<TestTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestSinglePixelBufferManager {
|
||||||
|
pub fn create_buffer(&self, color: Color) -> TestResult<Rc<TestBuffer>> {
|
||||||
|
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 {}
|
||||||
52
src/it/test_ifs/test_viewport.rs
Normal file
52
src/it/test_ifs/test_viewport.rs
Normal file
|
|
@ -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<TestTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {}
|
||||||
39
src/it/test_ifs/test_viewporter.rs
Normal file
39
src/it/test_ifs/test_viewporter.rs
Normal file
|
|
@ -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<TestTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestViewporter {
|
||||||
|
pub fn get_viewport(&self, surface: &TestSurface) -> TestResult<Rc<TestViewport>> {
|
||||||
|
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 {}
|
||||||
|
|
@ -13,6 +13,7 @@ pub struct TestMem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestMem {
|
impl TestMem {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn new(size: usize) -> Result<Rc<Self>, TestError> {
|
pub fn new(size: usize) -> Result<Rc<Self>, TestError> {
|
||||||
let fd = uapi::memfd_create("test_pool", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?;
|
let fd = uapi::memfd_create("test_pool", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?;
|
||||||
uapi::fcntl_add_seals(fd.raw(), c::F_SEAL_SHRINK)?;
|
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<Rc<Self>, TestError> {
|
pub fn grow(&self, size: usize) -> Result<Rc<Self>, TestError> {
|
||||||
let cur_len = uapi::fstat(self.fd.raw())?;
|
let cur_len = uapi::fstat(self.fd.raw())?;
|
||||||
if size > cur_len.st_size as _ {
|
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<u8>], TestError> {
|
fn map(fd: c::c_int, size: usize) -> Result<*const [Cell<u8>], TestError> {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return Ok(&[]);
|
return Ok(&[]);
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ impl TestTransport {
|
||||||
compositor: Default::default(),
|
compositor: Default::default(),
|
||||||
subcompositor: Default::default(),
|
subcompositor: Default::default(),
|
||||||
shm: Default::default(),
|
shm: Default::default(),
|
||||||
|
spbm: Default::default(),
|
||||||
|
viewporter: Default::default(),
|
||||||
xdg: Default::default(),
|
xdg: Default::default(),
|
||||||
seats: Default::default(),
|
seats: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,36 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
format::ARGB8888,
|
|
||||||
it::{
|
it::{
|
||||||
test_error::{TestError, TestResult},
|
test_error::{TestError, TestResult},
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_shm_buffer::TestShmBuffer, test_shm_pool::TestShmPool,
|
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||||
test_surface::TestSurface, test_xdg_surface::TestXdgSurface,
|
test_surface::TestSurface, test_viewport::TestViewport,
|
||||||
test_xdg_toplevel::TestXdgToplevel,
|
test_xdg_surface::TestXdgSurface, test_xdg_toplevel::TestXdgToplevel,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
utils::clonecell::CloneCell,
|
|
||||||
},
|
},
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TestWindow {
|
pub struct TestWindow {
|
||||||
pub surface: Rc<TestSurface>,
|
pub surface: Rc<TestSurface>,
|
||||||
|
pub spbm: Rc<TestSinglePixelBufferManager>,
|
||||||
|
pub viewport: Rc<TestViewport>,
|
||||||
pub xdg: Rc<TestXdgSurface>,
|
pub xdg: Rc<TestXdgSurface>,
|
||||||
pub tl: Rc<TestXdgToplevel>,
|
pub tl: Rc<TestXdgToplevel>,
|
||||||
pub shm: Rc<TestShmPool>,
|
|
||||||
pub buffer: CloneCell<Rc<TestShmBuffer>>,
|
|
||||||
pub color: Cell<Color>,
|
pub color: Cell<Color>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestWindow {
|
impl TestWindow {
|
||||||
pub async fn map(&self) -> Result<(), TestError> {
|
pub async fn map(&self) -> Result<(), TestError> {
|
||||||
let width = self.tl.width.get();
|
let buffer = self.spbm.create_buffer(self.color.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());
|
|
||||||
self.surface.attach(buffer.id)?;
|
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.xdg.ack_configure(self.xdg.last_serial.get())?;
|
||||||
self.surface.commit()?;
|
self.surface.commit()?;
|
||||||
self.buffer.set(buffer);
|
|
||||||
self.surface.tran.sync().await;
|
self.surface.tran.sync().await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,8 @@ impl TestRun {
|
||||||
comp: registry.get_compositor().await?,
|
comp: registry.get_compositor().await?,
|
||||||
sub: registry.get_subcompositor().await?,
|
sub: registry.get_subcompositor().await?,
|
||||||
shm: registry.get_shm().await?,
|
shm: registry.get_shm().await?,
|
||||||
|
spbm: registry.get_spbm().await?,
|
||||||
|
viewporter: registry.get_viewporter().await?,
|
||||||
xdg: registry.get_xdg().await?,
|
xdg: registry.get_xdg().await?,
|
||||||
registry,
|
registry,
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
format::ARGB8888,
|
|
||||||
it::{test_error::TestError, testrun::TestRun},
|
it::{test_error::TestError, testrun::TestRun},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
},
|
},
|
||||||
|
|
@ -26,17 +25,20 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
|
||||||
parent.set_color(0, 0, 0, 255);
|
parent.set_color(0, 0, 0, 255);
|
||||||
|
|
||||||
let child = client.comp.create_surface().await?;
|
let child = client.comp.create_surface().await?;
|
||||||
|
let child_viewport = client.viewporter.get_viewport(&child)?;
|
||||||
let sub = client
|
let sub = client
|
||||||
.sub
|
.sub
|
||||||
.get_subsurface(child.id, parent.surface.id)
|
.get_subsurface(child.id, parent.surface.id)
|
||||||
.await?;
|
.await?;
|
||||||
sub.set_position(100, 100)?;
|
sub.set_position(100, 100)?;
|
||||||
|
|
||||||
let pool = client.shm.create_pool(100 * 100 * 4)?;
|
let buffer = client
|
||||||
let buffer = pool.create_buffer(0, 100, 100, 100 * 4, ARGB8888)?;
|
.spbm
|
||||||
buffer.fill(Color::from_rgba_straight(255, 255, 255, 255));
|
.create_buffer(Color::from_rgba_straight(255, 255, 255, 255))?;
|
||||||
|
|
||||||
child.attach(buffer.id)?;
|
child.attach(buffer.id)?;
|
||||||
|
child_viewport.set_source(0, 0, 1, 1)?;
|
||||||
|
child_viewport.set_destination(100, 100)?;
|
||||||
child.commit()?;
|
child.commit()?;
|
||||||
|
|
||||||
parent.map().await?;
|
parent.map().await?;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use {
|
||||||
test_error::{TestErrorExt, TestResult},
|
test_error::{TestErrorExt, TestResult},
|
||||||
testrun::TestRun,
|
testrun::TestRun,
|
||||||
},
|
},
|
||||||
|
theme::Color,
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
@ -25,10 +26,13 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
window.map().await?;
|
window.map().await?;
|
||||||
|
|
||||||
let ns = client.comp.create_surface().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?;
|
let nss = client.sub.get_subsurface(ns.id, window.surface.id).await?;
|
||||||
nss.set_position(100, 100)?;
|
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)?;
|
ns.attach(buffer.id)?;
|
||||||
|
nsv.set_source(0, 0, 1, 1)?;
|
||||||
|
nsv.set_destination(100, 100)?;
|
||||||
ns.commit()?;
|
ns.commit()?;
|
||||||
|
|
||||||
run.cfg.set_fullscreen(ds.seat.id(), true)?;
|
run.cfg.set_fullscreen(ds.seat.id(), true)?;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ fn to_f32(c: u8) -> f32 {
|
||||||
c as f32 / 255f32
|
c as f32 / 255f32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn to_u8(c: f32) -> u8 {
|
fn to_u8(c: f32) -> u8 {
|
||||||
(c * 255f32) as 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] {
|
pub fn to_rgba_premultiplied(self) -> [u8; 4] {
|
||||||
[to_u8(self.r), to_u8(self.g), to_u8(self.b), to_u8(self.a)]
|
[to_u8(self.r), to_u8(self.g), to_u8(self.b), to_u8(self.a)]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue