diff options
Diffstat (limited to 'gpu_display')
-rw-r--r-- | gpu_display/Android.bp | 4 | ||||
-rw-r--r-- | gpu_display/examples/simple.rs | 5 | ||||
-rw-r--r-- | gpu_display/examples/simple_open.rs | 5 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_android.rs | 5 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_stub.rs | 5 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_win/mod.rs | 42 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_win/surface.rs | 38 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_win/window_manager.rs | 2 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_win/window_procedure_thread.rs | 54 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_wl.rs | 5 | ||||
-rw-r--r-- | gpu_display/src/gpu_display_x.rs | 5 | ||||
-rw-r--r-- | gpu_display/src/lib.rs | 12 | ||||
-rw-r--r-- | gpu_display/src/sys/windows.rs | 4 |
13 files changed, 97 insertions, 89 deletions
diff --git a/gpu_display/Android.bp b/gpu_display/Android.bp index 741f34c7b..e96b71db4 100644 --- a/gpu_display/Android.bp +++ b/gpu_display/Android.bp @@ -1,5 +1,7 @@ // This file is generated by cargo_embargo. -// Do not modify this file as changes will be overridden on upgrade. +// Do not modify this file after the first "rust_*" or "genrule" module +// because the changes will be overridden on upgrade. +// Content before the first "rust_*" or "genrule" module is preserved. // cargo2android.py limitations: // does not handle "-l dylib=wayland-client" yet diff --git a/gpu_display/examples/simple.rs b/gpu_display/examples/simple.rs index 9741dc44a..afc5b1f38 100644 --- a/gpu_display/examples/simple.rs +++ b/gpu_display/examples/simple.rs @@ -9,6 +9,8 @@ mod platform { use anyhow::Context; use anyhow::Result; use gpu_display::*; + use vm_control::gpu::DisplayMode; + use vm_control::gpu::DisplayParameters; pub fn run() -> Result<()> { let mut disp = GpuDisplay::open_wayland(None::<&str>).context("open_wayland")?; @@ -16,8 +18,7 @@ mod platform { .create_surface( None, /* scanout_id= */ Some(0), - 1280, - 1024, + &DisplayParameters::default_with_mode(DisplayMode::Windowed(1280, 1024)), SurfaceType::Scanout, ) .context("create_surface")?; diff --git a/gpu_display/examples/simple_open.rs b/gpu_display/examples/simple_open.rs index 73bdef757..1bf96a068 100644 --- a/gpu_display/examples/simple_open.rs +++ b/gpu_display/examples/simple_open.rs @@ -8,6 +8,8 @@ use anyhow::Context; use anyhow::Result; use gpu_display::GpuDisplay; use gpu_display::SurfaceType; +use vm_control::gpu::DisplayMode; +use vm_control::gpu::DisplayParameters; fn run() -> Result<()> { let mut disp = GpuDisplay::open_x(None::<&str>).context("open_x")?; @@ -15,8 +17,7 @@ fn run() -> Result<()> { .create_surface( None, /* scanout_id= */ Some(0), - 1280, - 1024, + &DisplayParameters::default_with_mode(DisplayMode::Windowed(1280, 1024)), SurfaceType::Scanout, ) .context("create_surface")?; diff --git a/gpu_display/src/gpu_display_android.rs b/gpu_display/src/gpu_display_android.rs index 9fcd5e7bc..5ccef070a 100644 --- a/gpu_display/src/gpu_display_android.rs +++ b/gpu_display/src/gpu_display_android.rs @@ -16,6 +16,7 @@ use base::AsRawDescriptor; use base::Event; use base::RawDescriptor; use base::VolatileSlice; +use vm_control::gpu::DisplayParameters; use crate::DisplayT; use crate::GpuDisplayError; @@ -209,14 +210,14 @@ impl DisplayT for DisplayAndroid { parent_surface_id: Option<u32>, _surface_id: u32, _scanout_id: Option<u32>, - requested_width: u32, - requested_height: u32, + display_params: &DisplayParameters, _surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { if parent_surface_id.is_some() { return Err(GpuDisplayError::Unsupported); } + let (requested_width, requested_height) = display_params.get_virtual_display_size(); // SAFETY: context is an opaque handle. let surface = NonNull::new(unsafe { create_android_surface(self.context.0.as_ptr(), requested_width, requested_height) diff --git a/gpu_display/src/gpu_display_stub.rs b/gpu_display/src/gpu_display_stub.rs index 53403561c..123ab7487 100644 --- a/gpu_display/src/gpu_display_stub.rs +++ b/gpu_display/src/gpu_display_stub.rs @@ -6,6 +6,7 @@ use base::AsRawDescriptor; use base::Event; use base::RawDescriptor; use base::VolatileSlice; +use vm_control::gpu::DisplayParameters; use crate::DisplayT; use crate::GpuDisplayError; @@ -103,14 +104,14 @@ impl DisplayT for DisplayStub { parent_surface_id: Option<u32>, _surface_id: u32, _scanout_id: Option<u32>, - width: u32, - height: u32, + display_params: &DisplayParameters, _surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { if parent_surface_id.is_some() { return Err(GpuDisplayError::Unsupported); } + let (width, height) = display_params.get_virtual_display_size(); Ok(Box::new(StubSurface { width, height, diff --git a/gpu_display/src/gpu_display_win/mod.rs b/gpu_display/src/gpu_display_win/mod.rs index ebe2dd737..f88e86435 100644 --- a/gpu_display/src/gpu_display_win/mod.rs +++ b/gpu_display/src/gpu_display_win/mod.rs @@ -36,14 +36,10 @@ use base::EventWaitResult; use base::RawDescriptor; use base::ReadNotifier; use base::SendTube; -use euclid::size2; -use euclid::Size2D; -use math_util::Size2DCheckedCast; use metrics::sys::windows::Metrics; pub use surface::Surface; use sync::Mutex; use sync::Waitable; -use vm_control::gpu::DisplayMode; use vm_control::gpu::DisplayParameters; use vm_control::ModifyWaitContext; use window_message_processor::DisplaySendToWndProc; @@ -72,28 +68,6 @@ pub(crate) type ObjectId = NonZeroU32; pub struct VirtualDisplaySpace; pub struct HostWindowSpace; -#[derive(Clone)] -pub struct DisplayProperties { - pub start_hidden: bool, - pub is_fullscreen: bool, - pub window_width: u32, - pub window_height: u32, -} - -impl From<&DisplayParameters> for DisplayProperties { - fn from(params: &DisplayParameters) -> Self { - let is_fullscreen = matches!(params.mode, DisplayMode::BorderlessFullScreen(_)); - let (window_width, window_height) = params.get_window_size(); - - Self { - start_hidden: params.hidden, - is_fullscreen, - window_width, - window_height, - } - } -} - pub enum VulkanDisplayWrapper { Uninitialized, #[cfg(feature = "vulkan_display")] @@ -104,7 +78,6 @@ pub struct DisplayWin { wndproc_thread: Rc<WindowProcedureThread>, close_requested_event: Event, win_metrics: Option<Weak<Metrics>>, - display_properties: DisplayProperties, is_surface_created: bool, #[allow(dead_code)] gpu_display_wait_descriptor_ctrl: SendTube, @@ -118,7 +91,6 @@ impl DisplayWin { pub fn new( wndproc_thread: WindowProcedureThread, win_metrics: Option<Weak<Metrics>>, - display_properties: DisplayProperties, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option<VulkanCreateParams>, ) -> Result<DisplayWin, GpuDisplayError> { @@ -133,7 +105,6 @@ impl DisplayWin { wndproc_thread: Rc::new(wndproc_thread), close_requested_event, win_metrics, - display_properties, is_surface_created: false, gpu_display_wait_descriptor_ctrl, event_device_wait_descriptor_requests: Vec::new(), @@ -148,10 +119,10 @@ impl DisplayWin { &mut self, surface_id: u32, scanout_id: u32, - virtual_display_size: Size2D<i32, VirtualDisplaySpace>, + display_params: &DisplayParameters, ) -> Result<Arc<Mutex<VulkanDisplayWrapper>>> { + let display_params_clone = display_params.clone(); let metrics = self.win_metrics.clone(); - let display_properties = self.display_properties.clone(); #[cfg(feature = "vulkan_display")] let vulkan_create_params = self.vulkan_display_create_params.clone(); // This function should not return until surface creation finishes. Besides, we would like @@ -216,9 +187,8 @@ impl DisplayWin { Surface::new( surface_id, window, - &virtual_display_size, metrics, - &display_properties, + &display_params_clone, display_event_dispatcher, vulkan_display, ) @@ -299,8 +269,7 @@ impl DisplayT for DisplayWin { parent_surface_id: Option<u32>, surface_id: u32, scanout_id: Option<u32>, - virtual_display_width: u32, - virtual_display_height: u32, + display_params: &DisplayParameters, surface_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { if parent_surface_id.is_some() { @@ -316,7 +285,7 @@ impl DisplayT for DisplayWin { let vulkan_display = match self.create_surface_internal( surface_id, scanout_id.expect("scanout id is required"), - size2(virtual_display_width, virtual_display_height).checked_cast(), + display_params, ) { Err(e) => { error!("Failed to create surface: {:?}", e); @@ -562,6 +531,7 @@ mod tests { let wndproc_thread_builder = { let mut wndproc_thread_builder = wndproc_thread_builder; wndproc_thread_builder + .set_max_num_windows(1) .set_display_tube(None) .set_ime_tube(Some(_device_ime_tube)); wndproc_thread_builder diff --git a/gpu_display/src/gpu_display_win/surface.rs b/gpu_display/src/gpu_display_win/surface.rs index be5811825..6c7491f50 100644 --- a/gpu_display/src/gpu_display_win/surface.rs +++ b/gpu_display/src/gpu_display_win/surface.rs @@ -24,6 +24,8 @@ use euclid::Box2D; use euclid::Size2D; use metrics::sys::windows::Metrics; use sync::Mutex; +use vm_control::gpu::DisplayMode; +use vm_control::gpu::DisplayParameters; use win_util::keys_down; use winapi::shared::minwindef::HIWORD; use winapi::shared::minwindef::LOWORD; @@ -48,10 +50,8 @@ use super::window_message_processor::SurfaceResources; use super::window_message_processor::WindowMessage; use super::window_message_processor::WindowPosMessage; use super::window_message_processor::HANDLE_WINDOW_MESSAGE_TIMEOUT; -use super::DisplayProperties; use super::HostWindowSpace; use super::MouseMode; -use super::VirtualDisplaySpace; use super::VulkanDisplayWrapper; use crate::EventDeviceKind; @@ -102,6 +102,29 @@ fn update_virtual_display_projection( } } +#[allow(dead_code)] +#[derive(Clone)] +pub(crate) struct DisplayProperties { + pub start_hidden: bool, + pub is_fullscreen: bool, + pub window_width: u32, + pub window_height: u32, +} + +impl From<&DisplayParameters> for DisplayProperties { + fn from(params: &DisplayParameters) -> Self { + let is_fullscreen = matches!(params.mode, DisplayMode::BorderlessFullScreen(_)); + let (window_width, window_height) = params.get_window_size(); + + Self { + start_hidden: params.hidden, + is_fullscreen, + window_width, + window_height, + } + } +} + pub struct Surface { surface_id: u32, mouse_input: MouseInputManager, @@ -116,9 +139,8 @@ impl Surface { pub fn new( surface_id: u32, window: &GuiWindow, - virtual_display_size: &Size2D<i32, VirtualDisplaySpace>, _metrics: Option<Weak<Metrics>>, - display_properties: &DisplayProperties, + display_params: &DisplayParameters, resources: SurfaceResources, vulkan_display: Arc<Mutex<VulkanDisplayWrapper>>, ) -> Result<Self> { @@ -130,8 +152,12 @@ impl Surface { ); let initial_host_viewport_size = window.get_client_rect().context(CONTEXT_MESSAGE)?.size; + let virtual_display_size = { + let (width, height) = display_params.get_virtual_display_size(); + size2(width, height).checked_cast() + }; let virtual_display_manager = - VirtualDisplayManager::new(&initial_host_viewport_size, virtual_display_size); + VirtualDisplayManager::new(&initial_host_viewport_size, &virtual_display_size); // This will make gfxstream initialize the child window to which it will render. update_virtual_display_projection( vulkan_display.lock(), @@ -156,7 +182,7 @@ impl Surface { mouse_input, window_manager: WindowManager::new( window, - display_properties, + &display_params.into(), initial_host_viewport_size, gpu_main_display_tube.clone(), ) diff --git a/gpu_display/src/gpu_display_win/window_manager.rs b/gpu_display/src/gpu_display_win/window_manager.rs index 006718503..f9ca33d84 100644 --- a/gpu_display/src/gpu_display_win/window_manager.rs +++ b/gpu_display/src/gpu_display_win/window_manager.rs @@ -8,9 +8,9 @@ use anyhow::Result; use base::Tube; use super::math_util::Size; +use super::surface::DisplayProperties; use super::window::GuiWindow; use super::window_message_processor::WindowPosMessage; -use super::DisplayProperties; pub(crate) struct NoopWindowManager {} diff --git a/gpu_display/src/gpu_display_win/window_procedure_thread.rs b/gpu_display/src/gpu_display_win/window_procedure_thread.rs index b84d69bf3..84253e762 100644 --- a/gpu_display/src/gpu_display_win/window_procedure_thread.rs +++ b/gpu_display/src/gpu_display_win/window_procedure_thread.rs @@ -62,11 +62,6 @@ use super::window_message_processor::*; // The default app icon id, which is defined in crosvm-manifest.rc. const APP_ICON_ID: u16 = 1; -// The number of GUI windows to pre-create when booting KiwiVM. At most this -// number of guest displays and host windows can be used concurrently. -// TODO(b/314984693): The service or the config file should specify this number. -const MAX_NUM_WINDOWS: usize = 1; - #[derive(Debug)] enum MessageLoopState { /// The initial state. @@ -241,13 +236,14 @@ impl WindowProcedureThread { // We don't implement Default for WindowProcedureThreadBuilder so that the builder function // is the only way to create WindowProcedureThreadBuilder. WindowProcedureThreadBuilder { + max_num_windows: 1, display_tube: None, #[cfg(feature = "kiwi")] ime_tube: None, } } - fn start_thread(gpu_main_display_tube: Option<Tube>) -> Result<Self> { + fn start_thread(max_num_windows: u32, gpu_main_display_tube: Option<Tube>) -> Result<Self> { let (message_router_handle_sender, message_router_handle_receiver) = channel(); let message_loop_state = Arc::new(AtomicI32::new(MessageLoopState::NotStarted as i32)); let close_requested_event = Event::new().unwrap(); @@ -262,6 +258,7 @@ impl WindowProcedureThread { .spawn(move || { match close_requested_event_clone.try_clone() { Ok(close_requested_event) => Self::run_message_loop( + max_num_windows, message_router_handle_sender, message_loop_state_clone, gpu_main_display_tube, @@ -337,6 +334,7 @@ impl WindowProcedureThread { } fn run_message_loop( + max_num_windows: u32, message_router_handle_sender: Sender<Result<u32>>, message_loop_state: Arc<AtomicI32>, gpu_main_display_tube: Option<Tube>, @@ -346,14 +344,16 @@ impl WindowProcedureThread { // SAFETY: // Safe because the dispatcher will take care of the lifetime of the `MessageOnlyWindow` and // `GuiWindow` objects. - match unsafe { Self::create_windows() }.and_then(|(message_router_window, gui_windows)| { - WindowMessageDispatcher::new( - message_router_window, - gui_windows, - gpu_main_display_tube.clone(), - close_requested_event, - ) - }) { + match unsafe { Self::create_windows(max_num_windows) }.and_then( + |(message_router_window, gui_windows)| { + WindowMessageDispatcher::new( + message_router_window, + gui_windows, + gpu_main_display_tube.clone(), + close_requested_event, + ) + }, + ) { Ok(dispatcher) => { info!("WndProc thread entering message loop"); message_loop_state.store(MessageLoopState::Running as i32, Ordering::SeqCst); @@ -542,7 +542,7 @@ impl WindowProcedureThread { /// # Safety /// The owner of the returned window objects is responsible for dropping them before we finish /// processing `WM_NCDESTROY`, because the window handle will become invalid afterwards. - unsafe fn create_windows() -> Result<(MessageOnlyWindow, Vec<GuiWindow>)> { + unsafe fn create_windows(max_num_windows: u32) -> Result<(MessageOnlyWindow, Vec<GuiWindow>)> { let message_router_window = MessageOnlyWindow::new( /* class_name */ Self::get_window_class_name::<MessageOnlyWindow>() @@ -559,10 +559,10 @@ impl WindowProcedureThread { // window may use the background brush to clear the gfxstream window client area when // drawing occurs. This caused the screen flickering issue during resizing. // See b/197786842 for details. - let mut gui_windows = Vec::with_capacity(MAX_NUM_WINDOWS); - for scanout_id in 0..MAX_NUM_WINDOWS { + let mut gui_windows = Vec::with_capacity(max_num_windows as usize); + for scanout_id in 0..max_num_windows { gui_windows.push(GuiWindow::new( - scanout_id as u32, + scanout_id, /* class_name */ Self::get_window_class_name::<GuiWindow>() .with_context(|| { @@ -650,12 +650,18 @@ unsafe impl Send for WindowProcedureThread {} #[derive(Deserialize, Serialize)] pub struct WindowProcedureThreadBuilder { + max_num_windows: u32, display_tube: Option<Tube>, #[cfg(feature = "kiwi")] ime_tube: Option<Tube>, } impl WindowProcedureThreadBuilder { + pub fn set_max_num_windows(&mut self, max_num_windows: u32) -> &mut Self { + self.max_num_windows = max_num_windows; + self + } + pub fn set_display_tube(&mut self, display_tube: Option<Tube>) -> &mut Self { self.display_tube = display_tube; self @@ -675,10 +681,16 @@ impl WindowProcedureThreadBuilder { pub fn start_thread(self) -> Result<WindowProcedureThread> { cfg_if::cfg_if! { if #[cfg(feature = "kiwi")] { - let ime_tube = self.ime_tube.ok_or_else(|| anyhow!("The ime tube is not set."))?; - WindowProcedureThread::start_thread(self.display_tube, ime_tube) + let ime_tube = self + .ime_tube + .ok_or_else(|| anyhow!("The ime tube is not set."))?; + WindowProcedureThread::start_thread( + self.max_num_windows, + self.display_tube, + ime_tube, + ) } else { - WindowProcedureThread::start_thread(None) + WindowProcedureThread::start_thread(self.max_num_windows, None) } } } diff --git a/gpu_display/src/gpu_display_wl.rs b/gpu_display/src/gpu_display_wl.rs index 61a7f9b9b..c163ee7ed 100644 --- a/gpu_display/src/gpu_display_wl.rs +++ b/gpu_display/src/gpu_display_wl.rs @@ -32,6 +32,7 @@ use base::VolatileMemory; use dwl::*; use linux_input_sys::virtio_input_event; use sync::Waitable; +use vm_control::gpu::DisplayParameters; use crate::DisplayExternalResourceImport; use crate::DisplayT; @@ -376,12 +377,12 @@ impl DisplayT for DisplayWl { parent_surface_id: Option<u32>, surface_id: u32, scanout_id: Option<u32>, - width: u32, - height: u32, + display_params: &DisplayParameters, surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { let parent_id = parent_surface_id.unwrap_or(0); + let (width, height) = display_params.get_virtual_display_size(); let row_size = width * BYTES_PER_PIXEL; let fb_size = row_size * height; let buffer_size = round_up_to_page_size(fb_size as usize * BUFFER_COUNT); diff --git a/gpu_display/src/gpu_display_x.rs b/gpu_display/src/gpu_display_x.rs index 0cd720c94..f7560a1e9 100644 --- a/gpu_display/src/gpu_display_x.rs +++ b/gpu_display/src/gpu_display_x.rs @@ -34,6 +34,7 @@ use libc::IPC_CREAT; use libc::IPC_PRIVATE; use libc::IPC_RMID; use linux_input_sys::virtio_input_event; +use vm_control::gpu::DisplayParameters; use crate::keycode_converter::KeycodeTranslator; use crate::keycode_converter::KeycodeTypes; @@ -699,8 +700,7 @@ impl DisplayT for DisplayX { parent_surface_id: Option<u32>, _surface_id: u32, _scanout_id: Option<u32>, - width: u32, - height: u32, + display_params: &DisplayParameters, _surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { if parent_surface_id.is_some() { @@ -710,6 +710,7 @@ impl DisplayT for DisplayX { // TODO(b/315870313): Add safety comment #[allow(clippy::undocumented_unsafe_blocks)] unsafe { + let (width, height) = display_params.get_virtual_display_size(); let depth = xlib::XDefaultDepthOfScreen(self.screen.as_ptr()) as u32; let black_pixel = xlib::XBlackPixelOfScreen(self.screen.as_ptr()); diff --git a/gpu_display/src/lib.rs b/gpu_display/src/lib.rs index 662575fed..49656fbb5 100644 --- a/gpu_display/src/lib.rs +++ b/gpu_display/src/lib.rs @@ -22,6 +22,7 @@ use serde::Deserialize; use serde::Serialize; use sync::Waitable; use thiserror::Error; +use vm_control::gpu::DisplayParameters; use vm_control::gpu::MouseMode; #[cfg(feature = "vulkan_display")] use vulkano::VulkanLibrary; @@ -47,8 +48,6 @@ pub mod vulkan; pub use event_device::EventDevice; pub use event_device::EventDeviceKind; #[cfg(windows)] -pub use gpu_display_win::DisplayProperties as WinDisplayProperties; -#[cfg(windows)] pub use gpu_display_win::WindowProcedureThread; #[cfg(windows)] pub use gpu_display_win::WindowProcedureThreadBuilder; @@ -319,8 +318,7 @@ trait DisplayT: AsRawDescriptor { parent_surface_id: Option<u32>, surface_id: u32, scanout_id: Option<u32>, - width: u32, - height: u32, + display_params: &DisplayParameters, surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>>; @@ -564,8 +562,7 @@ impl GpuDisplay { &mut self, parent_surface_id: Option<u32>, scanout_id: Option<u32>, - width: u32, - height: u32, + display_params: &DisplayParameters, surf_type: SurfaceType, ) -> GpuDisplayResult<u32> { if let Some(parent_id) = parent_surface_id { @@ -579,8 +576,7 @@ impl GpuDisplay { parent_surface_id, new_surface_id, scanout_id, - width, - height, + display_params, surf_type, )?; diff --git a/gpu_display/src/sys/windows.rs b/gpu_display/src/sys/windows.rs index 96ad10693..bb9feb44c 100644 --- a/gpu_display/src/sys/windows.rs +++ b/gpu_display/src/sys/windows.rs @@ -11,7 +11,6 @@ use base::SendTube; use base::WaitContext; use metrics::sys::windows::Metrics; -use crate::gpu_display_win::DisplayProperties; use crate::gpu_display_win::DisplayWin; use crate::DisplayEventToken; use crate::DisplayT; @@ -65,7 +64,6 @@ pub trait WinGpuDisplayExt { fn open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option<Weak<Metrics>>, - display_properties: DisplayProperties, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option<VulkanCreateParams>, ) -> GpuDisplayResult<GpuDisplay>; @@ -75,14 +73,12 @@ impl WinGpuDisplayExt for GpuDisplay { fn open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option<Weak<Metrics>>, - display_properties: DisplayProperties, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option<VulkanCreateParams>, ) -> GpuDisplayResult<GpuDisplay> { let display = DisplayWin::new( wndproc_thread, win_metrics, - display_properties, gpu_display_wait_descriptor_ctrl, vulkan_display_create_params, )?; |