From 308050dc7dd62a4ccbfe1bca094be78e8ed0cd90 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 29 Apr 2022 19:47:17 -0700 Subject: [PATCH] only update cells in the render call --- src/Grid.zig | 3 +++ src/Window.zig | 12 ++++-------- src/terminal/Terminal.zig | 31 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/Grid.zig b/src/Grid.zig index fcc33ac19..afbad3845 100644 --- a/src/Grid.zig +++ b/src/Grid.zig @@ -258,6 +258,9 @@ pub fn demoCells(self: *Grid) !void { /// updateCells updates our GPU cells from the current terminal view. /// The updated cells will take effect on the next render. pub fn updateCells(self: *Grid, term: Terminal) !void { + const t = trace(@src()); + defer t.end(); + // For now, we just ensure that we have enough cells for all the lines // we have plus a full width. This is very likely too much but its // the probably close enough while guaranteeing no more allocations. diff --git a/src/Window.zig b/src/Window.zig index 665e037be..b1eb8d0fe 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -260,9 +260,6 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { // Update the size of our terminal state win.terminal.resize(win.grid.size.columns, win.grid.size.rows); - // TODO: this is not the right place for this - win.grid.updateCells(win.terminal) catch unreachable; - // Update the size of our pty win.pty.setSize(.{ .ws_row = @intCast(u16, win.grid.size.rows), @@ -376,7 +373,6 @@ fn focusCallback(window: glfw.Window, focused: bool) void { } else { win.grid.cursor_visible = true; win.grid.cursor_style = .box_hollow; - win.grid.updateCells(win.terminal) catch unreachable; win.cursor_timer.stop() catch unreachable; } } @@ -387,7 +383,6 @@ fn cursorTimerCallback(t: *libuv.Timer) void { const win = t.getData(Window) orelse return; win.grid.cursor_visible = !win.grid.cursor_visible; - win.grid.updateCells(win.terminal) catch unreachable; win.render_timer.schedule() catch unreachable; } @@ -432,9 +427,6 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void { _ = win.cursor_timer.again() catch null; } - // Update the cells for drawing - win.grid.updateCells(win.terminal) catch unreachable; - // Schedule a render win.render_timer.schedule() catch unreachable; } @@ -456,10 +448,14 @@ fn ttyWrite(req: *libuv.WriteReq, status: i32) void { fn renderTimerCallback(t: *libuv.Timer) void { const tracy = trace(@src()); + tracy.color(0x006E7F); // blue-ish defer tracy.end(); const win = t.getData(Window).?; + // Update the cells for drawing + win.grid.updateCells(win.terminal) catch unreachable; + // Set our background gl.clearColor(0.2, 0.3, 0.3, 1.0); gl.clear(gl.c.GL_COLOR_BUFFER_BIT); diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 625b4f50b..da4dbb4f6 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -10,6 +10,7 @@ const Allocator = std.mem.Allocator; const ansi = @import("ansi.zig"); const Parser = @import("Parser.zig"); const Tabstops = @import("Tabstops.zig"); +const trace = @import("../tracy/tracy.zig").trace; const log = std.log.scoped(.terminal); @@ -105,6 +106,9 @@ pub fn plainString(self: Terminal, alloc: Allocator) ![]const u8 { /// Append a string of characters. See appendChar. pub fn append(self: *Terminal, alloc: Allocator, str: []const u8) !void { + const tracy = trace(@src()); + defer tracy.end(); + for (str) |c| { try self.appendChar(alloc, c); } @@ -114,6 +118,9 @@ pub fn append(self: *Terminal, alloc: Allocator, str: []const u8) !void { /// /// This may allocate if necessary to store the character in the grid. pub fn appendChar(self: *Terminal, alloc: Allocator, c: u8) !void { + const tracy = trace(@src()); + defer tracy.end(); + //log.debug("char: {}", .{c}); const actions = self.parser.next(c); for (actions) |action_opt| { @@ -125,6 +132,9 @@ pub fn appendChar(self: *Terminal, alloc: Allocator, c: u8) !void { } fn print(self: *Terminal, alloc: Allocator, c: u8) !void { + const tracy = trace(@src()); + defer tracy.end(); + // Build our cell const cell = try self.getOrPutCell(alloc, self.cursor.x, self.cursor.y); cell.* = .{ @@ -141,6 +151,9 @@ fn print(self: *Terminal, alloc: Allocator, c: u8) !void { } fn execute(self: *Terminal, alloc: Allocator, c: u8) !void { + const tracy = trace(@src()); + defer tracy.end(); + switch (@intToEnum(ansi.C0, c)) { .BEL => self.bell(), .BS => self.backspace(), @@ -158,12 +171,18 @@ pub fn bell(self: *Terminal) void { /// Backspace moves the cursor back a column (but not less than 0). pub fn backspace(self: *Terminal) void { + const tracy = trace(@src()); + defer tracy.end(); + self.cursor.x -|= 1; } /// Horizontal tab moves the cursor to the next tabstop, clearing /// the screen to the left the tabstop. pub fn horizontal_tab(self: *Terminal, alloc: Allocator) !void { + const tracy = trace(@src()); + defer tracy.end(); + while (self.cursor.x < self.cols) { // Clear try self.print(alloc, ' '); @@ -177,11 +196,17 @@ pub fn horizontal_tab(self: *Terminal, alloc: Allocator) !void { /// Carriage return moves the cursor to the first column. pub fn carriage_return(self: *Terminal) void { + const tracy = trace(@src()); + defer tracy.end(); + self.cursor.x = 0; } /// Linefeed moves the cursor to the next line. pub fn linefeed(self: *Terminal, alloc: Allocator) void { + const tracy = trace(@src()); + defer tracy.end(); + // If we're at the end of the screen, scroll up. This is surprisingly // common because most terminals live with a full screen so we do this // check first. @@ -196,6 +221,9 @@ pub fn linefeed(self: *Terminal, alloc: Allocator) void { /// Scroll the text up by one row. pub fn scroll_up(self: *Terminal, alloc: Allocator) void { + const tracy = trace(@src()); + defer tracy.end(); + // TODO: this is horribly expensive. we need to optimize the screen repr // If we have no items, scrolling does nothing. @@ -212,6 +240,9 @@ pub fn scroll_up(self: *Terminal, alloc: Allocator) void { } fn getOrPutCell(self: *Terminal, alloc: Allocator, x: usize, y: usize) !*Cell { + const tracy = trace(@src()); + defer tracy.end(); + // If we don't have enough lines to get to y, then add it. if (self.screen.items.len < y + 1) { try self.screen.ensureTotalCapacity(alloc, y + 1);