aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/display.rs59
-rw-r--r--src/renderer/mod.rs8
-rw-r--r--src/term/mod.rs1
4 files changed, 32 insertions, 37 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6283e41..4ab2bce2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
+- Rendering now occurs without the terminal locked which improves performance
- Clear screen properly before rendering of content to prevent various graphical glitches
- Fix build failure on 32-bit systems
- Windows started as unfocused now show the hollow cursor if the setting is enabled
diff --git a/src/display.rs b/src/display.rs
index 928434d8..d806b33a 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -24,7 +24,7 @@ use config::Config;
use font::{self, Rasterize};
use meter::Meter;
use renderer::{self, GlyphCache, QuadRenderer};
-use term::{Term, SizeInfo};
+use term::{Term, SizeInfo, RenderableCell};
use sync::FairMutex;
use window::{self, Size, Pixels, Window, SetInnerSize};
@@ -325,27 +325,15 @@ impl Display {
///
/// This call may block if vsync is enabled
pub fn draw(&mut self, terminal: &FairMutex<Term>, config: &Config) {
- let terminal_locked = terminal.lock();
- let size_info = *terminal_locked.size_info();
- let visual_bell_intensity = terminal_locked.visual_bell.intensity();
- let background_color = terminal_locked.background_color();
-
- // Clear when terminal mutex isn't held. Mesa for
- // some reason takes a long time to call glClear(). The driver descends
- // into xcb_connect_to_fd() which ends up calling __poll_nocancel()
- // which blocks for a while.
- //
- // By keeping this outside of the critical region, the Mesa bug is
- // worked around to some extent. Since this doesn't actually address the
- // issue of glClear being slow, less time is available for input
- // handling and rendering.
- drop(terminal_locked);
-
- self.renderer.with_api(config, &size_info, visual_bell_intensity, |api| {
- api.clear(background_color);
- });
-
let mut terminal = terminal.lock();
+ let size_info = *terminal.size_info();
+ let visual_bell_intensity = terminal.visual_bell.intensity();
+ let background_color = terminal.background_color();
+
+ let window_focused = self.window.is_focused;
+ let grid_cells: Vec<RenderableCell> = terminal
+ .renderable_cells(config, window_focused)
+ .collect();
// Clear dirty flag
terminal.dirty = !terminal.visual_bell.completed();
@@ -366,6 +354,21 @@ impl Display {
}
}
+ // Clear when terminal mutex isn't held. Mesa for
+ // some reason takes a long time to call glClear(). The driver descends
+ // into xcb_connect_to_fd() which ends up calling __poll_nocancel()
+ // which blocks for a while.
+ //
+ // By keeping this outside of the critical region, the Mesa bug is
+ // worked around to some extent. Since this doesn't actually address the
+ // issue of glClear being slow, less time is available for input
+ // handling and rendering.
+ drop(terminal);
+
+ self.renderer.with_api(config, &size_info, visual_bell_intensity, |api| {
+ api.clear(background_color);
+ });
+
{
let glyph_cache = &mut self.glyph_cache;
@@ -373,18 +376,9 @@ impl Display {
{
let _sampler = self.meter.sampler();
- // Make a copy of size_info since the closure passed here
- // borrows terminal mutably
- //
- // TODO I wonder if the renderable cells iter could avoid the
- // mutable borrow
- let window_focused = self.window.is_focused;
self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
// Draw the grid
- api.render_cells(
- terminal.renderable_cells(config, window_focused),
- glyph_cache,
- );
+ api.render_cells(grid_cells.iter(), glyph_cache);
});
}
@@ -398,8 +392,6 @@ impl Display {
}
}
- // Unlock the terminal mutex; following call to swap_buffers() may block
- drop(terminal);
self.window
.swap_buffers()
.expect("swap buffers");
@@ -423,3 +415,4 @@ impl Display {
self.window().set_ime_spot(nspot_x, nspot_y);
}
}
+
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index b461db0c..bcc896ef 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -374,7 +374,7 @@ pub struct RenderApi<'a> {
current_atlas: &'a mut usize,
program: &'a mut ShaderProgram,
config: &'a Config,
- visual_bell_intensity: f32
+ visual_bell_intensity: f32,
}
#[derive(Debug)]
@@ -799,7 +799,7 @@ impl<'a> RenderApi<'a> {
})
.collect::<Vec<_>>();
- self.render_cells(cells.into_iter(), glyph_cache);
+ self.render_cells(cells.iter(), glyph_cache);
}
#[inline]
@@ -817,12 +817,12 @@ impl<'a> RenderApi<'a> {
}
}
- pub fn render_cells<I>(
+ pub fn render_cells<'b, I>(
&mut self,
cells: I,
glyph_cache: &mut GlyphCache
)
- where I: Iterator<Item=RenderableCell>
+ where I: Iterator<Item=&'b RenderableCell>
{
for cell in cells {
// Get font key for cell
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 9be8b96b..495a7567 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -372,6 +372,7 @@ impl<'a> RenderableCellsIter<'a> {
}
}
+#[derive(Debug)]
pub struct RenderableCell {
/// A _Display_ line (not necessarily an _Active_ line)
pub line: Line,