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