diff --git a/src/Grid.zig b/src/Grid.zig index ad5ec0f92..0b72b2a2d 100644 --- a/src/Grid.zig +++ b/src/Grid.zig @@ -58,6 +58,9 @@ foreground: terminal.color.RGB, /// Default background color background: terminal.color.RGB, +/// The current value of the Z buffer. +cell_z: u16 = 0, + /// Available cursor styles for drawing. The values represents the mode value /// in the shader. pub const CursorStyle = enum(u8) { @@ -307,12 +310,18 @@ pub fn rebuildCells(self: *Grid, term: Terminal) !void { // We've written no data to the GPU, refresh it all self.gl_cells_written = 0; + // Reset the Z buffer at the end no matter what since we're fresh. + defer self.cell_z = 0; + // Build each cell var rowIter = term.screen.rowIterator(.viewport); var y: usize = 0; while (rowIter.next()) |line| { defer y += 1; - for (line) |cell, x| assert(try self.updateCell(term, cell, x, y)); + for (line) |cell, x| { + self.cell_z = 0; + assert(try self.updateCell(term, cell, x, y)); + } } // Add the cursor @@ -328,8 +337,10 @@ pub fn finalizeCells(self: *Grid, term: Terminal) !void { if (self.cells.items.len < self.cells.capacity) self.addCursor(term); - // If we're out of space, rebuild - if (self.cells.items.len == self.cells.capacity) { + // If we're out of space or we have no more Z-space, rebuild. + if (self.cells.items.len == self.cells.capacity or + self.cell_z == std.math.maxInt(@TypeOf(self.cell_z))) + { log.info("cell cache full, rebuilding from scratch", .{}); try self.rebuildCells(term); } @@ -434,13 +445,25 @@ pub fn updateCell( }; if (self.cells.items.len + needed > self.cells.capacity) return false; + // Bump our Z value. The "zbump" is the max amount we could increase + // the Z value this call. If it could theoretically go over the max + // int size of the Z type, then we return false -- we need a rebuild. + const zbump = 2; + const zmax = std.math.maxInt(@TypeOf(self.cell_z)); + const zmax_padded = zmax - (zbump * 2); + if (self.cell_z > zmax_padded) { + self.cell_z = zmax; + return false; + } + self.cell_z += zbump; + // If the cell has a background, we always draw it. if (colors.bg) |rgb| { self.cells.appendAssumeCapacity(.{ .mode = 1, .grid_col = @intCast(u16, x), .grid_row = @intCast(u16, y), - .grid_z = 0, + .grid_z = self.cell_z, .glyph_x = 0, .glyph_y = 0, .glyph_width = 0, @@ -479,7 +502,7 @@ pub fn updateCell( .mode = 2, .grid_col = @intCast(u16, x), .grid_row = @intCast(u16, y), - .grid_z = 1, + .grid_z = self.cell_z + 1, .glyph_x = glyph.atlas_x, .glyph_y = glyph.atlas_y, .glyph_width = glyph.width, @@ -502,7 +525,7 @@ pub fn updateCell( .mode = 6, // underline .grid_col = @intCast(u16, x), .grid_row = @intCast(u16, y), - .grid_z = 1, + .grid_z = self.cell_z + 1, .glyph_x = 0, .glyph_y = 0, .glyph_width = 0,