diff --git a/graphics/virtio-gpud/src/main.rs b/graphics/virtio-gpud/src/main.rs index 9ce2447ba0..880e80b9ab 100644 --- a/graphics/virtio-gpud/src/main.rs +++ b/graphics/virtio-gpud/src/main.rs @@ -392,7 +392,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { device.transport.run_device(); deamon.ready().unwrap(); - let mut scheme = futures::executor::block_on(scheme::GpuScheme::new( + let (mut scheme, mut inputd_handle) = futures::executor::block_on(scheme::GpuScheme::new( config, control_queue.clone(), cursor_queue.clone(), @@ -410,14 +410,14 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { EventQueue::new().expect("virtio-gpud: failed to create event queue"); event_queue .subscribe( - scheme.inputd_handle.inner().as_raw_fd() as usize, + inputd_handle.inner().as_raw_fd() as usize, Source::Input, event::EventFlags::READ, ) .unwrap(); event_queue .subscribe( - scheme.inner.event_handle().raw(), + scheme.event_handle().raw(), Source::Scheme, event::EventFlags::READ, ) @@ -430,17 +430,15 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { { match event { Source::Input => { - while let Some(vt_event) = scheme - .inputd_handle + while let Some(vt_event) = inputd_handle .read_vt_event() .expect("virtio-gpud: failed to read display handle") { - scheme.inner.handle_vt_event(vt_event); + scheme.handle_vt_event(vt_event); } } Source::Scheme => { scheme - .inner .tick() .expect("virtio-gpud: failed to process scheme events"); } diff --git a/graphics/virtio-gpud/src/scheme.rs b/graphics/virtio-gpud/src/scheme.rs index 7a548407d1..82809cad41 100644 --- a/graphics/virtio-gpud/src/scheme.rs +++ b/graphics/virtio-gpud/src/scheme.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use common::{dma::Dma, sgl}; use driver_graphics::{GraphicsAdapter, GraphicsScheme, Resource}; -use inputd::Damage; +use inputd::{Damage, DisplayHandle}; use syscall::PAGE_SIZE; @@ -70,6 +70,21 @@ impl VirtGpuAdapter<'_> { Ok(()) } + + async fn get_display_info(&self) -> Result, Error> { + let header = Dma::new(ControlHeader::with_ty(CommandTy::GetDisplayInfo))?; + + let response = Dma::new(GetDisplayInfo::default())?; + let command = ChainBuilder::new() + .chain(Buffer::new(&header)) + .chain(Buffer::new(&response).flags(DescriptorFlags::WRITE_ONLY)) + .build(); + + self.control_queue.send(command).await; + assert!(response.header.ty == CommandTy::RespOkDisplayInfo); + + Ok(response) + } } impl GraphicsAdapter for VirtGpuAdapter<'_> { @@ -217,46 +232,26 @@ impl GraphicsAdapter for VirtGpuAdapter<'_> { } } -pub struct GpuScheme<'a> { - pub inner: GraphicsScheme>, - pub inputd_handle: inputd::DisplayHandle, -} +pub struct GpuScheme {} -impl<'a> GpuScheme<'a> { +impl<'a> GpuScheme { pub async fn new( config: &'a mut GpuConfig, control_queue: Arc>, cursor_queue: Arc>, transport: Arc, - ) -> Result, Error> { - let displays = Self::probe(control_queue.clone(), config).await?; + ) -> Result<(GraphicsScheme>, DisplayHandle), Error> { + let mut adapter = VirtGpuAdapter { + control_queue, + cursor_queue, + transport, + displays: vec![], + }; - let inputd_handle = inputd::DisplayHandle::new("virtio-gpu").unwrap(); + let mut display_info = adapter.get_display_info().await?; + let raw_displays = &mut display_info.display_info[..config.num_scanouts() as usize]; - Ok(Self { - inner: GraphicsScheme::new( - VirtGpuAdapter { - control_queue, - cursor_queue, - transport, - displays, - }, - "display.virtio-gpu".to_owned(), - ), - inputd_handle, - }) - } - - async fn probe( - control_queue: Arc>, - config: &GpuConfig, - ) -> Result, Error> { - let mut display_info = Self::get_display_info(control_queue.clone()).await?; - let displays = &mut display_info.display_info[..config.num_scanouts() as usize]; - - let mut result = vec![]; - - for info in displays.iter() { + for info in raw_displays.iter() { log::info!( "virtio-gpu: opening display ({}x{}px)", info.rect.width, @@ -267,33 +262,23 @@ impl<'a> GpuScheme<'a> { // QEMU gives all displays other than the first a zero width and height, but trying // to attach a zero sized framebuffer to the display will result an error, so // default to 640x480px. - result.push(Display { + adapter.displays.push(Display { width: 640, height: 480, }); } else { - result.push(Display { + adapter.displays.push(Display { width: info.rect.width, height: info.rect.height, }); } } - Ok(result) - } + let inputd_handle = DisplayHandle::new("virtio-gpu").unwrap(); - async fn get_display_info(control_queue: Arc>) -> Result, Error> { - let header = Dma::new(ControlHeader::with_ty(CommandTy::GetDisplayInfo))?; - - let response = Dma::new(GetDisplayInfo::default())?; - let command = ChainBuilder::new() - .chain(Buffer::new(&header)) - .chain(Buffer::new(&response).flags(DescriptorFlags::WRITE_ONLY)) - .build(); - - control_queue.send(command).await; - assert!(response.header.ty == CommandTy::RespOkDisplayInfo); - - Ok(response) + Ok(( + GraphicsScheme::new(adapter, "display.virtio-gpu".to_owned()), + inputd_handle, + )) } }