diff --git a/src/it/test_gfx_api.rs b/src/it/test_gfx_api.rs index abae7a07..8ef52878 100644 --- a/src/it/test_gfx_api.rs +++ b/src/it/test_gfx_api.rs @@ -1,14 +1,15 @@ use { crate::{ allocator::{Allocator, AllocatorError, BufferObject, BufferUsage}, + clientmem::{ClientMemError, ClientMemOffset}, cpu_worker::CpuWorker, format::{Format, ARGB8888, XRGB8888}, gfx_api::{ - AsyncShmGfxTexture, CopyTexture, FillRect, FramebufferRect, GfxApiOpt, GfxContext, - GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture, GfxWriteModifier, - ResetStatus, ShmGfxTexture, SyncFile, + AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect, FramebufferRect, + GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture, + GfxWriteModifier, PendingShmUpload, ResetStatus, ShmGfxTexture, SyncFile, }, - rect::Rect, + rect::{Rect, Region}, theme::Color, video::{dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx, LINEAR_MODIFIER}, }, @@ -33,6 +34,8 @@ enum TestGfxError { MapDmaBuf(#[source] AllocatorError), #[error("Could not import dmabuf")] ImportDmaBuf(#[source] AllocatorError), + #[error("Could not access the client memory")] + AccessFailed(#[source] ClientMemError), } impl From for GfxError { @@ -136,13 +139,21 @@ impl GfxContext for TestGfxCtx { fn async_shmem_texture( self: Rc, - _format: &'static Format, - _width: i32, - _height: i32, - _stride: i32, + format: &'static Format, + width: i32, + height: i32, + stride: i32, _cpu_worker: &Rc, ) -> Result, GfxError> { - todo!() + assert!(stride >= width * 4); + let size = (stride * height) as usize; + Ok(Rc::new(TestGfxImage::Shm(TestShmGfxImage { + data: RefCell::new(vec![0; size]), + width, + height, + stride, + format, + }))) } fn allocator(&self) -> Rc { @@ -320,6 +331,48 @@ impl ShmGfxTexture for TestGfxImage { } } +impl AsyncShmGfxTexture for TestGfxImage { + fn async_upload( + self: Rc, + _callback: Rc, + mem: &Rc, + damage: Region, + ) -> Result, GfxError> { + mem.access(|d| self.clone().sync_upload(d, damage)) + .map_err(TestGfxError::AccessFailed)??; + Ok(None) + } + + fn sync_upload(self: Rc, mem: &[Cell], _damage: Region) -> Result<(), GfxError> { + let TestGfxImage::Shm(shm) = &*self else { + unreachable!(); + }; + let data = &mut *shm.data.borrow_mut(); + assert!(mem.len() >= data.len()); + unsafe { + ptr::copy_nonoverlapping(mem.as_ptr() as _, data.as_mut_ptr(), data.len()); + } + Ok(()) + } + + fn compatible_with( + &self, + format: &'static Format, + width: i32, + height: i32, + stride: i32, + ) -> bool { + let TestGfxImage::Shm(shm) = &self else { + unreachable!(); + }; + shm.format == format && shm.width == width && shm.height == height && shm.stride == stride + } + + fn into_texture(self: Rc) -> Rc { + self + } +} + impl GfxImage for TestGfxImage { fn to_framebuffer(self: Rc) -> Result, GfxError> { Ok(Rc::new(TestGfxFb {