From 88cfa76e2c7ffddbbe7d8173893a3529ff065570 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 6 Mar 2025 18:53:56 +0100 Subject: [PATCH] graphics: Merge set_scanout and flush_resource into update_plane The old api was pretty virtio-gpu specific. The new api is closed to how atomic mode setting on Linux works. --- graphics/driver-graphics/src/lib.rs | 9 ++++---- graphics/vesad/src/scheme.rs | 6 +---- graphics/virtio-gpud/src/main.rs | 2 +- graphics/virtio-gpud/src/scheme.rs | 35 +++++++++++++++-------------- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/graphics/driver-graphics/src/lib.rs b/graphics/driver-graphics/src/lib.rs index c35b88bcd8..3a9b503f54 100644 --- a/graphics/driver-graphics/src/lib.rs +++ b/graphics/driver-graphics/src/lib.rs @@ -17,8 +17,7 @@ pub trait GraphicsAdapter { fn create_resource(&mut self, width: u32, height: u32) -> Self::Resource; fn map_resource(&mut self, resource: &Self::Resource) -> *mut u8; - fn set_scanout(&mut self, display_id: usize, resource: &Self::Resource); - fn flush_resource( + fn update_plane( &mut self, display_id: usize, resource: &Self::Resource, @@ -90,7 +89,7 @@ impl GraphicsScheme { let (width, height) = self.adapter.display_size(display_id); self.adapter.create_resource(width, height) }); - self.adapter.set_scanout(display_id, resource); + self.adapter.update_plane(display_id, resource, None); self.active_vt = vt_event.vt; } @@ -196,7 +195,7 @@ impl Scheme for GraphicsScheme { return Ok(0); } let resource = &self.vts_res[vt][screen]; - self.adapter.flush_resource(*screen, resource, None); + self.adapter.update_plane(*screen, resource, None); Ok(0) } @@ -229,7 +228,7 @@ impl Scheme for GraphicsScheme { ) }; - self.adapter.flush_resource(*screen, resource, Some(damage)); + self.adapter.update_plane(*screen, resource, Some(damage)); Ok(buf.len()) } diff --git a/graphics/vesad/src/scheme.rs b/graphics/vesad/src/scheme.rs index 48c3b0940a..47fde67e88 100644 --- a/graphics/vesad/src/scheme.rs +++ b/graphics/vesad/src/scheme.rs @@ -34,11 +34,7 @@ impl GraphicsAdapter for FbAdapter { resource.ptr.as_ptr().cast::() } - fn set_scanout(&mut self, display_id: usize, resource: &Self::Resource) { - self.flush_resource(display_id, resource, None); - } - - fn flush_resource( + fn update_plane( &mut self, display_id: usize, resource: &Self::Resource, diff --git a/graphics/virtio-gpud/src/main.rs b/graphics/virtio-gpud/src/main.rs index 6b0b62f3fe..2313808470 100644 --- a/graphics/virtio-gpud/src/main.rs +++ b/graphics/virtio-gpud/src/main.rs @@ -192,7 +192,7 @@ impl Default for GetDisplayInfo { static RESOURCE_ALLOC: AtomicU32 = AtomicU32::new(1); // XXX: 0 is reserved for whatever that takes `resource_id`. -#[derive(Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] #[repr(C)] pub struct ResourceId(u32); diff --git a/graphics/virtio-gpud/src/scheme.rs b/graphics/virtio-gpud/src/scheme.rs index d80f45bbb6..bc0c1c4f98 100644 --- a/graphics/virtio-gpud/src/scheme.rs +++ b/graphics/virtio-gpud/src/scheme.rs @@ -44,6 +44,7 @@ impl Resource for VirtGpuResource { pub struct Display { width: u32, height: u32, + active_resource: Option, } pub struct VirtGpuAdapter<'a> { @@ -164,24 +165,9 @@ impl GraphicsAdapter for VirtGpuAdapter<'_> { resource.sgl.as_ptr() } - fn set_scanout(&mut self, display_id: usize, resource: &Self::Resource) { - futures::executor::block_on(async { - let scanout_request = Dma::new(SetScanout::new( - display_id as u32, - resource.id, - GpuRect::new(0, 0, resource.width, resource.height), - )) - .unwrap(); - let header = self.send_request(scanout_request).await.unwrap(); - assert_eq!(header.ty, CommandTy::RespOkNodata); - }); - - self.flush_resource(display_id, resource, None); - } - - fn flush_resource( + fn update_plane( &mut self, - _display_id: usize, + display_id: usize, resource: &Self::Resource, damage: Option<&[Damage]>, ) { @@ -200,6 +186,19 @@ impl GraphicsAdapter for VirtGpuAdapter<'_> { let header = self.send_request(req).await.unwrap(); assert_eq!(header.ty, CommandTy::RespOkNodata); + // FIXME once we support resizing we also need to check that the current and target size match + if self.displays[display_id].active_resource != Some(resource.id) { + let scanout_request = Dma::new(SetScanout::new( + display_id as u32, + resource.id, + GpuRect::new(0, 0, resource.width, resource.height), + )) + .unwrap(); + let header = self.send_request(scanout_request).await.unwrap(); + assert_eq!(header.ty, CommandTy::RespOkNodata); + self.displays[display_id].active_resource = Some(resource.id); + } + if let Some(damage) = damage { for damage in damage { self.flush_resource_inner(ResourceFlush::new( @@ -261,11 +260,13 @@ impl<'a> GpuScheme { adapter.displays.push(Display { width: 640, height: 480, + active_resource: None, }); } else { adapter.displays.push(Display { width: info.rect.width, height: info.rect.height, + active_resource: None, }); } }