perf(terminal): clear unprotected cells in spans

Previous behavior of clearing one at a time hit a page integrity assertion after clearing a wide character but not its tail. This fixes that and should also be - in theory - significantly more performant as well by identifying spans of unprotected cells and clearing them in bulk.
This commit is contained in:
Qwerasd
2024-03-29 13:08:38 -04:00
parent 37f31017dc
commit e55f2daf90
2 changed files with 24 additions and 27 deletions

View File

@ -891,10 +891,20 @@ pub fn clearUnprotectedCells(
row: *Row,
cells: []Cell,
) void {
for (cells) |*cell| {
if (cell.protected) continue;
const cell_multi: [*]Cell = @ptrCast(cell);
self.clearCells(page, row, cell_multi[0..1]);
var x0: usize = 0;
var x1: usize = 0;
while (x0 < cells.len) clear: {
while (cells[x0].protected) {
x0 += 1;
if (x0 >= cells.len) break :clear;
}
x1 = x0 + 1;
while (x1 < cells.len and !cells[x1].protected) {
x1 += 1;
}
self.clearCells(page, row, cells[x0..x1]);
x0 = x1;
}
page.assertIntegrity();

View File

@ -1793,20 +1793,12 @@ pub fn eraseChars(self: *Terminal, count_req: usize) void {
return;
}
// SLOW PATH
// We had a protection mode at some point. We must go through each
// cell and check its protection attribute.
for (0..end) |x| {
const cell_multi: [*]Cell = @ptrCast(cells + x);
const cell: *Cell = @ptrCast(&cell_multi[0]);
if (cell.protected) continue;
self.screen.clearCells(
self.screen.clearUnprotectedCells(
&self.screen.cursor.page_pin.page.data,
self.screen.cursor.page_row,
cell_multi[0..1],
cells[0..end],
);
}
}
/// Erase the line.
pub fn eraseLine(
@ -1878,17 +1870,12 @@ pub fn eraseLine(
return;
}
for (start..end) |x| {
const cell_multi: [*]Cell = @ptrCast(cells + x);
const cell: *Cell = @ptrCast(&cell_multi[0]);
if (cell.protected) continue;
self.screen.clearCells(
self.screen.clearUnprotectedCells(
&self.screen.cursor.page_pin.page.data,
self.screen.cursor.page_row,
cell_multi[0..1],
cells[start..end],
);
}
}
/// Erase the display.
pub fn eraseDisplay(