Improve terminal rendering performance (#33345)

Closes #18263

Improvements:

• **Batch text rendering** - Combine adjacent cells with identical
styling into single text runs to reduce draw calls
• **Throttle hyperlink searches** - Limit hyperlink detection to every
100ms or when mouse moves >5px to reduce CPU usage
• **Pre-allocate collections** - Use `Vec::with_capacity()` for cells,
runs, and regions to minimize reallocations
• **Optimize background regions** - Merge adjacent background rectangles
to reduce number of draw operations
• **Cache selection text** - Only compute terminal selection string when
selection exists

Release Notes:

- Improved terminal rendering performance.

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Alisina Bahadori 2025-07-08 11:05:01 -04:00 committed by GitHub
parent bcac748c2b
commit 925464cfc6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 609 additions and 177 deletions

View file

@ -259,20 +259,17 @@ impl Render for TerminalOutput {
cell: ic.cell.clone(),
});
let minimum_contrast = TerminalSettings::get_global(cx).minimum_contrast;
let (cells, rects) = TerminalElement::layout_grid(
grid,
0,
&text_style,
text_system,
None,
minimum_contrast,
window,
cx,
);
let (rects, batched_text_runs) =
TerminalElement::layout_grid(grid, 0, &text_style, None, minimum_contrast, cx);
// lines are 0-indexed, so we must add 1 to get the number of lines
let text_line_height = text_style.line_height_in_pixels(window.rem_size());
let num_lines = cells.iter().map(|c| c.point.line).max().unwrap_or(0) + 1;
let num_lines = batched_text_runs
.iter()
.map(|b| b.start_point.line)
.max()
.unwrap_or(0)
+ 1;
let height = num_lines as f32 * text_line_height;
let font_pixels = text_style.font_size.to_pixels(window.rem_size());
@ -300,15 +297,14 @@ impl Render for TerminalOutput {
);
}
for cell in cells {
cell.paint(
for batch in batched_text_runs {
batch.paint(
bounds.origin,
&terminal::TerminalBounds {
cell_width,
line_height: text_line_height,
bounds,
},
bounds,
window,
cx,
);

View file

@ -106,7 +106,9 @@ impl TableView {
for field in table.schema.fields.iter() {
runs[0].len = field.name.len();
let mut width = text_system.layout_line(&field.name, font_size, &runs).width;
let mut width = text_system
.layout_line(&field.name, font_size, &runs, None)
.width;
let Some(data) = table.data.as_ref() else {
widths.push(width);
@ -118,7 +120,7 @@ impl TableView {
runs[0].len = content.len();
let cell_width = window
.text_system()
.layout_line(&content, font_size, &runs)
.layout_line(&content, font_size, &runs, None)
.width;
width = width.max(cell_width)