diff options
author | Zach Reizner <zachr@google.com> | 2018-08-15 10:46:32 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-11 19:33:56 -0800 |
commit | aa5756669a8331420b84a22e29ddbfc13b791da5 (patch) | |
tree | 3a2767b6ecc2779ca1e9f64ff7c60d8ae3bf8fdf /devices/src/virtio/gpu/mod.rs | |
parent | 42c409c4d7c661ead9794c54811ce5fadf0ae8e7 (diff) | |
download | crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar.gz crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar.bz2 crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar.lz crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar.xz crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.tar.zst crosvm-aa5756669a8331420b84a22e29ddbfc13b791da5.zip |
devices: allow virtio-wayland to use virtgpu resources
This change uses the resource bridge between virtio-gpu and virtio-cpu to send resources over the host wayland connection that originated from the virtio-gpu device. This will help support gpu accelerated wayland surfaces. BUG=chromium:875998 TEST=wayland-simple-egl Change-Id: I3340ecef438779be5cb3643b2de8bb8c33097d75 Reviewed-on: https://chromium-review.googlesource.com/1182793 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Zach Reizner <zachr@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/virtio/gpu/mod.rs')
-rw-r--r-- | devices/src/virtio/gpu/mod.rs | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs index f13c06d..bcab27e 100644 --- a/devices/src/virtio/gpu/mod.rs +++ b/devices/src/virtio/gpu/mod.rs @@ -30,7 +30,8 @@ use self::gpu_display::*; use self::gpu_renderer::{format_fourcc, Renderer}; use super::{ - AvailIter, Queue, VirtioDevice, INTERRUPT_STATUS_USED_RING, TYPE_GPU, VIRTIO_F_VERSION_1, + resource_bridge::*, AvailIter, Queue, VirtioDevice, INTERRUPT_STATUS_USED_RING, TYPE_GPU, + VIRTIO_F_VERSION_1, }; use self::backend::Backend; @@ -89,6 +90,10 @@ impl Frontend { self.backend.process_display() } + fn process_resource_bridge(&self, resource_bridge: &ResourceResponseSocket) { + self.backend.process_resource_bridge(resource_bridge); + } + fn process_gpu_command( &mut self, mem: &GuestMemory, @@ -462,6 +467,7 @@ struct Worker { ctrl_evt: EventFd, cursor_queue: Queue, cursor_evt: EventFd, + resource_bridge: Option<ResourceResponseSocket>, kill_evt: EventFd, state: Frontend, } @@ -479,6 +485,7 @@ impl Worker { CtrlQueue, CursorQueue, Display, + ResourceBridge, InterruptResample, Kill, } @@ -501,6 +508,12 @@ impl Worker { } }; + if let Some(ref resource_bridge) = self.resource_bridge { + if let Err(e) = poll_ctx.add(resource_bridge, Token::ResourceBridge) { + error!("failed to add resource bridge to PollContext: {:?}", e); + } + } + 'poll: loop { // If there are outstanding fences, wake up early to poll them. let duration = if !self.state.fence_descriptors.is_empty() { @@ -517,6 +530,7 @@ impl Worker { } }; let mut signal_used = false; + let mut process_resource_bridge = false; for event in events.iter_readable() { match event.token() { Token::CtrlQueue => { @@ -535,6 +549,7 @@ impl Worker { let _ = self.exit_evt.write(1); } } + Token::ResourceBridge => process_resource_bridge = true, Token::InterruptResample => { let _ = self.interrupt_resample_evt.read(); if self.interrupt_status.load(Ordering::SeqCst) != 0 { @@ -570,6 +585,15 @@ impl Worker { } } + // Process the entire control queue before the resource bridge in case a resource is + // created or destroyed by the control queue. Processing the resource bridge first may + // lead to a race condition. + if process_resource_bridge { + if let Some(ref resource_bridge) = self.resource_bridge { + self.state.process_resource_bridge(resource_bridge); + } + } + if signal_used { self.signal_used_queue(); } @@ -580,15 +604,21 @@ impl Worker { pub struct Gpu { config_event: bool, exit_evt: EventFd, + resource_bridge: Option<ResourceResponseSocket>, kill_evt: Option<EventFd>, wayland_socket_path: PathBuf, } impl Gpu { - pub fn new<P: AsRef<Path>>(exit_evt: EventFd, wayland_socket_path: P) -> Gpu { + pub fn new<P: AsRef<Path>>( + exit_evt: EventFd, + resource_bridge: Option<ResourceResponseSocket>, + wayland_socket_path: P, + ) -> Gpu { Gpu { config_event: false, exit_evt, + resource_bridge, kill_evt: None, wayland_socket_path: wayland_socket_path.as_ref().to_path_buf(), } @@ -695,6 +725,8 @@ impl VirtioDevice for Gpu { }; self.kill_evt = Some(self_kill_evt); + let resource_bridge = self.resource_bridge.take(); + let ctrl_queue = queues.remove(0); let ctrl_evt = queue_evts.remove(0); let cursor_queue = queues.remove(0); @@ -744,6 +776,7 @@ impl VirtioDevice for Gpu { ctrl_evt, cursor_queue, cursor_evt, + resource_bridge, kill_evt, state: Frontend::new(Backend::new(device, display, renderer)), }.run() |