On windows, recreate renderer swap chain on restore from minimized (#21756)
Closes #21688 Release Notes: - Windows: Fix freeze after window minimize and maximize
This commit is contained in:
parent
adc66473e7
commit
ab1e9bf270
3 changed files with 29 additions and 3 deletions
|
@ -431,13 +431,25 @@ impl BladeRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_drawable_size(&mut self, size: Size<DevicePixels>) {
|
pub fn update_drawable_size(&mut self, size: Size<DevicePixels>) {
|
||||||
|
self.update_drawable_size_impl(size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Like `update_drawable_size` but skips the check that the size has changed. This is useful in
|
||||||
|
/// cases like restoring a window from minimization where the size is the same but the
|
||||||
|
/// renderer's swap chain needs to be recreated.
|
||||||
|
#[cfg_attr(any(target_os = "macos", target_os = "linux"), allow(dead_code))]
|
||||||
|
pub fn update_drawable_size_even_if_unchanged(&mut self, size: Size<DevicePixels>) {
|
||||||
|
self.update_drawable_size_impl(size, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_drawable_size_impl(&mut self, size: Size<DevicePixels>, always_resize: bool) {
|
||||||
let gpu_size = gpu::Extent {
|
let gpu_size = gpu::Extent {
|
||||||
width: size.width.0 as u32,
|
width: size.width.0 as u32,
|
||||||
height: size.height.0 as u32,
|
height: size.height.0 as u32,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
if gpu_size != self.surface_config.size {
|
if always_resize || gpu_size != self.surface_config.size {
|
||||||
self.wait_for_gpu();
|
self.wait_for_gpu();
|
||||||
self.surface_config.size = gpu_size;
|
self.surface_config.size = gpu_size;
|
||||||
self.gpu.resize(self.surface_config);
|
self.gpu.resize(self.surface_config);
|
||||||
|
|
|
@ -141,16 +141,27 @@ fn handle_size_msg(
|
||||||
lparam: LPARAM,
|
lparam: LPARAM,
|
||||||
state_ptr: Rc<WindowsWindowStatePtr>,
|
state_ptr: Rc<WindowsWindowStatePtr>,
|
||||||
) -> Option<isize> {
|
) -> Option<isize> {
|
||||||
|
let mut lock = state_ptr.state.borrow_mut();
|
||||||
|
|
||||||
|
// Don't resize the renderer when the window is minimized, but record that it was minimized so
|
||||||
|
// that on restore the swap chain can be recreated via `update_drawable_size_even_if_unchanged`.
|
||||||
if wparam.0 == SIZE_MINIMIZED as usize {
|
if wparam.0 == SIZE_MINIMIZED as usize {
|
||||||
|
lock.is_minimized = Some(true);
|
||||||
return Some(0);
|
return Some(0);
|
||||||
}
|
}
|
||||||
|
let may_have_been_minimized = lock.is_minimized.unwrap_or(true);
|
||||||
|
lock.is_minimized = Some(false);
|
||||||
|
|
||||||
let width = lparam.loword().max(1) as i32;
|
let width = lparam.loword().max(1) as i32;
|
||||||
let height = lparam.hiword().max(1) as i32;
|
let height = lparam.hiword().max(1) as i32;
|
||||||
let mut lock = state_ptr.state.borrow_mut();
|
|
||||||
let new_size = size(DevicePixels(width), DevicePixels(height));
|
let new_size = size(DevicePixels(width), DevicePixels(height));
|
||||||
let scale_factor = lock.scale_factor;
|
let scale_factor = lock.scale_factor;
|
||||||
|
if may_have_been_minimized {
|
||||||
|
lock.renderer
|
||||||
|
.update_drawable_size_even_if_unchanged(new_size);
|
||||||
|
} else {
|
||||||
lock.renderer.update_drawable_size(new_size);
|
lock.renderer.update_drawable_size(new_size);
|
||||||
|
}
|
||||||
let new_size = new_size.to_pixels(scale_factor);
|
let new_size = new_size.to_pixels(scale_factor);
|
||||||
lock.logical_size = new_size;
|
lock.logical_size = new_size;
|
||||||
if let Some(mut callback) = lock.callbacks.resize.take() {
|
if let Some(mut callback) = lock.callbacks.resize.take() {
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub struct WindowsWindowState {
|
||||||
pub fullscreen_restore_bounds: Bounds<Pixels>,
|
pub fullscreen_restore_bounds: Bounds<Pixels>,
|
||||||
pub border_offset: WindowBorderOffset,
|
pub border_offset: WindowBorderOffset,
|
||||||
pub scale_factor: f32,
|
pub scale_factor: f32,
|
||||||
|
pub is_minimized: Option<bool>,
|
||||||
|
|
||||||
pub callbacks: Callbacks,
|
pub callbacks: Callbacks,
|
||||||
pub input_handler: Option<PlatformInputHandler>,
|
pub input_handler: Option<PlatformInputHandler>,
|
||||||
|
@ -92,6 +93,7 @@ impl WindowsWindowState {
|
||||||
size: logical_size,
|
size: logical_size,
|
||||||
};
|
};
|
||||||
let border_offset = WindowBorderOffset::default();
|
let border_offset = WindowBorderOffset::default();
|
||||||
|
let is_minimized = None;
|
||||||
let renderer = windows_renderer::windows_renderer(hwnd, transparent)?;
|
let renderer = windows_renderer::windows_renderer(hwnd, transparent)?;
|
||||||
let callbacks = Callbacks::default();
|
let callbacks = Callbacks::default();
|
||||||
let input_handler = None;
|
let input_handler = None;
|
||||||
|
@ -109,6 +111,7 @@ impl WindowsWindowState {
|
||||||
fullscreen_restore_bounds,
|
fullscreen_restore_bounds,
|
||||||
border_offset,
|
border_offset,
|
||||||
scale_factor,
|
scale_factor,
|
||||||
|
is_minimized,
|
||||||
callbacks,
|
callbacks,
|
||||||
input_handler,
|
input_handler,
|
||||||
system_key_handled,
|
system_key_handled,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue