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 use std::sync::Weak; 6 7 use base::AsRawDescriptor; 8 use base::RawDescriptor; 9 use base::ReadNotifier; 10 use base::SendTube; 11 use base::WaitContext; 12 use metrics::sys::windows::Metrics; 13 14 use crate::gpu_display_win::DisplayWin; 15 use crate::DisplayEventToken; 16 use crate::DisplayT; 17 use crate::EventDevice; 18 use crate::GpuDisplay; 19 use crate::GpuDisplayExt; 20 use crate::GpuDisplayResult; 21 use crate::VulkanCreateParams; 22 use crate::WindowProcedureThread; 23 24 pub(crate) trait WinDisplayT: DisplayT { 25 /// Imports an event device into the display backend. import_event_device( &mut self, _event_device_id: u32, _event_device: EventDevice, ) -> GpuDisplayResult<()>26 fn import_event_device( 27 &mut self, 28 _event_device_id: u32, 29 _event_device: EventDevice, 30 ) -> GpuDisplayResult<()> { 31 Ok(()) 32 } 33 34 /// Called when the given event device is readable; in other words, when the guest sends data 35 /// to the host (e.g. to set the numlock LED on/off). handle_event_device(&mut self, _event_device_id: u32)36 fn handle_event_device(&mut self, _event_device_id: u32) {} 37 } 38 39 impl GpuDisplayExt for GpuDisplay { import_event_device(&mut self, event_device: EventDevice) -> GpuDisplayResult<u32>40 fn import_event_device(&mut self, event_device: EventDevice) -> GpuDisplayResult<u32> { 41 let new_event_device_id = self.next_id; 42 43 // Safety (even though it's technically "safe"): event_device is owned by self.inner, and 44 // will live until self.inner is dropped. 45 self.wait_ctx.add( 46 event_device.get_read_notifier(), 47 DisplayEventToken::EventDevice { 48 event_device_id: new_event_device_id, 49 }, 50 )?; 51 self.inner 52 .import_event_device(new_event_device_id, event_device)?; 53 54 self.next_id += 1; 55 Ok(new_event_device_id) 56 } 57 handle_event_device(&mut self, event_device_id: u32)58 fn handle_event_device(&mut self, event_device_id: u32) { 59 self.inner.handle_event_device(event_device_id); 60 } 61 } 62 63 pub trait WinGpuDisplayExt { open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option<Weak<Metrics>>, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option<VulkanCreateParams>, ) -> GpuDisplayResult<GpuDisplay>64 fn open_winapi( 65 wndproc_thread: WindowProcedureThread, 66 win_metrics: Option<Weak<Metrics>>, 67 gpu_display_wait_descriptor_ctrl: SendTube, 68 vulkan_display_create_params: Option<VulkanCreateParams>, 69 ) -> GpuDisplayResult<GpuDisplay>; 70 } 71 72 impl WinGpuDisplayExt for GpuDisplay { open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option<Weak<Metrics>>, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option<VulkanCreateParams>, ) -> GpuDisplayResult<GpuDisplay>73 fn open_winapi( 74 wndproc_thread: WindowProcedureThread, 75 win_metrics: Option<Weak<Metrics>>, 76 gpu_display_wait_descriptor_ctrl: SendTube, 77 vulkan_display_create_params: Option<VulkanCreateParams>, 78 ) -> GpuDisplayResult<GpuDisplay> { 79 let display = DisplayWin::new( 80 wndproc_thread, 81 win_metrics, 82 gpu_display_wait_descriptor_ctrl, 83 vulkan_display_create_params, 84 )?; 85 86 let wait_ctx = WaitContext::new()?; 87 wait_ctx.add(&display, DisplayEventToken::Display)?; 88 89 Ok(GpuDisplay { 90 inner: Box::new(display), 91 next_id: 1, 92 event_devices: Default::default(), 93 surfaces: Default::default(), 94 wait_ctx, 95 }) 96 } 97 } 98 99 impl AsRawDescriptor for GpuDisplay { as_raw_descriptor(&self) -> RawDescriptor100 fn as_raw_descriptor(&self) -> RawDescriptor { 101 self.inner.as_raw_descriptor() 102 } 103 } 104