• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Definitions and utilities for GPU related parameters.
6 
7 #[cfg(windows)]
8 use std::marker::PhantomData;
9 
10 use rutabaga_gfx::RutabagaWsi;
11 use serde::Deserialize;
12 use serde::Deserializer;
13 use serde::Serialize;
14 use serde::Serializer;
15 use serde_keyvalue::FromKeyValues;
16 use vm_control::gpu::DisplayParameters;
17 
18 use super::GpuMode;
19 
20 mod serde_capset_mask {
21     use super::*;
22 
serialize<S>(capset_mask: &u64, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,23     pub fn serialize<S>(capset_mask: &u64, serializer: S) -> Result<S::Ok, S::Error>
24     where
25         S: Serializer,
26     {
27         let context_types = rutabaga_gfx::calculate_capset_names(*capset_mask).join(":");
28 
29         serializer.serialize_str(context_types.as_str())
30     }
31 
deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u64, D::Error>32     pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u64, D::Error> {
33         let s = String::deserialize(deserializer)?;
34         let context_types: Vec<String> = s.split(':').map(|s| s.to_string()).collect();
35 
36         Ok(rutabaga_gfx::calculate_capset_mask(context_types))
37     }
38 }
39 
40 #[derive(Clone, Debug, Serialize, Deserialize, FromKeyValues)]
41 #[serde(deny_unknown_fields, default, rename_all = "kebab-case")]
42 pub struct GpuParameters {
43     #[serde(rename = "backend")]
44     pub mode: GpuMode,
45     #[serde(rename = "displays")]
46     pub display_params: Vec<DisplayParameters>,
47     // `width` and `height` are supported for CLI backwards compatibility.
48     #[serde(rename = "width")]
49     pub __width_compat: Option<u32>,
50     #[serde(rename = "height")]
51     pub __height_compat: Option<u32>,
52     #[serde(rename = "egl")]
53     pub renderer_use_egl: bool,
54     #[serde(rename = "gles")]
55     pub renderer_use_gles: bool,
56     #[serde(rename = "glx")]
57     pub renderer_use_glx: bool,
58     #[serde(rename = "surfaceless")]
59     pub renderer_use_surfaceless: bool,
60     #[cfg(feature = "gfxstream")]
61     #[serde(rename = "angle")]
62     pub gfxstream_use_guest_angle: Option<bool>,
63     #[serde(rename = "vulkan")]
64     pub use_vulkan: Option<bool>,
65     // It is possible that we compile with the gfxstream feature but don't use the gfxstream
66     // backend, in which case we want to ensure this option is not touched accidentally, so we make
67     // it an `Option` with default value `None`.
68     #[cfg(feature = "gfxstream")]
69     #[serde(rename = "gles31")]
70     pub gfxstream_support_gles31: Option<bool>,
71     pub wsi: Option<RutabagaWsi>,
72     pub udmabuf: bool,
73     pub cache_path: Option<String>,
74     pub cache_size: Option<String>,
75     pub pci_bar_size: u64,
76     #[serde(rename = "context-types", with = "serde_capset_mask")]
77     pub capset_mask: u64,
78 }
79 
80 impl Default for GpuParameters {
default() -> Self81     fn default() -> Self {
82         GpuParameters {
83             display_params: vec![],
84             __width_compat: None,
85             __height_compat: None,
86             renderer_use_egl: true,
87             renderer_use_gles: true,
88             renderer_use_glx: false,
89             renderer_use_surfaceless: true,
90             #[cfg(feature = "gfxstream")]
91             gfxstream_use_guest_angle: None,
92             use_vulkan: None,
93             mode: Default::default(),
94             #[cfg(feature = "gfxstream")]
95             gfxstream_support_gles31: None,
96             wsi: None,
97             cache_path: None,
98             cache_size: None,
99             pci_bar_size: (1 << 33),
100             udmabuf: false,
101             capset_mask: 0,
102         }
103     }
104 }
105 
106 #[cfg(test)]
107 mod tests {
108     use serde_json::*;
109 
110     use super::*;
111 
112     #[test]
capset_mask_serialize_deserialize()113     fn capset_mask_serialize_deserialize() {
114         #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
115         struct CapsetMask {
116             #[serde(rename = "context-types", with = "serde_capset_mask")]
117             pub value: u64,
118         }
119 
120         // Capset "virgl", id: 1, capset_mask: 0b0010
121         // Capset "gfxstream", id: 3, capset_mask: 0b1000
122         const CAPSET_MASK: u64 = 0b1010;
123         const SERIALIZED_CAPSET_MASK: &str = "{\"context-types\":\"virgl:gfxstream\"}";
124 
125         let capset_mask = CapsetMask { value: CAPSET_MASK };
126 
127         assert_eq!(to_string(&capset_mask).unwrap(), SERIALIZED_CAPSET_MASK);
128         assert_eq!(
129             from_str::<CapsetMask>(SERIALIZED_CAPSET_MASK).unwrap(),
130             capset_mask
131         );
132     }
133 }
134