blob: 0e99c34db9e0399c519a05aa5ec7a50d9f0ee8b5 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#[cfg(feature = "kiwi")]
use base::warn;
#[cfg(feature = "kiwi")]
use battlestar::process_invariants;
use devices::virtio::GpuDisplayMode;
use devices::virtio::GpuDisplayParameters;
#[cfg(feature = "gfxstream")]
use devices::virtio::GpuMode;
use devices::virtio::GpuParameters;
use vm_control::gpu::DEFAULT_DPI;
use crate::crosvm::cmdline::FixedGpuDisplayParameters;
use crate::crosvm::cmdline::FixedGpuParameters;
use crate::crosvm::config::Config;
#[cfg(feature = "gfxstream")]
fn default_use_vulkan() -> bool {
!cfg!(windows)
}
pub(crate) fn fixup_gpu_options(
mut gpu_params: GpuParameters,
) -> Result<FixedGpuParameters, String> {
// Fix up `gpu_params.display_params` parsed from command-line.
gpu_params.display_params = gpu_params
.display_params
.into_iter()
.map(|p| fixup_gpu_display_options(p).map(|p| p.0))
.collect::<Result<Vec<_>, _>>()?;
match (
gpu_params.__width_compat.take(),
gpu_params.__height_compat.take(),
) {
(Some(width), Some(height)) => {
let display_mode = GpuDisplayMode::Windowed(width, height);
gpu_params
.display_params
.push(GpuDisplayParameters::default_with_mode(display_mode));
}
(None, None) => {}
_ => {
return Err("must include both 'width' and 'height' if either is supplied".to_string())
}
}
#[cfg(feature = "gfxstream")]
if gpu_params.mode == GpuMode::ModeGfxstream {
if gpu_params.use_vulkan.is_none() {
gpu_params.use_vulkan = Some(default_use_vulkan());
}
} else {
#[cfg(windows)]
return Err(format!(
"backend type {:?} is deprecated, please use gfxstream",
gpu_params.mode
));
}
Ok(FixedGpuParameters(gpu_params))
}
/// Fixes `GpuDisplayParameters` after parsing using serde.
///
/// The `dpi` field is guaranteed to be populated after this is called.
pub(crate) fn fixup_gpu_display_options(
mut display_params: GpuDisplayParameters,
) -> Result<FixedGpuDisplayParameters, String> {
let (horizontal_dpi_compat, vertical_dpi_compat) = (
display_params.__horizontal_dpi_compat.take(),
display_params.__vertical_dpi_compat.take(),
);
// Make sure `display_params.dpi` is always populated.
display_params.dpi = Some(match display_params.dpi {
Some(dpi) => {
if horizontal_dpi_compat.is_some() || vertical_dpi_compat.is_some() {
return Err(
"if 'dpi' is supplied, 'horizontal-dpi' and 'vertical-dpi' must not be supplied"
.to_string(),
);
}
dpi
}
None => (
horizontal_dpi_compat.unwrap_or(DEFAULT_DPI),
vertical_dpi_compat.unwrap_or(DEFAULT_DPI),
),
});
Ok(FixedGpuDisplayParameters(display_params))
}
pub(crate) fn validate_gpu_config(cfg: &mut Config) -> Result<(), String> {
if let Some(gpu_parameters) = cfg.gpu_parameters.as_mut() {
if !gpu_parameters.pci_bar_size.is_power_of_two() {
return Err(format!(
"`pci-bar-size` must be a power of two but is {}",
gpu_parameters.pci_bar_size
));
}
// Add a default display if no display is specified.
if gpu_parameters.display_params.is_empty() {
gpu_parameters.display_params.push(Default::default());
}
// Process invariants are not written to the static `PROCESS_INVARIANTS` yet, so instead of
// calling `phenotype!(kiwi_emulator_feature, get_enable_4k_uhd_resolution)`, we have to
// load it by ourselves.
// TODO(b/276909432): The BSS should read the experiment flags and specify the virtual
// display size, and then we can remove this workaround.
#[cfg(feature = "kiwi")]
let is_4k_uhd_enabled = match process_invariants::load_invariants(
&cfg.process_invariants_data_handle,
&cfg.process_invariants_data_size,
) {
Ok(invariants) => invariants
.get_flag_snapshot()
.get_features()
.kiwi_emulator_feature
.clone()
.unwrap_or_default()
.get_enable_4k_uhd_resolution(),
Err(e) => {
warn!(
"Failed to load process invariants, will not enable 4k UHD: {}",
e
);
false
}
};
#[cfg(not(feature = "kiwi"))]
let is_4k_uhd_enabled = false;
let (width, height) =
gpu_parameters.display_params[0].get_virtual_display_size_4k_uhd(is_4k_uhd_enabled);
if let Some(virtio_multi_touch) = cfg.virtio_multi_touch.first_mut() {
virtio_multi_touch.set_default_size(width, height);
}
if let Some(virtio_single_touch) = cfg.virtio_single_touch.first_mut() {
virtio_single_touch.set_default_size(width, height);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use argh::FromArgs;
#[cfg(feature = "gfxstream")]
use devices::virtio::GpuWsi;
use super::*;
use crate::crosvm::config::from_key_values;
const fn get_backend_name() -> &'static str {
if cfg!(feature = "gfxstream") {
"gfxstream"
} else if cfg!(feature = "virgl_renderer") {
"virglrenderer"
} else {
"2d"
}
}
/// Parses and fix up a `GpuParameters` from a command-line option string.
fn parse_gpu_options(s: &str) -> Result<GpuParameters, String> {
from_key_values::<FixedGpuParameters>(s).map(|p| p.0)
}
fn parse_gpu_display_options(s: &str) -> Result<GpuDisplayParameters, String> {
from_key_values::<GpuDisplayParameters>(s)
}
#[test]
fn parse_gpu_options_mode() {
use devices::virtio::gpu::GpuMode;
let gpu_params = parse_gpu_options("backend=2d").unwrap();
assert_eq!(gpu_params.mode, GpuMode::Mode2D);
let gpu_params = parse_gpu_options("backend=2D").unwrap();
assert_eq!(gpu_params.mode, GpuMode::Mode2D);
#[cfg(feature = "virgl_renderer")]
{
let gpu_params = parse_gpu_options("backend=3d").unwrap();
assert_eq!(gpu_params.mode, GpuMode::ModeVirglRenderer);
let gpu_params = parse_gpu_options("backend=3D").unwrap();
assert_eq!(gpu_params.mode, GpuMode::ModeVirglRenderer);
let gpu_params = parse_gpu_options("backend=virglrenderer").unwrap();
assert_eq!(gpu_params.mode, GpuMode::ModeVirglRenderer);
}
#[cfg(feature = "gfxstream")]
{
let gpu_params = parse_gpu_options("backend=gfxstream").unwrap();
assert_eq!(gpu_params.mode, GpuMode::ModeGfxstream);
}
}
#[test]
fn parse_gpu_options_flags() {
macro_rules! assert_default {
($p:ident.$a:ident) => {
assert_eq!($p.$a, GpuParameters::default().$a)
};
}
let gpu_params = parse_gpu_options("").unwrap();
assert_default!(gpu_params.renderer_use_egl);
assert_default!(gpu_params.renderer_use_gles);
assert_default!(gpu_params.renderer_use_glx);
assert_default!(gpu_params.renderer_use_surfaceless);
assert_default!(gpu_params.use_vulkan);
assert_default!(gpu_params.udmabuf);
let gpu_params = parse_gpu_options("egl=false,gles=false").unwrap();
assert_eq!(gpu_params.renderer_use_egl, false);
assert_eq!(gpu_params.renderer_use_gles, false);
assert_default!(gpu_params.renderer_use_glx);
assert_default!(gpu_params.renderer_use_surfaceless);
assert_default!(gpu_params.use_vulkan);
assert_default!(gpu_params.udmabuf);
let gpu_params = parse_gpu_options("surfaceless=false,glx").unwrap();
assert_default!(gpu_params.renderer_use_egl);
assert_default!(gpu_params.renderer_use_gles);
assert_eq!(gpu_params.renderer_use_surfaceless, false);
assert_eq!(gpu_params.renderer_use_glx, true);
assert_default!(gpu_params.use_vulkan);
assert_default!(gpu_params.udmabuf);
let gpu_params = parse_gpu_options("vulkan,udmabuf").unwrap();
assert_default!(gpu_params.renderer_use_egl);
assert_default!(gpu_params.renderer_use_gles);
assert_default!(gpu_params.renderer_use_glx);
assert_default!(gpu_params.renderer_use_surfaceless);
assert_eq!(gpu_params.use_vulkan, Some(true));
assert_eq!(gpu_params.udmabuf, true);
assert!(parse_gpu_options("egl=false,gles=true,foomatic").is_err());
}
#[cfg(feature = "gfxstream")]
#[test]
fn parse_gpu_options_gfxstream_with_wsi_specified() {
{
let gpu_params = parse_gpu_options("backend=gfxstream,wsi=vk").unwrap();
assert!(matches!(gpu_params.wsi, Some(GpuWsi::Vulkan)));
}
{
let gpu_params = parse_gpu_options("wsi=vk,backend=gfxstream").unwrap();
assert!(matches!(gpu_params.wsi, Some(GpuWsi::Vulkan)));
}
{
assert!(parse_gpu_options("backend=gfxstream,wsi=invalid_value").is_err());
}
{
assert!(parse_gpu_options("wsi=invalid_value,backend=gfxstream").is_err());
}
}
#[test]
fn parse_gpu_options_default_vulkan_support() {
let gpu_params = parse_gpu_options("backend=2d").unwrap();
assert_eq!(gpu_params.use_vulkan, None);
#[cfg(feature = "virgl_renderer")]
{
let gpu_params = parse_gpu_options("backend=virglrenderer").unwrap();
assert_eq!(gpu_params.use_vulkan, None);
}
#[cfg(feature = "gfxstream")]
{
let gpu_params = parse_gpu_options("backend=gfxstream").unwrap();
assert_eq!(gpu_params.use_vulkan, Some(default_use_vulkan()));
}
}
#[test]
fn parse_gpu_options_with_vulkan_specified() {
const BACKEND: &str = get_backend_name();
{
let gpu_params = parse_gpu_options("vulkan=true").unwrap();
assert_eq!(gpu_params.use_vulkan, Some(true));
}
{
let gpu_params =
parse_gpu_options(format!("backend={},vulkan=true", BACKEND).as_str()).unwrap();
assert_eq!(gpu_params.use_vulkan, Some(true));
}
{
let gpu_params =
parse_gpu_options(format!("vulkan=true,backend={}", BACKEND).as_str()).unwrap();
assert_eq!(gpu_params.use_vulkan, Some(true));
}
{
let gpu_params = parse_gpu_options("vulkan=false").unwrap();
assert_eq!(gpu_params.use_vulkan, Some(false));
}
{
let gpu_params =
parse_gpu_options(format!("backend={},vulkan=false", BACKEND).as_str()).unwrap();
assert_eq!(gpu_params.use_vulkan, Some(false));
}
{
let gpu_params =
parse_gpu_options(format!("vulkan=false,backend={}", BACKEND).as_str()).unwrap();
assert_eq!(gpu_params.use_vulkan, Some(false));
}
{
assert!(parse_gpu_options(
format!("backend={},vulkan=invalid_value", BACKEND).as_str()
)
.is_err());
}
{
assert!(parse_gpu_options(
format!("vulkan=invalid_value,backend={}", BACKEND).as_str()
)
.is_err());
}
}
#[test]
fn parse_gpu_options_context_types() {
use rutabaga_gfx::RUTABAGA_CAPSET_CROSS_DOMAIN;
use rutabaga_gfx::RUTABAGA_CAPSET_VIRGL;
let gpu_params = parse_gpu_options("context-types=virgl:cross-domain").unwrap();
assert_eq!(
gpu_params.capset_mask,
(1 << RUTABAGA_CAPSET_VIRGL) | (1 << RUTABAGA_CAPSET_CROSS_DOMAIN)
);
}
#[test]
fn parse_gpu_options_cache() {
let gpu_params = parse_gpu_options("cache-path=/path/to/cache,cache-size=16384").unwrap();
assert_eq!(gpu_params.cache_path, Some("/path/to/cache".into()));
assert_eq!(gpu_params.cache_size, Some("16384".into()));
}
#[test]
fn parse_gpu_options_pci_bar() {
let gpu_params = parse_gpu_options("pci-bar-size=0x100000").unwrap();
assert_eq!(gpu_params.pci_bar_size, 0x100000);
}
#[test]
fn parse_gpu_options_no_display_specified() {
let display_params = parse_gpu_options("").unwrap().display_params;
assert!(display_params.is_empty());
}
#[test]
fn parse_gpu_options_display_size_valid() {
const WIDTH: u32 = 1720;
const HEIGHT: u32 = 1800;
let display_params = parse_gpu_options(format!("width={},height=720", WIDTH).as_str())
.unwrap()
.display_params;
assert_eq!(display_params.len(), 1);
assert!(
matches!(display_params[0].mode, GpuDisplayMode::Windowed(width, _) if width == WIDTH)
);
let display_params = parse_gpu_options(format!("width=1280,height={}", HEIGHT).as_str())
.unwrap()
.display_params;
assert_eq!(display_params.len(), 1);
assert!(
matches!(display_params[0].mode, GpuDisplayMode::Windowed(_, height) if height == HEIGHT)
);
}
#[test]
fn parse_gpu_options_display_size_incomplete() {
assert!(parse_gpu_options("width=1280").is_err());
assert!(parse_gpu_options("height=720").is_err());
}
#[test]
fn parse_gpu_options_display_size_duplicated() {
assert!(parse_gpu_options("width=1280,width=1280,height=720").is_err());
assert!(parse_gpu_options("width=1280,height=720,height=720").is_err());
}
#[test]
fn parse_gpu_display_options_mode() {
let display_params = parse_gpu_display_options("mode=windowed[1280,720]").unwrap();
assert!(matches!(
display_params.mode,
GpuDisplayMode::Windowed(_, _)
));
#[cfg(windows)]
{
let display_params = parse_gpu_display_options("mode=borderless_full_screen").unwrap();
assert!(matches!(
display_params.mode,
GpuDisplayMode::BorderlessFullScreen(_)
));
}
assert!(parse_gpu_display_options("mode=invalid_mode").is_err());
}
#[test]
fn parse_gpu_display_options_mode_duplicated() {
assert!(
parse_gpu_display_options("mode=windowed[1280,720],mode=windowed[1280,720]").is_err()
);
}
#[cfg(windows)]
#[test]
fn parse_gpu_display_options_borderless_full_screen_should_not_be_specified_with_size() {
assert!(parse_gpu_display_options("mode=borderless_full_screen[1280,720]").is_err());
}
#[test]
fn parse_gpu_display_options_windowed_with_size() {
const WIDTH: u32 = 1720;
const HEIGHT: u32 = 1800;
let display_params =
parse_gpu_display_options(format!("mode=windowed[{},720]", WIDTH).as_str()).unwrap();
assert!(matches!(
display_params.mode,
GpuDisplayMode::Windowed(width, _) if width == WIDTH
));
let display_params =
parse_gpu_display_options(format!("mode=windowed[1280,{}]", HEIGHT).as_str()).unwrap();
assert!(matches!(
display_params.mode,
GpuDisplayMode::Windowed(_, height) if height == HEIGHT
));
assert!(parse_gpu_display_options("mode=windowed[]").is_err());
assert!(parse_gpu_display_options("mode=windowed[1280]").is_err());
}
#[test]
fn parse_gpu_display_options_hidden() {
let display_params = parse_gpu_display_options("hidden").unwrap();
assert!(display_params.hidden);
let display_params = parse_gpu_display_options("hidden=true").unwrap();
assert!(display_params.hidden);
let display_params = parse_gpu_display_options("hidden=false").unwrap();
assert!(!display_params.hidden);
}
#[test]
fn parse_gpu_display_options_hidden_duplicated() {
assert!(parse_gpu_display_options("hidden,hidden").is_err());
}
#[test]
fn parse_gpu_display_options_refresh_rate() {
const REFRESH_RATE: u32 = 30;
let display_params =
parse_gpu_display_options(format!("refresh-rate={}", REFRESH_RATE).as_str()).unwrap();
assert_eq!(display_params.refresh_rate, REFRESH_RATE);
}
#[test]
fn parse_gpu_display_options_refresh_rate_duplicated() {
assert!(parse_gpu_display_options("refresh-rate=30,refresh-rate=60").is_err());
}
#[test]
fn parse_gpu_display_options_dpi() {
const HORIZONTAL_DPI: u32 = 160;
const VERTICAL_DPI: u32 = 25;
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
format!("dpi=[{},{}]", HORIZONTAL_DPI, VERTICAL_DPI).as_str(),
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(
gpu_params.display_params[0].horizontal_dpi(),
HORIZONTAL_DPI
);
assert_eq!(gpu_params.display_params[0].vertical_dpi(), VERTICAL_DPI);
}
#[test]
fn parse_gpu_display_options_default_dpi() {
{
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&["--gpu-display", "mode=windowed[800,600]", "/dev/null"],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(gpu_params.display_params[0].horizontal_dpi(), DEFAULT_DPI);
assert_eq!(gpu_params.display_params[0].vertical_dpi(), DEFAULT_DPI);
}
{
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&["--gpu", "displays=[[mode=windowed[800,600]]]", "/dev/null"],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(gpu_params.display_params[0].horizontal_dpi(), DEFAULT_DPI);
assert_eq!(gpu_params.display_params[0].vertical_dpi(), DEFAULT_DPI);
}
}
#[test]
fn parse_gpu_display_options_dpi_compat() {
const HORIZONTAL_DPI: u32 = 160;
const VERTICAL_DPI: u32 = 25;
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
format!(
"horizontal-dpi={},vertical-dpi={}",
HORIZONTAL_DPI, VERTICAL_DPI
)
.as_str(),
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(
gpu_params.display_params[0].horizontal_dpi(),
HORIZONTAL_DPI
);
assert_eq!(gpu_params.display_params[0].vertical_dpi(), VERTICAL_DPI);
}
#[test]
fn parse_gpu_display_options_dpi_duplicated() {
assert!(crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
"horizontal-dpi=160,horizontal-dpi=320",
"/dev/null",
],
)
.is_err());
assert!(crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
"vertical-dpi=25,vertical-dpi=50",
"/dev/null",
],
)
.is_err());
assert!(crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
"dpi=[160,320],horizontal-dpi=160,vertical-dpi=25",
"/dev/null",
],
)
.is_err());
}
#[test]
fn parse_gpu_options_single_display() {
{
let gpu_params = parse_gpu_options("displays=[[mode=windowed[800,600]]]").unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(800, 600)
);
}
#[cfg(windows)]
{
let gpu_params = parse_gpu_options("displays=[[mode=borderless_full_screen]]").unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert!(matches!(
gpu_params.display_params[0].mode,
GpuDisplayMode::BorderlessFullScreen(_)
));
}
}
#[test]
fn parse_gpu_options_multi_display() {
{
let gpu_params =
parse_gpu_options("displays=[[mode=windowed[500,600]],[mode=windowed[700,800]]]")
.unwrap();
assert_eq!(gpu_params.display_params.len(), 2);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(500, 600)
);
assert_eq!(
gpu_params.display_params[1].mode,
GpuDisplayMode::Windowed(700, 800)
);
}
#[cfg(windows)]
{
let gpu_params = parse_gpu_options(
"displays=[[mode=windowed[800,600]],[mode=borderless_full_screen]]",
)
.unwrap();
assert_eq!(gpu_params.display_params.len(), 2);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(800, 600)
);
assert!(matches!(
gpu_params.display_params[1].mode,
GpuDisplayMode::BorderlessFullScreen(_)
));
}
}
#[test]
fn parse_gpu_options_single_display_compat() {
const BACKEND: &str = get_backend_name();
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
format!("backend={},width=500,height=600", BACKEND,).as_str(),
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(500, 600)
);
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
format!("backend={}", BACKEND,).as_str(),
"--gpu-display",
"mode=windowed[700,800]",
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 1);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(700, 800)
);
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[test]
fn parse_gpu_options_and_gpu_display_options_multi_display_supported_on_unix() {
{
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
format!(
"backend={},width=500,height=600,displays=[[mode=windowed[700,800]]]",
get_backend_name()
)
.as_str(),
"--gpu-display",
"mode=windowed[900,1000]",
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.display_params.len(), 3);
assert_eq!(
gpu_params.display_params[0].mode,
GpuDisplayMode::Windowed(700, 800)
);
assert_eq!(
gpu_params.display_params[1].mode,
GpuDisplayMode::Windowed(500, 600)
);
assert_eq!(
gpu_params.display_params[2].mode,
GpuDisplayMode::Windowed(900, 1000)
);
}
}
#[cfg(windows)]
#[test]
fn parse_gpu_options_and_gpu_display_options_multi_display_unsupported_on_windows() {
let command = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu-display",
"mode=borderless_full_screen",
"--gpu-display",
"mode=borderless_full_screen",
"/dev/null",
],
)
.unwrap();
assert!(Config::try_from(command).is_err());
let command = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
"width=1280,height=720",
"--gpu-display",
"mode=borderless_full_screen",
"/dev/null",
],
)
.unwrap();
assert!(Config::try_from(command).is_err());
let command = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
"displays=[[mode=windowed[1280,720]]]",
"--gpu-display",
"mode=borderless_full_screen",
"/dev/null",
],
)
.unwrap();
assert!(Config::try_from(command).is_err());
let command = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
"displays=[[mode=windowed[500,600]],[mode=windowed[700,800]]]",
"/dev/null",
],
)
.unwrap();
assert!(Config::try_from(command).is_err());
}
#[test]
fn parse_gpu_options_cache_size() {
{
let config: Config = crate::crosvm::cmdline::RunCommand::from_args(
&[],
&[
"--gpu",
"vulkan=false,cache-path=/some/path,cache-size=50M",
"/dev/null",
],
)
.unwrap()
.try_into()
.unwrap();
let gpu_params = config.gpu_parameters.unwrap();
assert_eq!(gpu_params.cache_path, Some("/some/path".into()));
assert_eq!(gpu_params.cache_size, Some("50M".into()));
}
}
}