From e55f2daf9075e567b8287ddb0ba049712731ff1d Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Fri, 29 Mar 2024 13:08:38 -0400 Subject: [PATCH] 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. --- src/terminal/Screen.zig | 18 ++++++++++++++---- src/terminal/Terminal.zig | 33 ++++++++++----------------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index a94a24c7a..61af34338 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -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(); diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 2c17c051a..0c91cb428 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1793,19 +1793,11 @@ 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.cursor.page_pin.page.data, - self.screen.cursor.page_row, - cell_multi[0..1], - ); - } + self.screen.clearUnprotectedCells( + &self.screen.cursor.page_pin.page.data, + self.screen.cursor.page_row, + cells[0..end], + ); } /// Erase the line. @@ -1878,16 +1870,11 @@ 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.cursor.page_pin.page.data, - self.screen.cursor.page_row, - cell_multi[0..1], - ); - } + self.screen.clearUnprotectedCells( + &self.screen.cursor.page_pin.page.data, + self.screen.cursor.page_row, + cells[start..end], + ); } /// Erase the display.