fix(performance): undo degredation introduced in 646 (#651)

* fix(performance): undo degredation introduced in 646

* style(fmt): make rustfmt happy

* style(fmt): make clippy happy
This commit is contained in:
Aram Drevekenin 2021-08-19 19:02:05 +02:00 committed by GitHub
parent e889891604
commit 2100865063
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 57 deletions

View file

@ -348,7 +348,7 @@ pub struct Grid {
colors: Palette, colors: Palette,
output_buffer: OutputBuffer, output_buffer: OutputBuffer,
title_stack: Vec<String>, title_stack: Vec<String>,
pub changed_colors: [Option<AnsiCode>; 256], pub changed_colors: Option<[Option<AnsiCode>; 256]>,
pub should_render: bool, pub should_render: bool,
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "") pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "")
pub erasure_mode: bool, // ERM pub erasure_mode: bool, // ERM
@ -402,7 +402,7 @@ impl Grid {
selection: Default::default(), selection: Default::default(),
title_stack: vec![], title_stack: vec![],
title: None, title: None,
changed_colors: [None; 256], changed_colors: None,
} }
} }
pub fn render_full_viewport(&mut self) { pub fn render_full_viewport(&mut self) {
@ -1227,7 +1227,7 @@ impl Grid {
self.disable_linewrap = false; self.disable_linewrap = false;
self.cursor.change_shape(CursorShape::Block); self.cursor.change_shape(CursorShape::Block);
self.output_buffer.update_all_lines(); self.output_buffer.update_all_lines();
self.changed_colors = [None; 256]; self.changed_colors = None;
} }
fn set_preceding_character(&mut self, terminal_character: TerminalCharacter) { fn set_preceding_character(&mut self, terminal_character: TerminalCharacter) {
self.preceding_char = Some(terminal_character); self.preceding_char = Some(terminal_character);
@ -1356,22 +1356,12 @@ impl Perform for Grid {
fn print(&mut self, c: char) { fn print(&mut self, c: char) {
let c = self.cursor.charsets[self.active_charset].map(c); let c = self.cursor.charsets[self.active_charset].map(c);
// we add the changed_colors here instead of changing the actual colors on the
// TerminalCharacter in real time because these changed colors also affect the area around
// the character (eg. empty space after it)
// on the other hand, we must do it here and not at render-time because then it would be
// wiped out when one scrolls
let styles = self
.cursor
.pending_styles
.changed_colors(self.changed_colors);
// apparently, building TerminalCharacter like this without a "new" method // apparently, building TerminalCharacter like this without a "new" method
// is a little faster // is a little faster
let terminal_character = TerminalCharacter { let terminal_character = TerminalCharacter {
character: c, character: c,
width: c.width().unwrap_or(0), width: c.width().unwrap_or(0),
styles, styles: self.cursor.pending_styles,
}; };
self.set_preceding_character(terminal_character); self.set_preceding_character(terminal_character);
self.add_character(terminal_character); self.add_character(terminal_character);
@ -1447,7 +1437,10 @@ impl Perform for Grid {
let index = parse_number(chunk[0]); let index = parse_number(chunk[0]);
let color = xparse_color(chunk[1]); let color = xparse_color(chunk[1]);
if let (Some(i), Some(c)) = (index, color) { if let (Some(i), Some(c)) = (index, color) {
self.changed_colors[i as usize] = Some(c); if self.changed_colors.is_none() {
self.changed_colors = Some([None; 256]);
}
self.changed_colors.as_mut().unwrap()[i as usize] = Some(c);
return; return;
} }
} }
@ -1526,16 +1519,16 @@ impl Perform for Grid {
b"104" => { b"104" => {
// Reset all color indexes when no parameters are given. // Reset all color indexes when no parameters are given.
if params.len() == 1 { if params.len() == 1 {
for i in 0..256 { self.changed_colors = None;
self.changed_colors[i] = None;
}
return; return;
} }
// Reset color indexes given as parameters. // Reset color indexes given as parameters.
for param in &params[1..] { for param in &params[1..] {
if let Some(index) = parse_number(param) { if let Some(index) = parse_number(param) {
self.changed_colors[index as usize] = None if self.changed_colors.is_some() {
self.changed_colors.as_mut().unwrap()[index as usize] = None
}
} }
} }

View file

@ -21,7 +21,6 @@ pub const EMPTY_TERMINAL_CHARACTER: TerminalCharacter = TerminalCharacter {
bold: Some(AnsiCode::Reset), bold: Some(AnsiCode::Reset),
dim: Some(AnsiCode::Reset), dim: Some(AnsiCode::Reset),
italic: Some(AnsiCode::Reset), italic: Some(AnsiCode::Reset),
changed_colors: None,
}, },
}; };
@ -110,7 +109,6 @@ pub struct CharacterStyles {
pub bold: Option<AnsiCode>, pub bold: Option<AnsiCode>,
pub dim: Option<AnsiCode>, pub dim: Option<AnsiCode>,
pub italic: Option<AnsiCode>, pub italic: Option<AnsiCode>,
pub changed_colors: Option<[Option<AnsiCode>; 256]>,
} }
impl Default for CharacterStyles { impl Default for CharacterStyles {
@ -127,7 +125,6 @@ impl Default for CharacterStyles {
bold: None, bold: None,
dim: None, dim: None,
italic: None, italic: None,
changed_colors: None,
} }
} }
} }
@ -180,10 +177,6 @@ impl CharacterStyles {
self.strike = strike_code; self.strike = strike_code;
self self
} }
pub fn changed_colors(mut self, changed_colors: [Option<AnsiCode>; 256]) -> Self {
self.changed_colors = Some(changed_colors);
self
}
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.foreground = None; self.foreground = None;
self.background = None; self.background = None;
@ -200,6 +193,7 @@ impl CharacterStyles {
pub fn update_and_return_diff( pub fn update_and_return_diff(
&mut self, &mut self,
new_styles: &CharacterStyles, new_styles: &CharacterStyles,
changed_colors: Option<[Option<AnsiCode>; 256]>,
) -> Option<CharacterStyles> { ) -> Option<CharacterStyles> {
let mut diff: Option<CharacterStyles> = None; let mut diff: Option<CharacterStyles> = None;
@ -329,13 +323,16 @@ impl CharacterStyles {
} }
} }
if let Some(changed_colors) = new_styles.changed_colors { if let Some(changed_colors) = changed_colors {
if let Some(new_diff) = diff.as_mut() { if let Some(AnsiCode::ColorIndex(color_index)) = diff.and_then(|diff| diff.foreground) {
diff = Some(new_diff.changed_colors(changed_colors)); if let Some(changed_color) = changed_colors[color_index as usize] {
self.changed_colors = new_styles.changed_colors; diff.as_mut().unwrap().foreground = Some(changed_color);
} else { }
diff = Some(CharacterStyles::new().changed_colors(changed_colors)); }
self.changed_colors = new_styles.changed_colors; if let Some(AnsiCode::ColorIndex(color_index)) = diff.and_then(|diff| diff.background) {
if let Some(changed_color) = changed_colors[color_index as usize] {
diff.as_mut().unwrap().background = Some(changed_color);
}
} }
} }
diff diff
@ -498,17 +495,7 @@ impl Display for CharacterStyles {
write!(f, "\u{1b}[38;2;{};{};{}m", r, g, b)?; write!(f, "\u{1b}[38;2;{};{};{}m", r, g, b)?;
} }
AnsiCode::ColorIndex(color_index) => { AnsiCode::ColorIndex(color_index) => {
match self write!(f, "\u{1b}[38;5;{}m", color_index)?;
.changed_colors
.and_then(|changed_colors| changed_colors[color_index as usize])
{
Some(AnsiCode::RgbCode((r, g, b))) => {
write!(f, "\u{1b}[38;2;{};{};{}m", r, g, b)?;
}
_ => {
write!(f, "\u{1b}[38;5;{}m", color_index)?;
}
}
} }
AnsiCode::Reset => { AnsiCode::Reset => {
write!(f, "\u{1b}[39m")?; write!(f, "\u{1b}[39m")?;
@ -525,17 +512,7 @@ impl Display for CharacterStyles {
write!(f, "\u{1b}[48;2;{};{};{}m", r, g, b)?; write!(f, "\u{1b}[48;2;{};{};{}m", r, g, b)?;
} }
AnsiCode::ColorIndex(color_index) => { AnsiCode::ColorIndex(color_index) => {
match self write!(f, "\u{1b}[48;5;{}m", color_index)?;
.changed_colors
.and_then(|changed_colors| changed_colors[color_index as usize])
{
Some(AnsiCode::RgbCode((r, g, b))) => {
write!(f, "\u{1b}[48;2;{};{};{}m", r, g, b)?;
}
_ => {
write!(f, "\u{1b}[48;5;{}m", color_index)?;
}
}
} }
AnsiCode::Reset => { AnsiCode::Reset => {
write!(f, "\u{1b}[49m")?; write!(f, "\u{1b}[49m")?;

View file

@ -236,8 +236,8 @@ impl Pane for TerminalPane {
break; break;
} }
if let Some(new_styles) = if let Some(new_styles) = character_styles
character_styles.update_and_return_diff(&t_character.styles) .update_and_return_diff(&t_character.styles, self.grid.changed_colors)
{ {
vte_output.push_str(&new_styles.to_string()); vte_output.push_str(&new_styles.to_string());
} }