mirror of
https://github.com/wez/wezterm.git
synced 2024-12-22 21:01:36 +03:00
perf: adjust clustering when bidi is disabled
When a line is rapidly updated with only some of the cells being actually changed (eg: progress counter or other status being frequently updated), it is desirable to avoid paying the cost of shaping the entire line. When bidi is not enabled we can assume that it is safe to break clusters on whitespace boundaries. Doing so allows each of those whitespace separated words to be shaped and potentially cached independently, which reduces the amount of CPU time spent for the whole line. This commit just adjusts the clustering, which reduces the CPU utilization a bit. refs: https://github.com/wez/wezterm/issues/2701
This commit is contained in:
parent
0516b61f62
commit
831eda86b9
@ -102,17 +102,29 @@ impl CellCluster {
|
||||
// the terminal is wide and a long series of short lines are printed;
|
||||
// the shaper can cache the few variations of trailing whitespace
|
||||
// and focus on shaping the shorter cluster sequences.
|
||||
// Or:
|
||||
// when bidi is disabled, force break on whitespace boundaries.
|
||||
// This reduces shaping load in the case where is a line is
|
||||
// updated continually, but only a portion of it changes
|
||||
// (eg: progress counter).
|
||||
let was_whitespace = whitespace_run > 0;
|
||||
if cell_str == " " {
|
||||
whitespace_run += 1;
|
||||
} else {
|
||||
whitespace_run = 0;
|
||||
only_whitespace = false;
|
||||
}
|
||||
if !only_whitespace && whitespace_run > 2 {
|
||||
|
||||
let force_break = (!only_whitespace && whitespace_run > 2)
|
||||
|| (!only_whitespace && bidi_hint.is_none() && was_whitespace);
|
||||
|
||||
if force_break {
|
||||
clusters.push(last);
|
||||
|
||||
only_whitespace = cell_str == " ";
|
||||
whitespace_run = 1;
|
||||
if whitespace_run > 0 {
|
||||
whitespace_run = 1;
|
||||
}
|
||||
Some(CellCluster::new(
|
||||
hint,
|
||||
presentation,
|
||||
|
@ -128,7 +128,6 @@ mod test {
|
||||
use crate::shapecache::{GlyphPosition, ShapedInfo};
|
||||
use crate::utilsprites::RenderMetrics;
|
||||
use config::{FontAttributes, TextStyle};
|
||||
use k9::assert_equal as assert_eq;
|
||||
use std::rc::Rc;
|
||||
use termwiz::cell::CellAttributes;
|
||||
use termwiz::surface::{Line, SEQ_ZERO};
|
||||
@ -149,48 +148,53 @@ mod test {
|
||||
{
|
||||
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO, None);
|
||||
eprintln!("{:?}", line);
|
||||
let cell_clusters = line.cluster(None);
|
||||
assert_eq!(cell_clusters.len(), 1);
|
||||
let cluster = &cell_clusters[0];
|
||||
let presentation_width = PresentationWidth::with_cluster(&cluster);
|
||||
let infos = font
|
||||
.shape(
|
||||
&cluster.text,
|
||||
|| {},
|
||||
|_| {},
|
||||
None,
|
||||
Direction::LeftToRight,
|
||||
None,
|
||||
Some(&presentation_width),
|
||||
)
|
||||
.unwrap();
|
||||
let glyphs = infos
|
||||
.iter()
|
||||
.map(|info| {
|
||||
let cell_idx = cluster.byte_to_cell_idx(info.cluster as usize);
|
||||
let num_cells = cluster.byte_to_cell_width(info.cluster as usize);
|
||||
let mut all_infos = vec![];
|
||||
let mut all_glyphs = vec![];
|
||||
|
||||
let followed_by_space = match line.get_cell(cell_idx + 1) {
|
||||
Some(cell) => cell.str() == " ",
|
||||
None => false,
|
||||
};
|
||||
for cluster in line.cluster(None) {
|
||||
let presentation_width = PresentationWidth::with_cluster(&cluster);
|
||||
let mut infos = font
|
||||
.shape(
|
||||
&cluster.text,
|
||||
|| {},
|
||||
|_| {},
|
||||
None,
|
||||
Direction::LeftToRight,
|
||||
None,
|
||||
Some(&presentation_width),
|
||||
)
|
||||
.unwrap();
|
||||
let mut glyphs = infos
|
||||
.iter()
|
||||
.map(|info| {
|
||||
let cell_idx = cluster.byte_to_cell_idx(info.cluster as usize);
|
||||
let num_cells = cluster.byte_to_cell_width(info.cluster as usize);
|
||||
|
||||
glyph_cache
|
||||
.cached_glyph(
|
||||
info,
|
||||
&style,
|
||||
followed_by_space,
|
||||
font,
|
||||
render_metrics,
|
||||
num_cells,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let followed_by_space = match line.get_cell(cell_idx + 1) {
|
||||
Some(cell) => cell.str() == " ",
|
||||
None => false,
|
||||
};
|
||||
|
||||
eprintln!("infos: {:#?}", infos);
|
||||
eprintln!("glyphs: {:#?}", glyphs);
|
||||
ShapedInfo::process(&infos, &glyphs)
|
||||
glyph_cache
|
||||
.cached_glyph(
|
||||
info,
|
||||
&style,
|
||||
followed_by_space,
|
||||
font,
|
||||
render_metrics,
|
||||
num_cells,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
all_infos.append(&mut infos);
|
||||
all_glyphs.append(&mut glyphs);
|
||||
}
|
||||
|
||||
eprintln!("infos: {:#?}", all_infos);
|
||||
eprintln!("glyphs: {:#?}", all_glyphs);
|
||||
ShapedInfo::process(&all_infos, &all_glyphs)
|
||||
.into_iter()
|
||||
.map(|p| p.pos)
|
||||
.collect()
|
||||
|
Loading…
Reference in New Issue
Block a user