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, row: *Row,
cells: []Cell, cells: []Cell,
) void { ) void {
for (cells) |*cell| { var x0: usize = 0;
if (cell.protected) continue; var x1: usize = 0;
const cell_multi: [*]Cell = @ptrCast(cell);
self.clearCells(page, row, cell_multi[0..1]); 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(); page.assertIntegrity();

View File

@ -1793,19 +1793,11 @@ pub fn eraseChars(self: *Terminal, count_req: usize) void {
return; return;
} }
// SLOW PATH self.screen.clearUnprotectedCells(
// 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.cursor.page_pin.page.data, &self.screen.cursor.page_pin.page.data,
self.screen.cursor.page_row, self.screen.cursor.page_row,
cell_multi[0..1], cells[0..end],
); );
}
} }
/// Erase the line. /// Erase the line.
@ -1878,16 +1870,11 @@ pub fn eraseLine(
return; return;
} }
for (start..end) |x| { self.screen.clearUnprotectedCells(
const cell_multi: [*]Cell = @ptrCast(cells + x);
const cell: *Cell = @ptrCast(&cell_multi[0]);
if (cell.protected) continue;
self.screen.clearCells(
&self.screen.cursor.page_pin.page.data, &self.screen.cursor.page_pin.page.data,
self.screen.cursor.page_row, self.screen.cursor.page_row,
cell_multi[0..1], cells[start..end],
); );
}
} }
/// Erase the display. /// Erase the display.