diff options
author | Joe Wilm <joe@jwilm.com> | 2016-12-29 21:38:22 -0500 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-12-29 21:38:22 -0500 |
commit | a91a3f2dce121a179a9371cd0ad1e548cf3d7731 (patch) | |
tree | 311f1ee1b60eb9fb11bad3bdee8812d3be5590b8 /src/window.rs | |
parent | b704dafb2420df6f7fca64980a2f52c1a00bcef5 (diff) | |
download | alacritty-a91a3f2dce121a179a9371cd0ad1e548cf3d7731.tar.gz alacritty-a91a3f2dce121a179a9371cd0ad1e548cf3d7731.zip |
Fix pty read sometimes not triggering draw
There was a lot of complexity around the threadsafe `Flag` type and
waking up the event loop. The idea was to prevent unnecessary calls to
the glutin window's wakeup_event_loop() method which can be expensive.
This complexity made it difficult to get synchronization between the pty
reader and the render thread correct. Now, the `dirty` flag on the
terminal is also used to prevent spurious wakeups. It is only changed
when the mutex is held, so race conditions associated with that flag
shouldn't happen.
Diffstat (limited to 'src/window.rs')
-rw-r--r-- | src/window.rs | 75 |
1 files changed, 6 insertions, 69 deletions
diff --git a/src/window.rs b/src/window.rs index 62c65c9c..edf1e7f1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -11,8 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; use std::convert::From; use std::fmt::{self, Display}; use std::ops::Deref; @@ -57,16 +55,11 @@ type Result<T> = ::std::result::Result<T, Error>; /// Wraps the underlying windowing library to provide a stable API in Alacritty pub struct Window { glutin_window: glutin::Window, - - /// This flag allows calls to wakeup_event_loop to be coalesced. Waking the - /// event loop is potentially very slow (and indeed is on X11). - flag: Flag } /// Threadsafe APIs for the window pub struct Proxy { inner: glutin::WindowProxy, - flag: Flag, } /// Information about where the window is being displayed @@ -98,46 +91,6 @@ pub struct Pixels<T>(pub T); #[derive(Debug, Copy, Clone)] pub struct Points<T>(pub T); -/// A wrapper around glutin's `WaitEventsIterator` that clears the wakeup -/// optimization flag on drop. -pub struct WaitEventsIterator<'a> { - inner: glutin::WaitEventsIterator<'a>, - flag: Flag -} - -impl<'a> Iterator for WaitEventsIterator<'a> { - type Item = glutin::Event; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - self.inner.next() - } -} - -impl<'a> Drop for WaitEventsIterator<'a> { - fn drop(&mut self) { - self.flag.set(false); - } -} - -#[derive(Clone)] -pub struct Flag(pub Arc<AtomicBool>); -impl Flag { - pub fn new(initial_value: bool) -> Flag { - Flag(Arc::new(AtomicBool::new(initial_value))) - } - - #[inline] - pub fn get(&self) -> bool { - self.0.load(Ordering::Acquire) - } - - #[inline] - pub fn set(&self, value: bool) { - self.0.store(value, Ordering::Release) - } -} - pub trait ToPoints { fn to_points(&self, scale: f32) -> Size<Points<u32>>; } @@ -265,7 +218,6 @@ impl Window { Ok(Window { glutin_window: window, - flag: Flag::new(false), }) } @@ -308,7 +260,6 @@ impl Window { pub fn create_window_proxy(&self) -> Proxy { Proxy { inner: self.glutin_window.create_window_proxy(), - flag: self.flag.clone(), } } @@ -319,26 +270,18 @@ impl Window { .map_err(From::from) } - /// Block waiting for events + /// Poll for any available events #[inline] - pub fn wait_events(&self) -> WaitEventsIterator { - WaitEventsIterator { - inner: self.glutin_window.wait_events(), - flag: self.flag.clone() - } - } - - /// Clear the wakeup optimization flag - pub fn clear_wakeup_flag(&self) { - self.flag.set(false); + pub fn poll_events(&self) -> glutin::PollEventsIterator { + self.glutin_window.poll_events() } /// Block waiting for events /// /// FIXME should return our own type #[inline] - pub fn poll_events(&self) -> glutin::PollEventsIterator { - self.glutin_window.poll_events() + pub fn wait_events(&self) -> glutin::WaitEventsIterator { + self.glutin_window.wait_events() } } @@ -348,13 +291,7 @@ impl Proxy { /// This is useful for triggering a draw when the renderer would otherwise /// be waiting on user input. pub fn wakeup_event_loop(&self) { - // Only wake up the window event loop if it hasn't already been - // signaled. This is a really important optimization because waking up - // the event loop redundantly burns *a lot* of cycles. - if !self.flag.get() { - self.inner.wakeup_event_loop(); - self.flag.set(true); - } + self.inner.wakeup_event_loop(); } } |