mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
Fix mesa rendering outside window borders on wayland
The mesa workaround has lead to some issues with rendering on Wayland. To resolve this problem, the mesa workaround has been restructured in a way which still allows clearing the screen before rendering without killing performance with the mesa driver. The performance is identical to the master brach and there have been no recorded regressions.
This commit is contained in:
parent
cee35b309d
commit
9b694fcc54
3 changed files with 33 additions and 35 deletions
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Clear screen properly before rendering of content to prevent various graphical glitches
|
||||||
- Fix build failure on 32-bit systems
|
- Fix build failure on 32-bit systems
|
||||||
- Windows started as unfocused now show the hollow cursor if the setting is enabled
|
- Windows started as unfocused now show the hollow cursor if the setting is enabled
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ use font::{self, Rasterize};
|
||||||
use meter::Meter;
|
use meter::Meter;
|
||||||
use renderer::{self, GlyphCache, QuadRenderer};
|
use renderer::{self, GlyphCache, QuadRenderer};
|
||||||
use term::{Term, SizeInfo};
|
use term::{Term, SizeInfo};
|
||||||
|
use sync::FairMutex;
|
||||||
|
|
||||||
use window::{self, Size, Pixels, Window, SetInnerSize};
|
use window::{self, Size, Pixels, Window, SetInnerSize};
|
||||||
|
|
||||||
|
@ -97,7 +98,6 @@ pub struct Display {
|
||||||
meter: Meter,
|
meter: Meter,
|
||||||
font_size: font::Size,
|
font_size: font::Size,
|
||||||
size_info: SizeInfo,
|
size_info: SizeInfo,
|
||||||
last_background_color: Rgb,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can wakeup the render loop from other threads
|
/// Can wakeup the render loop from other threads
|
||||||
|
@ -210,7 +210,6 @@ impl Display {
|
||||||
meter: Meter::new(),
|
meter: Meter::new(),
|
||||||
font_size: font::Size::new(0.),
|
font_size: font::Size::new(0.),
|
||||||
size_info,
|
size_info,
|
||||||
last_background_color: background_color,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +324,29 @@ impl Display {
|
||||||
/// A reference to Term whose state is being drawn must be provided.
|
/// A reference to Term whose state is being drawn must be provided.
|
||||||
///
|
///
|
||||||
/// This call may block if vsync is enabled
|
/// This call may block if vsync is enabled
|
||||||
pub fn draw(&mut self, mut terminal: MutexGuard<Term>, config: &Config) {
|
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();
|
||||||
|
|
||||||
// Clear dirty flag
|
// Clear dirty flag
|
||||||
terminal.dirty = !terminal.visual_bell.completed();
|
terminal.dirty = !terminal.visual_bell.completed();
|
||||||
|
|
||||||
|
@ -345,13 +366,6 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let size_info = *terminal.size_info();
|
|
||||||
let visual_bell_intensity = terminal.visual_bell.intensity();
|
|
||||||
|
|
||||||
let background_color = terminal.background_color();
|
|
||||||
let background_color_changed = background_color != self.last_background_color;
|
|
||||||
self.last_background_color = background_color;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let glyph_cache = &mut self.glyph_cache;
|
let glyph_cache = &mut self.glyph_cache;
|
||||||
|
|
||||||
|
@ -366,11 +380,6 @@ impl Display {
|
||||||
// mutable borrow
|
// mutable borrow
|
||||||
let window_focused = self.window.is_focused;
|
let window_focused = self.window.is_focused;
|
||||||
self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
|
self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
|
||||||
// Clear screen to update whole background with new color
|
|
||||||
if background_color_changed {
|
|
||||||
api.clear(background_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the grid
|
// Draw the grid
|
||||||
api.render_cells(
|
api.render_cells(
|
||||||
terminal.renderable_cells(config, window_focused),
|
terminal.renderable_cells(config, window_focused),
|
||||||
|
@ -394,19 +403,6 @@ impl Display {
|
||||||
self.window
|
self.window
|
||||||
.swap_buffers()
|
.swap_buffers()
|
||||||
.expect("swap buffers");
|
.expect("swap buffers");
|
||||||
|
|
||||||
// Clear after swap_buffers 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.
|
|
||||||
self.renderer.with_api(config, &size_info, visual_bell_intensity, |api| {
|
|
||||||
api.clear(background_color);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_window_id(&self) -> Option<usize> {
|
pub fn get_window_id(&self) -> Option<usize> {
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -173,7 +173,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
|
||||||
// Main display loop
|
// Main display loop
|
||||||
loop {
|
loop {
|
||||||
// Process input and window events
|
// Process input and window events
|
||||||
let mut terminal = processor.process_events(&terminal, display.window());
|
let mut terminal_lock = processor.process_events(&terminal, display.window());
|
||||||
|
|
||||||
// Handle config reloads
|
// Handle config reloads
|
||||||
if let Some(new_config) = config_monitor
|
if let Some(new_config) = config_monitor
|
||||||
|
@ -183,22 +183,23 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
|
||||||
config = new_config.update_dynamic_title(options);
|
config = new_config.update_dynamic_title(options);
|
||||||
display.update_config(&config);
|
display.update_config(&config);
|
||||||
processor.update_config(&config);
|
processor.update_config(&config);
|
||||||
terminal.update_config(&config);
|
terminal_lock.update_config(&config);
|
||||||
terminal.dirty = true;
|
terminal_lock.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe draw the terminal
|
// Maybe draw the terminal
|
||||||
if terminal.needs_draw() {
|
if terminal_lock.needs_draw() {
|
||||||
// Try to update the position of the input method editor
|
// Try to update the position of the input method editor
|
||||||
display.update_ime_position(&terminal);
|
display.update_ime_position(&terminal_lock);
|
||||||
// Handle pending resize events
|
// Handle pending resize events
|
||||||
//
|
//
|
||||||
// The second argument is a list of types that want to be notified
|
// The second argument is a list of types that want to be notified
|
||||||
// of display size changes.
|
// of display size changes.
|
||||||
display.handle_resize(&mut terminal, &config, &mut [&mut pty, &mut processor]);
|
display.handle_resize(&mut terminal_lock, &config, &mut [&mut pty, &mut processor]);
|
||||||
|
drop(terminal_lock);
|
||||||
|
|
||||||
// Draw the current state of the terminal
|
// Draw the current state of the terminal
|
||||||
display.draw(terminal, &config);
|
display.draw(&terminal, &config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin shutdown if the flag was raised.
|
// Begin shutdown if the flag was raised.
|
||||||
|
|
Loading…
Reference in a new issue