gpu: refactor gpu device creation

Reduce the number of parameters passed down multiple levels of the call
stack.

BUG=None
Test=cargo build --features=gpu,x,wl-dmabuf,virgl_renderer,virgl_renderer_next,gfxstream

Change-Id: Iac4436e391b2d246b5ab7aecf04fd48d523fac78
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4563456
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Ryan Neph <ryanneph@google.com>
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index 3b2936f..a307c74 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -1078,10 +1078,8 @@
         gpu_parameters: &GpuParameters,
         rutabaga_server_descriptor: Option<SafeDescriptor>,
         event_devices: Vec<EventDevice>,
-        external_blob: bool,
-        system_blob: bool,
         base_features: u64,
-        channels: BTreeMap<String, PathBuf>,
+        channels: &BTreeMap<String, PathBuf>,
         #[cfg(windows)] wndproc_thread: WindowProcedureThread,
         #[cfg(unix)] gpu_cgroup_path: Option<&PathBuf>,
     ) -> Gpu {
@@ -1092,7 +1090,7 @@
         let (display_width, display_height) = display_params[0].get_virtual_display_size();
 
         let mut rutabaga_channels: Vec<RutabagaChannel> = Vec::new();
-        for (channel_name, path) in &channels {
+        for (channel_name, path) in channels {
             match &channel_name[..] {
                 "" => rutabaga_channels.push(RutabagaChannel {
                     base_channel: path.clone(),
@@ -1127,8 +1125,8 @@
             .set_use_surfaceless(gpu_parameters.renderer_use_surfaceless)
             .set_use_vulkan(gpu_parameters.use_vulkan.unwrap_or_default())
             .set_wsi(gpu_parameters.wsi.as_ref())
-            .set_use_external_blob(external_blob)
-            .set_use_system_blob(system_blob)
+            .set_use_external_blob(gpu_parameters.external_blob)
+            .set_use_system_blob(gpu_parameters.system_blob)
             .set_use_render_server(use_render_server);
 
         Gpu {
@@ -1144,7 +1142,7 @@
             display_event: Arc::new(AtomicBool::new(false)),
             rutabaga_builder: Some(rutabaga_builder),
             pci_bar_size: gpu_parameters.pci_bar_size,
-            external_blob,
+            external_blob: gpu_parameters.external_blob,
             rutabaga_component: component,
             #[cfg(windows)]
             wndproc_thread: Some(wndproc_thread),
diff --git a/devices/src/virtio/gpu/parameters.rs b/devices/src/virtio/gpu/parameters.rs
index 9317856..a4e7573 100644
--- a/devices/src/virtio/gpu/parameters.rs
+++ b/devices/src/virtio/gpu/parameters.rs
@@ -64,6 +64,9 @@
     pub pci_bar_size: u64,
     #[serde(rename = "context-types", with = "serde_capset_mask")]
     pub capset_mask: u64,
+    // enforce that blob resources MUST be exportable as file descriptors
+    pub external_blob: bool,
+    pub system_blob: bool,
 }
 
 impl Default for GpuParameters {
@@ -84,6 +87,8 @@
             pci_bar_size: (1 << 33),
             udmabuf: false,
             capset_mask: 0,
+            external_blob: false,
+            system_blob: false,
         }
     }
 }
diff --git a/devices/src/virtio/vhost/user/device/gpu/sys/unix.rs b/devices/src/virtio/vhost/user/device/gpu/sys/unix.rs
index 48147dd..144ae07 100644
--- a/devices/src/virtio/vhost/user/device/gpu/sys/unix.rs
+++ b/devices/src/virtio/vhost/user/device/gpu/sys/unix.rs
@@ -170,7 +170,7 @@
         wayland_sock,
     } = opts;
 
-    let wayland_paths: BTreeMap<_, _> = wayland_sock.into_iter().collect();
+    let channels: BTreeMap<_, _> = wayland_sock.into_iter().collect();
 
     let resource_bridge_listeners = resource_bridge
         .into_iter()
@@ -229,7 +229,7 @@
         virtio::DisplayBackend::X(x_display),
         virtio::DisplayBackend::Stub,
     ];
-    if let Some(p) = wayland_paths.get("") {
+    if let Some(p) = channels.get("") {
         display_backends.insert(0, virtio::DisplayBackend::Wayland(Some(p.to_owned())));
     }
 
@@ -238,13 +238,12 @@
 
     // The regular gpu device sets this to true when sandboxing is enabled. Assume that we
     // are always sandboxed.
-    let external_blob = true;
+    gpu_parameters.external_blob = true;
 
     // Fallback for when external_blob is not available on the machine. Currently always off.
-    let system_blob = false;
+    gpu_parameters.system_blob = false;
 
     let base_features = virtio::base_features(ProtectionType::Unprotected);
-    let channels = wayland_paths;
 
     let listener = VhostUserListener::new_from_socket_or_vfio(&socket, &vfio, MAX_QUEUE_NUM, None)?;
 
@@ -254,12 +253,11 @@
         Vec::new(), // resource_bridges, handled separately by us
         display_backends,
         &gpu_parameters,
+        /* rutabaga_server_descriptor */
         None,
         event_devices,
-        external_blob,
-        system_blob,
         base_features,
-        channels,
+        &channels,
         /* gpu_cgroup_path */
         None,
     )));
diff --git a/devices/src/virtio/vhost/user/device/gpu/sys/windows.rs b/devices/src/virtio/vhost/user/device/gpu/sys/windows.rs
index b6e1481..3d0d050 100644
--- a/devices/src/virtio/vhost/user/device/gpu/sys/windows.rs
+++ b/devices/src/virtio/vhost/user/device/gpu/sys/windows.rs
@@ -185,11 +185,13 @@
     let wndproc_thread =
         virtio::gpu::start_wndproc_thread(None).context("failed to start wndproc_thread")?;
 
