// 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. use std::sync::Weak; use base::AsRawDescriptor; use base::RawDescriptor; use base::ReadNotifier; use base::SendTube; use base::WaitContext; use metrics::sys::windows::Metrics; use crate::gpu_display_win::DisplayWin; use crate::DisplayEventToken; use crate::DisplayT; use crate::EventDevice; use crate::GpuDisplay; use crate::GpuDisplayExt; use crate::GpuDisplayResult; use crate::VulkanCreateParams; use crate::WindowProcedureThread; pub(crate) trait WinDisplayT: DisplayT { /// Imports an event device into the display backend. fn import_event_device( &mut self, _event_device_id: u32, _event_device: EventDevice, ) -> GpuDisplayResult<()> { Ok(()) } /// Called when the given event device is readable; in other words, when the guest sends data /// to the host (e.g. to set the numlock LED on/off). fn handle_event_device(&mut self, _event_device_id: u32) {} } impl GpuDisplayExt for GpuDisplay { fn import_event_device(&mut self, event_device: EventDevice) -> GpuDisplayResult { let new_event_device_id = self.next_id; // Safety (even though it's technically "safe"): event_device is owned by self.inner, and // will live until self.inner is dropped. self.wait_ctx.add( event_device.get_read_notifier(), DisplayEventToken::EventDevice { event_device_id: new_event_device_id, }, )?; self.inner .import_event_device(new_event_device_id, event_device)?; self.next_id += 1; Ok(new_event_device_id) } fn handle_event_device(&mut self, event_device_id: u32) { self.inner.handle_event_device(event_device_id); } } pub trait WinGpuDisplayExt { fn open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option>, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option, ) -> GpuDisplayResult; } impl WinGpuDisplayExt for GpuDisplay { fn open_winapi( wndproc_thread: WindowProcedureThread, win_metrics: Option>, gpu_display_wait_descriptor_ctrl: SendTube, vulkan_display_create_params: Option, ) -> GpuDisplayResult { let display = DisplayWin::new( wndproc_thread, win_metrics, gpu_display_wait_descriptor_ctrl, vulkan_display_create_params, )?; let wait_ctx = WaitContext::new()?; wait_ctx.add(&display, DisplayEventToken::Display)?; Ok(GpuDisplay { inner: Box::new(display), next_id: 1, event_devices: Default::default(), surfaces: Default::default(), wait_ctx, }) } } impl AsRawDescriptor for GpuDisplay { fn as_raw_descriptor(&self) -> RawDescriptor { self.inner.as_raw_descriptor() } }