renderer/metal: clean up some unnecessary state around rebuilds

This commit is contained in:
Mitchell Hashimoto
2024-05-04 19:05:22 -07:00
parent 0836aa7318
commit 6b3cb69101
2 changed files with 37 additions and 21 deletions

View File

@ -98,9 +98,6 @@ current_background_color: terminal.color.RGB,
/// cells goes into a separate shader. /// cells goes into a separate shader.
cells: mtl_cell.Contents, cells: mtl_cell.Contents,
/// If this is true, we do a full cell rebuild on the next frame.
cells_rebuild: bool = true,
/// Set to true after rebuildCells is called. This can be used /// Set to true after rebuildCells is called. This can be used
/// to determine if any possible changes have been made to the /// to determine if any possible changes have been made to the
/// cells for the draw call. /// cells for the draw call.
@ -818,6 +815,9 @@ pub fn updateFrame(
preedit: ?renderer.State.Preedit, preedit: ?renderer.State.Preedit,
cursor_style: ?renderer.CursorStyle, cursor_style: ?renderer.CursorStyle,
color_palette: terminal.color.Palette, color_palette: terminal.color.Palette,
/// If true, rebuild the full screen.
full_rebuild: bool,
}; };
// Update all our data as tightly as possible within the mutex. // Update all our data as tightly as possible within the mutex.
@ -888,16 +888,20 @@ pub fn updateFrame(
// If we have any terminal dirty flags set then we need to rebuild // If we have any terminal dirty flags set then we need to rebuild
// the entire screen. This can be optimized in the future. // the entire screen. This can be optimized in the future.
{ const full_rebuild: bool = rebuild: {
const Int = @typeInfo(terminal.Terminal.Dirty).Struct.backing_integer.?; {
const v: Int = @bitCast(state.terminal.flags.dirty); const Int = @typeInfo(terminal.Terminal.Dirty).Struct.backing_integer.?;
if (v > 0) self.cells_rebuild = true; const v: Int = @bitCast(state.terminal.flags.dirty);
} if (v > 0) break :rebuild true;
{ }
const Int = @typeInfo(terminal.Screen.Dirty).Struct.backing_integer.?; {
const v: Int = @bitCast(state.terminal.screen.dirty); const Int = @typeInfo(terminal.Screen.Dirty).Struct.backing_integer.?;
if (v > 0) self.cells_rebuild = true; const v: Int = @bitCast(state.terminal.screen.dirty);
} if (v > 0) break :rebuild true;
}
break :rebuild false;
};
// Reset the dirty flags in the terminal and screen. We assume // Reset the dirty flags in the terminal and screen. We assume
// that our rebuild will be successful since so we optimize for // that our rebuild will be successful since so we optimize for
@ -923,6 +927,7 @@ pub fn updateFrame(
.preedit = preedit, .preedit = preedit,
.cursor_style = cursor_style, .cursor_style = cursor_style,
.color_palette = state.terminal.color_palette.colors, .color_palette = state.terminal.color_palette.colors,
.full_rebuild = full_rebuild,
}; };
}; };
defer { defer {
@ -932,6 +937,7 @@ pub fn updateFrame(
// Build our GPU cells // Build our GPU cells
try self.rebuildCells( try self.rebuildCells(
critical.full_rebuild,
&critical.screen, &critical.screen,
critical.mouse, critical.mouse,
critical.preedit, critical.preedit,
@ -1799,6 +1805,7 @@ pub fn setScreenSize(
/// memory and doesn't touch the GPU. /// memory and doesn't touch the GPU.
fn rebuildCells( fn rebuildCells(
self: *Metal, self: *Metal,
rebuild: bool,
screen: *terminal.Screen, screen: *terminal.Screen,
mouse: renderer.State.Mouse, mouse: renderer.State.Mouse,
preedit: ?renderer.State.Preedit, preedit: ?renderer.State.Preedit,
@ -1839,6 +1846,9 @@ fn rebuildCells(
}; };
} else null; } else null;
// If we are doing a full rebuild, then we clear the entire cell buffer.
if (rebuild) self.cells.reset();
// Go row-by-row to build the cells. We go row by row because we do // Go row-by-row to build the cells. We go row by row because we do
// font shaping by row. In the future, we will also do dirty tracking // font shaping by row. In the future, we will also do dirty tracking
// by row. // by row.
@ -1847,12 +1857,14 @@ fn rebuildCells(
while (row_it.next()) |row| { while (row_it.next()) |row| {
y = y - 1; y = y - 1;
// Only rebuild if we are doing a full rebuild or this row is dirty. if (!rebuild) {
// if (row.isDirty()) std.log.warn("dirty y={}", .{y}); // Only rebuild if we are doing a full rebuild or this row is dirty.
if (!self.cells_rebuild and !row.isDirty()) continue; // if (row.isDirty()) std.log.warn("dirty y={}", .{y});
if (!row.isDirty()) continue;
// If we're rebuilding a row, then we always clear the cells // Clear the cells if the row is dirty
self.cells.clear(y); self.cells.clear(y);
}
// True if we want to do font shaping around the cursor. We want to // True if we want to do font shaping around the cursor. We want to
// do font shaping as long as the cursor is enabled. // do font shaping as long as the cursor is enabled.
@ -1996,9 +2008,6 @@ fn rebuildCells(
} }
} }
// We always mark our rebuild flag as false since we're done.
self.cells_rebuild = false;
// Update that our cells rebuilt // Update that our cells rebuilt
self.cells_rebuilt = true; self.cells_rebuilt = true;

View File

@ -124,6 +124,13 @@ pub const Contents = struct {
self.text.shrinkAndFree(alloc, text_reserved_len); self.text.shrinkAndFree(alloc, text_reserved_len);
} }
/// Reset the cell contents to an empty state without resizing.
pub fn reset(self: *Contents) void {
@memset(self.map, .{});
self.bgs.clearRetainingCapacity();
self.text.shrinkRetainingCapacity(text_reserved_len);
}
/// Returns the slice of fg cell contents to sync with the GPU. /// Returns the slice of fg cell contents to sync with the GPU.
pub fn fgCells(self: *const Contents) []const mtl_shaders.CellText { pub fn fgCells(self: *const Contents) []const mtl_shaders.CellText {
const start: usize = if (self.cursor) 0 else 1; const start: usize = if (self.cursor) 0 else 1;