+    let mut gpu_params = config.params.clone();
+
     // Required to share memory across processes.
-    let external_blob = true;
+    gpu_params.external_blob = true;
 
     // Fallback for when external_blob is not available on the machine. Currently always off.
-    let system_blob = false;
+    gpu_params.system_blob = false;
 
     let base_features = virtio::base_features(ProtectionType::Unprotected);
 
@@ -197,13 +199,11 @@
         config.exit_evt_wrtube,
         /*resource_bridges=*/ Vec::new(),
         display_backends,
-        &config.params,
-        None,
+        &gpu_params,
+        /*render_server_descriptor*/ None,
         config.event_devices,
-        external_blob,
-        system_blob,
         base_features,
-        /*channels=*/ Default::default(),
+        /*channels=*/ &Default::default(),
         wndproc_thread,
     )));
 
diff --git a/src/crosvm/sys/unix.rs b/src/crosvm/sys/unix.rs
index 82bcd9e..9a3683a 100644
--- a/src/crosvm/sys/unix.rs
+++ b/src/crosvm/sys/unix.rs
@@ -286,15 +286,15 @@
     #[cfg(feature = "gpu")]
     {
         if let Some(gpu_parameters) = &cfg.gpu_parameters {
-            let display_param = if gpu_parameters.display_params.is_empty() {
-                Default::default()
-            } else {
-                gpu_parameters.display_params[0].clone()
-            };
-            let (gpu_display_w, gpu_display_h) = display_param.get_virtual_display_size();
-
             let mut event_devices = Vec::new();
             if cfg.display_window_mouse {
+                let display_param = if gpu_parameters.display_params.is_empty() {
+                    Default::default()
+                } else {
+                    gpu_parameters.display_params[0].clone()
+                };
+                let (gpu_display_w, gpu_display_h) = display_param.get_virtual_display_size();
+
                 let (event_device_socket, virtio_dev_socket) =
                     StreamChannel::pair(BlockingMode::Nonblocking, FramingMode::Byte)
                         .context("failed to create socket")?;
@@ -344,9 +344,6 @@
                 vm_evt_wrtube,
                 gpu_control_tube,
                 resource_bridges,
-                // Use the unnamed socket for GPU display screens.
-                cfg.wayland_socket_paths.get(""),
-                cfg.x_display.clone(),
                 render_server_fd,
                 event_devices,
             )?);
diff --git a/src/crosvm/sys/unix/gpu.rs b/src/crosvm/sys/unix/gpu.rs
index ca2289f..284f6d4 100644
--- a/src/crosvm/sys/unix/gpu.rs
+++ b/src/crosvm/sys/unix/gpu.rs
@@ -87,17 +87,20 @@
     exit_evt_wrtube: &SendTube,
     gpu_control_tube: Tube,
     resource_bridges: Vec<Tube>,
-    wayland_socket_path: Option<&PathBuf>,
-    x_display: Option<String>,
     render_server_fd: Option<SafeDescriptor>,
     event_devices: Vec<EventDevice>,
 ) -> DeviceResult {
+    let is_sandboxed = cfg.jail_config.is_some();
+    let mut gpu_params = cfg.gpu_parameters.clone().unwrap();
+    gpu_params.external_blob = is_sandboxed;
+
     let mut display_backends = vec![
-        virtio::DisplayBackend::X(x_display),
+        virtio::DisplayBackend::X(cfg.x_display.clone()),
         virtio::DisplayBackend::Stub,
     ];
 
-    if let Some(socket_path) = wayland_socket_path {
+    // Use the unnamed socket for GPU display screens.
+    if let Some(socket_path) = cfg.wayland_socket_paths.get("") {
         display_backends.insert(
             0,
             virtio::DisplayBackend::Wayland(Some(socket_path.to_owned())),
@@ -111,13 +114,11 @@
         gpu_control_tube,
         resource_bridges,
         display_backends,
-        cfg.gpu_parameters.as_ref().unwrap(),
+        &gpu_params,
         render_server_fd,
         event_devices,
-        /*external_blob=*/ cfg.jail_config.is_some(),
-        /*system_blob=*/ false,
         virtio::base_features(cfg.protection_type),
-        cfg.wayland_socket_paths.clone(),
+        &cfg.wayland_socket_paths,
         cfg.gpu_cgroup_path.as_ref(),
     );
 
@@ -130,12 +131,12 @@
         let mut jail = create_gpu_minijail(&jail_config.pivot_root, &config)?;
 
         // Prepare GPU shader disk cache directory.
-        let (cache_dir, cache_size) = cfg
-            .gpu_parameters
-            .as_ref()
-            .map(|params| (params.cache_path.as_ref(), params.cache_size.as_ref()))
-            .unwrap();
-        let cache_info = get_gpu_cache_info(cache_dir, cache_size, None, cfg.jail_config.is_some());
+        let cache_info = get_gpu_cache_info(
+            gpu_params.cache_path.as_ref(),
+            gpu_params.cache_size.as_ref(),
+            None,
+            cfg.jail_config.is_some(),
+        );
 
         if let Some(dir) = cache_info.directory {
             // Manually bind mount recursively to allow DLC shader caches
diff --git a/src/sys/windows/generic.rs b/src/sys/windows/generic.rs
index ab11bd4..3fe8662 100644
--- a/src/sys/windows/generic.rs
+++ b/src/sys/windows/generic.rs
@@ -201,10 +201,8 @@
         gpu_parameters,
         None,
         event_devices,
-        /* external_blob= */ false,
-        /* system_blob= */ false,
         features,
-        BTreeMap::new(),
+        &BTreeMap::new(),
         wndproc_thread,
     ))
 }