Remove resize block on Windows (#634)

* Remove Windows block on resize

* Add CHANGELOG entry

* Move CHANGELOG entry to Unreleased

* Further edits to CHANGELOG entry
This commit is contained in:
Osspial 2018-08-24 13:48:57 -04:00 committed by Francesca Frangipane
parent 102ed3b800
commit a70bc20829
2 changed files with 4 additions and 49 deletions

View file

@ -1,6 +1,7 @@
# Unreleased # Unreleased
- Fixed graphical glitches when resizing on Wayland - Fixed graphical glitches when resizing on Wayland.
- On Windows, fix freezes when performing certain actions after a window resize has been triggered. Reintroduces some visual artifacts when resizing.
# Version 0.17.2 (2018-08-19) # Version 0.17.2 (2018-08-19)

View file

@ -18,7 +18,7 @@ use std::collections::HashMap;
use std::ffi::OsString; use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt; use std::os::windows::ffi::OsStringExt;
use std::os::windows::io::AsRawHandle; use std::os::windows::io::AsRawHandle;
use std::sync::{Arc, Barrier, Condvar, mpsc, Mutex}; use std::sync::{Arc, Barrier, mpsc, Mutex};
use winapi::ctypes::c_int; use winapi::ctypes::c_int;
use winapi::shared::minwindef::{ use winapi::shared::minwindef::{
@ -138,10 +138,6 @@ pub struct EventsLoop {
thread_id: DWORD, thread_id: DWORD,
// Receiver for the events. The sender is in the background thread. // Receiver for the events. The sender is in the background thread.
receiver: mpsc::Receiver<Event>, receiver: mpsc::Receiver<Event>,
// Variable that contains the block state of the win32 event loop thread during a WM_SIZE event.
// The mutex's value is `true` when it's blocked, and should be set to false when it's done
// blocking. That's done by the parent thread when it receives a Resized event.
win32_block_loop: Arc<(Mutex<bool>, Condvar)>,
} }
impl EventsLoop { impl EventsLoop {
@ -154,8 +150,6 @@ impl EventsLoop {
// The main events transfer channel. // The main events transfer channel.
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
let win32_block_loop = Arc::new((Mutex::new(false), Condvar::new()));
let win32_block_loop_child = win32_block_loop.clone();
// Local barrier in order to block the `new()` function until the background thread has // Local barrier in order to block the `new()` function until the background thread has
// an events queue. // an events queue.
@ -167,7 +161,6 @@ impl EventsLoop {
*context_stash.borrow_mut() = Some(ThreadLocalData { *context_stash.borrow_mut() = Some(ThreadLocalData {
sender: tx, sender: tx,
windows: HashMap::with_capacity(4), windows: HashMap::with_capacity(4),
win32_block_loop: win32_block_loop_child,
mouse_buttons_down: 0 mouse_buttons_down: 0
}); });
}); });
@ -220,7 +213,6 @@ impl EventsLoop {
EventsLoop { EventsLoop {
thread_id, thread_id,
receiver: rx, receiver: rx,
win32_block_loop,
} }
} }
@ -232,18 +224,8 @@ impl EventsLoop {
Ok(e) => e, Ok(e) => e,
Err(_) => return Err(_) => return
}; };
let is_resize = match event {
Event::WindowEvent{ event: WindowEvent::Resized(..), .. } => true,
_ => false
};
callback(event); callback(event);
if is_resize {
let (ref mutex, ref cvar) = *self.win32_block_loop;
let mut block_thread = mutex.lock().unwrap();
*block_thread = false;
cvar.notify_all();
}
} }
} }
@ -255,18 +237,8 @@ impl EventsLoop {
Ok(e) => e, Ok(e) => e,
Err(_) => return Err(_) => return
}; };
let is_resize = match event {
Event::WindowEvent{ event: WindowEvent::Resized(..), .. } => true,
_ => false
};
let flow = callback(event); let flow = callback(event);
if is_resize {
let (ref mutex, ref cvar) = *self.win32_block_loop;
let mut block_thread = mutex.lock().unwrap();
*block_thread = false;
cvar.notify_all();
}
match flow { match flow {
ControlFlow::Continue => continue, ControlFlow::Continue => continue,
ControlFlow::Break => break, ControlFlow::Break => break,
@ -399,7 +371,6 @@ thread_local!(static CONTEXT_STASH: RefCell<Option<ThreadLocalData>> = RefCell::
struct ThreadLocalData { struct ThreadLocalData {
sender: mpsc::Sender<Event>, sender: mpsc::Sender<Event>,
windows: HashMap<HWND, Arc<Mutex<WindowState>>>, windows: HashMap<HWND, Arc<Mutex<WindowState>>>,
win32_block_loop: Arc<(Mutex<bool>, Condvar)>,
mouse_buttons_down: u32 mouse_buttons_down: u32
} }
@ -527,24 +498,7 @@ pub unsafe extern "system" fn callback(
event: Resized(logical_size), event: Resized(logical_size),
}; };
// If this window has been inserted into the window map, the resize event happened cstash.sender.send(event).ok();
// during the event loop. If it hasn't, the event happened on window creation and
// should be ignored.
if cstash.windows.get(&window).is_some() {
let (ref mutex, ref cvar) = *cstash.win32_block_loop;
let mut block_thread = mutex.lock().unwrap();
*block_thread = true;
// The event needs to be sent after the lock to ensure that `notify_all` is
// called after `wait`.
cstash.sender.send(event).ok();
while *block_thread {
block_thread = cvar.wait(block_thread).unwrap();
}
} else {
cstash.sender.send(event).ok();
}
}); });
0 0
}, },