From 65b98f1ccc2ce1d52c12f75a224a259fd399e555 Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Fri, 22 Nov 2019 17:34:58 -0800 Subject: utilize EventDevices to make virtio-input devices BUG=chromium:1023975 TEST=./build_test Change-Id: I10267e535d4d1dae90b2b5f30db046c388791a16 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1930409 Reviewed-by: Zach Reizner Commit-Queue: Zach Reizner Tested-by: Zach Reizner Tested-by: kokoro --- devices/src/virtio/gpu/backend.rs | 47 +++++++++++++++++++++++++++++++++------ devices/src/virtio/gpu/mod.rs | 27 +++++++++++++++++----- 2 files changed, 61 insertions(+), 13 deletions(-) (limited to 'devices/src/virtio') diff --git a/devices/src/virtio/gpu/backend.rs b/devices/src/virtio/gpu/backend.rs index f13904c..8845612 100644 --- a/devices/src/virtio/gpu/backend.rs +++ b/devices/src/virtio/gpu/backend.rs @@ -11,6 +11,8 @@ use std::os::unix::io::AsRawFd; use std::rc::Rc; use std::usize; +use libc::EINVAL; + use data_model::*; use msg_socket::{MsgReceiver, MsgSender}; @@ -19,7 +21,8 @@ use sys_util::{error, GuestAddress, GuestMemory}; use gpu_display::*; use gpu_renderer::{ - Box3, Context as RendererContext, Renderer, Resource as GpuRendererResource, ResourceCreateArgs, + Box3, Context as RendererContext, Error as GpuRendererError, Renderer, + Resource as GpuRendererResource, ResourceCreateArgs, }; use super::protocol::{ @@ -73,6 +76,7 @@ impl VirtioGpuResource { let (query, dmabuf) = match self.gpu_resource.export() { Ok(export) => (export.0, export.1), + Err(GpuRendererError::Virglrenderer(e)) if e == -EINVAL => return None, Err(e) => { error!("failed to query resource: {}", e); return None; @@ -160,6 +164,8 @@ pub struct Backend { renderer: Renderer, resources: Map, contexts: Map, + // Maps event devices to scanout number. + event_devices: Map, gpu_device_socket: VmMemoryControlRequestSocket, scanout_surface: Option, cursor_surface: Option, @@ -187,9 +193,10 @@ impl Backend { display_width, display_height, renderer, - gpu_device_socket, resources: Default::default(), contexts: Default::default(), + event_devices: Default::default(), + gpu_device_socket, scanout_surface: None, cursor_surface: None, scanout_resource: 0, @@ -203,6 +210,25 @@ impl Backend { &self.display } + pub fn import_event_device(&mut self, event_device: EventDevice, scanout: u32) { + // TODO(zachr): support more than one scanout. + if scanout != 0 { + return; + } + + let mut display = self.display.borrow_mut(); + let event_device_id = match display.import_event_device(event_device) { + Ok(id) => id, + Err(e) => { + error!("error importing event device: {}", e); + return; + } + }; + self.scanout_surface + .map(|s| display.attach_event_device(s, event_device_id)); + self.event_devices.insert(event_device_id, scanout); + } + /// Processes the internal `display` events and returns `true` if the main display was closed. pub fn process_display(&mut self) -> bool { let mut display = self.display.borrow_mut(); @@ -281,9 +307,9 @@ impl Backend { } /// Sets the given resource id as the source of scanout to the display. - pub fn set_scanout(&mut self, id: u32) -> GpuResponse { + pub fn set_scanout(&mut self, _scanout_id: u32, resource_id: u32) -> GpuResponse { let mut display = self.display.borrow_mut(); - if id == 0 { + if resource_id == 0 { if let Some(surface) = self.scanout_surface.take() { display.release_surface(surface); } @@ -293,12 +319,19 @@ impl Backend { } self.cursor_resource = 0; GpuResponse::OkNoData - } else if self.resources.get_mut(&id).is_some() { - self.scanout_resource = id; + } else if self.resources.get_mut(&resource_id).is_some() { + self.scanout_resource = resource_id; if self.scanout_surface.is_none() { match display.create_surface(None, self.display_width, self.display_height) { - Ok(surface) => self.scanout_surface = Some(surface), + Ok(surface) => { + // TODO(zachr): do not assume every event device belongs to this scanout_id; + // in other words, support multiple display outputs. + for &event_device in self.event_devices.keys() { + display.attach_event_device(surface, event_device); + } + self.scanout_surface = Some(surface); + } Err(e) => error!("failed to create display surface: {}", e), } } diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs index 896e2ca..637f22b 100644 --- a/devices/src/virtio/gpu/mod.rs +++ b/devices/src/virtio/gpu/mod.rs @@ -23,6 +23,7 @@ use sys_util::{ debug, error, warn, Error, EventFd, GuestAddress, GuestMemory, PollContext, PollToken, }; +pub use gpu_display::EventDevice; use gpu_display::*; use gpu_renderer::{Renderer, RendererFlags}; @@ -119,7 +120,9 @@ impl Frontend { GpuCommand::ResourceUnref(info) => { self.backend.unref_resource(info.resource_id.to_native()) } - GpuCommand::SetScanout(info) => self.backend.set_scanout(info.resource_id.to_native()), + GpuCommand::SetScanout(info) => self + .backend + .set_scanout(info.scanout_id.to_native(), info.resource_id.to_native()), GpuCommand::ResourceFlush(info) => self.backend.flush_resource( info.resource_id.to_native(), info.r.x.to_native(), @@ -672,6 +675,7 @@ fn build_backend( possible_displays: &[DisplayBackend], display_width: u32, display_height: u32, + event_devices: Vec, gpu_device_socket: VmMemoryControlRequestSocket, pci_bar: Alloc, ) -> Option { @@ -717,22 +721,29 @@ fn build_backend( } }; - Some(Backend::new( + let mut backend = Backend::new( display, display_width, display_height, renderer, gpu_device_socket, pci_bar, - )) + ); + + for event_device in event_devices { + backend.import_event_device(event_device, 0); + } + + Some(backend) } pub struct Gpu { - config_event: bool, exit_evt: EventFd, gpu_device_socket: Option, resource_bridges: Vec, + event_devices: Vec, kill_evt: Option, + config_event: bool, worker_thread: Option>, num_scanouts: NonZeroU8, display_backends: Vec, @@ -749,15 +760,17 @@ impl Gpu { resource_bridges: Vec, display_backends: Vec, gpu_parameters: &GpuParameters, + event_devices: Vec, ) -> Gpu { Gpu { - config_event: false, exit_evt, gpu_device_socket, + num_scanouts, resource_bridges, + event_devices, + config_event: false, kill_evt: None, worker_thread: None, - num_scanouts, display_backends, display_width: gpu_parameters.display_width, display_height: gpu_parameters.display_height, @@ -881,6 +894,7 @@ impl VirtioDevice for Gpu { let display_backends = self.display_backends.clone(); let display_width = self.display_width; let display_height = self.display_height; + let event_devices = self.event_devices.split_off(0); if let (Some(gpu_device_socket), Some(pci_bar)) = (self.gpu_device_socket.take(), self.pci_bar.take()) { @@ -892,6 +906,7 @@ impl VirtioDevice for Gpu { &display_backends, display_width, display_height, + event_devices, gpu_device_socket, pci_bar, ) { -- cgit 1.4.1