mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-09 03:57:24 +00:00
gpu_display: sync with downstream code.
Notable changes: 1. Use "W" methods during window creation and message dispatching to ensure unicode characters are sent to the window. 2. In DisplayEventDispatcher::dispatch(), filter() and map() will be ignored if we don't call collect(). We replace map() with a for loop to make this clearer. Other changes are due to linter/formatter warnings, etc. Bug=b:213150276 TEST=cargo b -p gpu_display --features win64 --no-default-features Change-Id: I767aec208d8afd7d7cb86039d08ba8ec8369da81 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3913991 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Pujun Lun <lunpujun@google.com>
This commit is contained in:
parent
51f9faf3a4
commit
26d9803ccb
5 changed files with 51 additions and 62 deletions
|
@ -209,12 +209,11 @@ impl DisplayT for DisplayWin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let display_closed_event = self.display_closed_event.try_clone().map_err(|e| {
|
|
||||||
error!("Failed to clone display_closed_event: {}", e);
|
|
||||||
GpuDisplayError::Allocate
|
|
||||||
})?;
|
|
||||||
Ok(Box::new(SurfaceWin {
|
Ok(Box::new(SurfaceWin {
|
||||||
display_closed_event,
|
display_closed_event: self.display_closed_event.try_clone().map_err(|e| {
|
||||||
|
error!("Failed to clone display_closed_event: {}", e);
|
||||||
|
GpuDisplayError::Allocate
|
||||||
|
})?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
@ -23,6 +22,7 @@ use euclid::Size2D;
|
||||||
use vm_control::display::WindowVisibility;
|
use vm_control::display::WindowVisibility;
|
||||||
use win_util::syscall_bail;
|
use win_util::syscall_bail;
|
||||||
use win_util::win32_string;
|
use win_util::win32_string;
|
||||||
|
use win_util::win32_wide_string;
|
||||||
use winapi::shared::minwindef::DWORD;
|
use winapi::shared::minwindef::DWORD;
|
||||||
use winapi::shared::minwindef::FALSE;
|
use winapi::shared::minwindef::FALSE;
|
||||||
use winapi::shared::minwindef::HINSTANCE;
|
use winapi::shared::minwindef::HINSTANCE;
|
||||||
|
@ -123,10 +123,7 @@ impl Window {
|
||||||
info!("Creating window");
|
info!("Creating window");
|
||||||
static CONTEXT_MESSAGE: &str = "When creating Window";
|
static CONTEXT_MESSAGE: &str = "When creating Window";
|
||||||
|
|
||||||
let class_name = win32_string(class_name);
|
|
||||||
let title = win32_string(title);
|
|
||||||
let hinstance = Self::get_current_module_handle();
|
let hinstance = Self::get_current_module_handle();
|
||||||
|
|
||||||
// If we fail to load any UI element below, use NULL to let the system use the default UI
|
// If we fail to load any UI element below, use NULL to let the system use the default UI
|
||||||
// rather than crash.
|
// rather than crash.
|
||||||
let hicon = Self::load_custom_icon(hinstance, icon_resource_id).unwrap_or(null_mut());
|
let hicon = Self::load_custom_icon(hinstance, icon_resource_id).unwrap_or(null_mut());
|
||||||
|
@ -136,21 +133,16 @@ impl Window {
|
||||||
Self::register_window_class(
|
Self::register_window_class(
|
||||||
wnd_proc,
|
wnd_proc,
|
||||||
hinstance,
|
hinstance,
|
||||||
&class_name,
|
class_name,
|
||||||
hicon,
|
hicon,
|
||||||
hcursor,
|
hcursor,
|
||||||
hbrush_background,
|
hbrush_background,
|
||||||
)
|
)
|
||||||
.context(CONTEXT_MESSAGE)?;
|
.context(CONTEXT_MESSAGE)?;
|
||||||
|
|
||||||
let hwnd = Self::create_sys_window(
|
let hwnd =
|
||||||
hinstance,
|
Self::create_sys_window(hinstance, class_name, title, dw_style, initial_window_size)
|
||||||
&class_name,
|
.context(CONTEXT_MESSAGE)?;
|
||||||
&title,
|
|
||||||
dw_style,
|
|
||||||
initial_window_size,
|
|
||||||
)
|
|
||||||
.context(CONTEXT_MESSAGE)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
hwnd,
|
hwnd,
|
||||||
|
@ -339,7 +331,7 @@ impl Window {
|
||||||
/// Calls `MonitorFromWindow()` internally.
|
/// Calls `MonitorFromWindow()` internally.
|
||||||
pub fn is_on_active_display(&self) -> bool {
|
pub fn is_on_active_display(&self) -> bool {
|
||||||
// Safe because `Window` object won't outlive the HWND.
|
// Safe because `Window` object won't outlive the HWND.
|
||||||
unsafe { MonitorFromWindow(self.hwnd, MONITOR_DEFAULTTONULL) != null_mut() }
|
unsafe { !MonitorFromWindow(self.hwnd, MONITOR_DEFAULTTONULL).is_null() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `SetWindowPos()` internally.
|
/// Calls `SetWindowPos()` internally.
|
||||||
|
@ -499,8 +491,10 @@ impl Window {
|
||||||
|
|
||||||
/// Calls `GetWindowPlacement()` and `SetWindowPlacement()` internally.
|
/// Calls `GetWindowPlacement()` and `SetWindowPlacement()` internally.
|
||||||
pub fn set_restored_pos(&self, window_rect: &Rect) -> Result<()> {
|
pub fn set_restored_pos(&self, window_rect: &Rect) -> Result<()> {
|
||||||
let mut window_placement: WINDOWPLACEMENT = Default::default();
|
let mut window_placement = WINDOWPLACEMENT {
|
||||||
window_placement.length = mem::size_of::<WINDOWPLACEMENT>().try_into().unwrap();
|
length: mem::size_of::<WINDOWPLACEMENT>().try_into().unwrap(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
// Safe because `Window` object won't outlive the HWND, we know `window_placement` is valid,
|
// Safe because `Window` object won't outlive the HWND, we know `window_placement` is valid,
|
||||||
// and failures are handled below.
|
// and failures are handled below.
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -596,13 +590,13 @@ impl Window {
|
||||||
fn register_window_class(
|
fn register_window_class(
|
||||||
wnd_proc: WNDPROC,
|
wnd_proc: WNDPROC,
|
||||||
hinstance: HINSTANCE,
|
hinstance: HINSTANCE,
|
||||||
class_name: &CString,
|
class_name: &str,
|
||||||
hicon: HICON,
|
hicon: HICON,
|
||||||
hcursor: HCURSOR,
|
hcursor: HCURSOR,
|
||||||
hbrush_background: HBRUSH,
|
hbrush_background: HBRUSH,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_class = WNDCLASSEXA {
|
let window_class = WNDCLASSEXW {
|
||||||
cbSize: std::mem::size_of::<WNDCLASSEXA>() as u32,
|
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
|
||||||
style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
||||||
lpfnWndProc: wnd_proc,
|
lpfnWndProc: wnd_proc,
|
||||||
cbClsExtra: 0,
|
cbClsExtra: 0,
|
||||||
|
@ -612,14 +606,14 @@ impl Window {
|
||||||
hCursor: hcursor,
|
hCursor: hcursor,
|
||||||
hbrBackground: hbrush_background,
|
hbrBackground: hbrush_background,
|
||||||
lpszMenuName: null_mut(),
|
lpszMenuName: null_mut(),
|
||||||
lpszClassName: class_name.as_ptr(),
|
lpszClassName: win32_wide_string(class_name).as_ptr(),
|
||||||
hIconSm: hicon,
|
hIconSm: hicon,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safe because we know the lifetime of `window_class`, and we handle failures below.
|
// Safe because we know the lifetime of `window_class`, and we handle failures below.
|
||||||
unsafe {
|
unsafe {
|
||||||
if RegisterClassExA(&window_class) == 0 {
|
if RegisterClassExW(&window_class) == 0 {
|
||||||
syscall_bail!("Failed to call RegisterClassExA()");
|
syscall_bail!("Failed to call RegisterClassExW()");
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -627,17 +621,17 @@ impl Window {
|
||||||
|
|
||||||
fn create_sys_window(
|
fn create_sys_window(
|
||||||
hinstance: HINSTANCE,
|
hinstance: HINSTANCE,
|
||||||
class_name: &CString,
|
class_name: &str,
|
||||||
title: &CString,
|
title: &str,
|
||||||
dw_style: DWORD,
|
dw_style: DWORD,
|
||||||
initial_window_size: &Size2D<i32, HostWindowSpace>,
|
initial_window_size: &Size2D<i32, HostWindowSpace>,
|
||||||
) -> Result<HWND> {
|
) -> Result<HWND> {
|
||||||
// Safe because we handle failures below.
|
// Safe because we handle failures below.
|
||||||
unsafe {
|
unsafe {
|
||||||
let hwnd = CreateWindowExA(
|
let hwnd = CreateWindowExW(
|
||||||
0,
|
0,
|
||||||
class_name.as_ptr(),
|
win32_wide_string(class_name).as_ptr(),
|
||||||
title.as_ptr(),
|
win32_wide_string(title).as_ptr(),
|
||||||
dw_style,
|
dw_style,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -648,8 +642,8 @@ impl Window {
|
||||||
hinstance,
|
hinstance,
|
||||||
null_mut(),
|
null_mut(),
|
||||||
);
|
);
|
||||||
if hwnd == null_mut() {
|
if hwnd.is_null() {
|
||||||
syscall_bail!("Failed to call CreateWindowExA()");
|
syscall_bail!("Failed to call CreateWindowExW()");
|
||||||
}
|
}
|
||||||
Ok(hwnd)
|
Ok(hwnd)
|
||||||
}
|
}
|
||||||
|
@ -692,8 +686,10 @@ impl MonitorInfo {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Caller is responsible for ensuring that `hmonitor` is a valid handle.
|
/// Caller is responsible for ensuring that `hmonitor` is a valid handle.
|
||||||
unsafe fn get_monitor_info(hmonitor: HMONITOR) -> Result<MONITORINFO> {
|
unsafe fn get_monitor_info(hmonitor: HMONITOR) -> Result<MONITORINFO> {
|
||||||
let mut monitor_info: MONITORINFO = Default::default();
|
let mut monitor_info = MONITORINFO {
|
||||||
monitor_info.cbSize = mem::size_of::<MONITORINFO>().try_into().unwrap();
|
cbSize: mem::size_of::<MONITORINFO>().try_into().unwrap(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
if GetMonitorInfoA(hmonitor, &mut monitor_info) == 0 {
|
if GetMonitorInfoA(hmonitor, &mut monitor_info) == 0 {
|
||||||
syscall_bail!("Failed to call GetMonitorInfoA()");
|
syscall_bail!("Failed to call GetMonitorInfoA()");
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,16 +47,16 @@ impl DisplayEventDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch(&self, events: &[virtio_input_event], device_type: EventDeviceKind) {
|
pub fn dispatch(&self, events: &[virtio_input_event], device_type: EventDeviceKind) {
|
||||||
let _ = self
|
for event_device in self
|
||||||
.event_devices
|
.event_devices
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.iter_mut()
|
.values_mut()
|
||||||
.filter(|(_, event_device)| event_device.kind() == device_type)
|
.filter(|event_device| event_device.kind() == device_type)
|
||||||
.map(|(_, event_device)| {
|
{
|
||||||
if let Err(e) = event_device.send_report(events.iter().cloned()) {
|
if let Err(e) = event_device.send_report(events.iter().cloned()) {
|
||||||
error!("Failed to send events to event device: {}", e);
|
error!("Failed to send events to event device: {}", e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_event_device(&mut self, event_device_id: ObjectId, event_device: EventDevice) {
|
fn import_event_device(&mut self, event_device_id: ObjectId, event_device: EventDevice) {
|
||||||
|
@ -187,7 +187,7 @@ impl<T: HandleWindowMessage> WindowMessageDispatcher<T> {
|
||||||
}
|
}
|
||||||
None => debug!("No window to destroy on WndProc thread drop"),
|
None => debug!("No window to destroy on WndProc thread drop"),
|
||||||
},
|
},
|
||||||
// Safe because we are processing a message tageting this thread.
|
// Safe because we are processing a message targeting this thread.
|
||||||
_ => unsafe {
|
_ => unsafe {
|
||||||
DefWindowProcA(null_mut(), msg, w_param, l_param);
|
DefWindowProcA(null_mut(), msg, w_param, l_param);
|
||||||
},
|
},
|
||||||
|
|
|
@ -82,9 +82,6 @@ pub trait HandleWindowMessage {
|
||||||
/// Called when processing `WM_SETFOCUS`.
|
/// Called when processing `WM_SETFOCUS`.
|
||||||
fn on_set_focus(&mut self) {}
|
fn on_set_focus(&mut self) {}
|
||||||
|
|
||||||
/// Called when processing `WM_KILLFOCUS`.
|
|
||||||
fn on_kill_focus(&mut self) {}
|
|
||||||
|
|
||||||
/// Called when processing `WM_INPUT`.
|
/// Called when processing `WM_INPUT`.
|
||||||
fn on_raw_input(&mut self, _window: &Window, _l_param: LPARAM) {}
|
fn on_raw_input(&mut self, _window: &Window, _l_param: LPARAM) {}
|
||||||
|
|
||||||
|
@ -92,7 +89,7 @@ pub trait HandleWindowMessage {
|
||||||
fn on_mouse_move(&mut self, _w_param: WPARAM, _l_param: LPARAM) {}
|
fn on_mouse_move(&mut self, _w_param: WPARAM, _l_param: LPARAM) {}
|
||||||
|
|
||||||
/// Called when processing `WM_LBUTTONDOWN` and `WM_LBUTTONUP`.
|
/// Called when processing `WM_LBUTTONDOWN` and `WM_LBUTTONUP`.
|
||||||
fn on_mouse_button_left(&mut self, _is_down: bool, _l_param: LPARAM) {}
|
fn on_mouse_button_left(&mut self, _window: &Window, _is_down: bool, _l_param: LPARAM) {}
|
||||||
|
|
||||||
/// Called when processing `WM_RBUTTONDOWN` and `WM_RBUTTONUP`.
|
/// Called when processing `WM_RBUTTONDOWN` and `WM_RBUTTONUP`.
|
||||||
fn on_mouse_button_right(&mut self, _is_down: bool) {}
|
fn on_mouse_button_right(&mut self, _is_down: bool) {}
|
||||||
|
@ -225,10 +222,6 @@ impl<T: HandleWindowMessage> WindowMessageProcessor<T> {
|
||||||
handler.on_set_focus();
|
handler.on_set_focus();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
WM_KILLFOCUS => {
|
|
||||||
handler.on_kill_focus();
|
|
||||||
0
|
|
||||||
}
|
|
||||||
WM_INPUT => {
|
WM_INPUT => {
|
||||||
handler.on_raw_input(&self.window, l_param);
|
handler.on_raw_input(&self.window, l_param);
|
||||||
self.window.default_process_message(packet)
|
self.window.default_process_message(packet)
|
||||||
|
@ -238,7 +231,8 @@ impl<T: HandleWindowMessage> WindowMessageProcessor<T> {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
WM_LBUTTONDOWN | WM_LBUTTONUP => {
|
WM_LBUTTONDOWN | WM_LBUTTONUP => {
|
||||||
handler.on_mouse_button_left(/* is_down= */ msg == WM_LBUTTONDOWN, l_param);
|
let is_down = msg == WM_LBUTTONDOWN;
|
||||||
|
handler.on_mouse_button_left(&self.window, is_down, l_param);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
WM_RBUTTONDOWN | WM_RBUTTONUP => {
|
WM_RBUTTONDOWN | WM_RBUTTONUP => {
|
||||||
|
|
|
@ -175,7 +175,7 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
||||||
loop {
|
loop {
|
||||||
let mut message = mem::MaybeUninit::uninit();
|
let mut message = mem::MaybeUninit::uninit();
|
||||||
// Safe because we know the lifetime of `message`.
|
// Safe because we know the lifetime of `message`.
|
||||||
match unsafe { GetMessageA(message.as_mut_ptr(), null_mut(), 0, 0) } {
|
match unsafe { GetMessageW(message.as_mut_ptr(), null_mut(), 0, 0) } {
|
||||||
0 => {
|
0 => {
|
||||||
info!("WndProc thread exiting message loop since WM_QUIT is received");
|
info!("WndProc thread exiting message loop since WM_QUIT is received");
|
||||||
message_loop_state
|
message_loop_state
|
||||||
|
@ -184,7 +184,7 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
||||||
}
|
}
|
||||||
-1 => {
|
-1 => {
|
||||||
error!(
|
error!(
|
||||||
"WndProc thread exiting message loop because GetMessageA() failed with \
|
"WndProc thread exiting message loop because GetMessageW() failed with \
|
||||||
error code {}",
|
error code {}",
|
||||||
unsafe { GetLastError() }
|
unsafe { GetLastError() }
|
||||||
);
|
);
|
||||||
|
@ -195,19 +195,19 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe because `GetMessageA()` will block until `message` is populated.
|
// Safe because `GetMessageW()` will block until `message` is populated.
|
||||||
let new_message = unsafe { message.assume_init() };
|
let new_message = unsafe { message.assume_init() };
|
||||||
if new_message.hwnd == null_mut() {
|
if new_message.hwnd.is_null() {
|
||||||
// Thread messages don't target a specific window and `DispatchMessageA()` won't
|
// Thread messages don't target a specific window and `DispatchMessageA()` won't
|
||||||
// send them to `wnd_proc()` function, hence we need to handle it as a special case.
|
// send them to `wnd_proc()` function, hence we need to handle it as a special case.
|
||||||
dispatcher
|
dispatcher
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.process_thread_message(&new_message.into());
|
.process_thread_message(&new_message.into());
|
||||||
} else {
|
} else {
|
||||||
// Safe because `GetMessageA()` will block until `message` is populated.
|
// Safe because `GetMessageW()` will block until `message` is populated.
|
||||||
unsafe {
|
unsafe {
|
||||||
TranslateMessage(&new_message);
|
TranslateMessage(&new_message);
|
||||||
DispatchMessageA(&new_message);
|
DispatchMessageW(&new_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,8 +266,8 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
||||||
/// processing `WM_NCDESTROY`, because the window handle will become invalid afterwards.
|
/// processing `WM_NCDESTROY`, because the window handle will become invalid afterwards.
|
||||||
unsafe fn create_window() -> Result<Window> {
|
unsafe fn create_window() -> Result<Window> {
|
||||||
// Gfxstream window is a child window of CrosVM window. Without WS_CLIPCHILDREN, the parent
|
// Gfxstream window is a child window of CrosVM window. Without WS_CLIPCHILDREN, the parent
|
||||||
// window may use the background brush to clear the gfxstream window client area when drawing
|
// window may use the background brush to clear the gfxstream window client area when
|
||||||
// occurs. This caused the screen flickering issue during resizing.
|
// drawing occurs. This caused the screen flickering issue during resizing.
|
||||||
// See b/197786842 for details.
|
// See b/197786842 for details.
|
||||||
let dw_style = WS_POPUP | WS_CLIPCHILDREN;
|
let dw_style = WS_POPUP | WS_CLIPCHILDREN;
|
||||||
Window::new(
|
Window::new(
|
||||||
|
|
Loading…
Reference in a new issue