summary refs log tree commit diff
path: root/devices/src
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-11-22 17:34:58 -0800
committerCommit Bot <commit-bot@chromium.org>2019-12-11 00:25:55 +0000
commit65b98f1ccc2ce1d52c12f75a224a259fd399e555 (patch)
tree0e73ceacdb9385cb44521a94303230aec3d8f36a /devices/src
parent2767223fdbcf189ccebbffbec8b3a0f254d9d40e (diff)
downloadcrosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.gz
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.bz2
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.lz
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.xz
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.tar.zst
crosvm-65b98f1ccc2ce1d52c12f75a224a259fd399e555.zip
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 <zachr@chromium.org>
Commit-Queue: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'devices/src')
-rw-r--r--devices/src/virtio/gpu/backend.rs47
-rw-r--r--devices/src/virtio/gpu/mod.rs27
2 files changed, 61 insertions, 13 deletions
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<u32, VirtioGpuResource>,
     contexts: Map<u32, RendererContext>,
+    // Maps event devices to scanout number.
+    event_devices: Map<u32, u32>,
     gpu_device_socket: VmMemoryControlRequestSocket,
     scanout_surface: Option<u32>,
     cursor_surface: Option<u32>,
@@ -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<EventDevice>,
     gpu_device_socket: VmMemoryControlRequestSocket,
     pci_bar: Alloc,
 ) -> Option<Backend> {
@@ -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<VmMemoryControlRequestSocket>,
     resource_bridges: Vec<ResourceResponseSocket>,
+    event_devices: Vec<EventDevice>,
     kill_evt: Option<EventFd>,
+    config_event: bool,
     worker_thread: Option<thread::JoinHandle<()>>,
     num_scanouts: NonZeroU8,
     display_backends: Vec<DisplayBackend>,
@@ -749,15 +760,17 @@ impl Gpu {
         resource_bridges: Vec<ResourceResponseSocket>,
         display_backends: Vec<DisplayBackend>,
         gpu_parameters: &GpuParameters,
+        event_devices: Vec<EventDevice>,
     ) -> 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,
                         ) {