renderer: build up render state, rebuild cells with it
parent
a66963e3f8
commit
040d7794af
|
|
@ -207,6 +207,9 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
/// Our shader pipelines.
|
||||
shaders: Shaders,
|
||||
|
||||
/// The render state we update per loop.
|
||||
terminal_state: terminal.RenderState = .empty,
|
||||
|
||||
/// Swap chain which maintains multiple copies of the state needed to
|
||||
/// render a frame, so that we can start building the next frame while
|
||||
/// the previous frame is still being processed on the GPU.
|
||||
|
|
@ -738,6 +741,8 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.terminal_state.deinit(self.alloc);
|
||||
|
||||
self.swap_chain.deinit();
|
||||
|
||||
if (DisplayLink != void) {
|
||||
|
|
@ -1096,6 +1101,9 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
return;
|
||||
}
|
||||
|
||||
// Update our terminal state
|
||||
try self.terminal_state.update(self.alloc, state.terminal);
|
||||
|
||||
// Get our scrollbar out of the terminal. We synchronize
|
||||
// the scrollbar read with frame data updates because this
|
||||
// naturally limits the number of calls to this method (it
|
||||
|
|
@ -2311,6 +2319,86 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||
}
|
||||
}
|
||||
|
||||
fn rebuildCells2(
|
||||
self: *Self,
|
||||
) !void {
|
||||
const state: *terminal.RenderState = &self.terminal_state;
|
||||
|
||||
self.draw_mutex.lock();
|
||||
defer self.draw_mutex.unlock();
|
||||
|
||||
// Handle the case that our grid size doesn't match the terminal
|
||||
// state grid size. It's possible our backing views for renderers
|
||||
// have a mismatch temporarily since view resize is handled async
|
||||
// to terminal state resize and is mostly dependent on GUI
|
||||
// frameworks.
|
||||
const grid_size_diff =
|
||||
self.cells.size.rows != state.rows or
|
||||
self.cells.size.columns != state.cols;
|
||||
if (grid_size_diff) {
|
||||
var new_size = self.cells.size;
|
||||
new_size.rows = state.rows;
|
||||
new_size.columns = state.cols;
|
||||
try self.cells.resize(self.alloc, new_size);
|
||||
|
||||
// Update our uniforms accordingly, otherwise
|
||||
// our background cells will be out of place.
|
||||
self.uniforms.grid_size = .{ new_size.columns, new_size.rows };
|
||||
}
|
||||
|
||||
// Redraw means we are redrawing the full grid, regardless of
|
||||
// individual row dirtiness.
|
||||
const redraw = state.redraw or grid_size_diff;
|
||||
|
||||
if (redraw) {
|
||||
// If we are doing a full rebuild, then we clear the entire
|
||||
// cell buffer.
|
||||
self.cells.reset();
|
||||
|
||||
// We also reset our padding extension depending on the
|
||||
// screen type
|
||||
switch (self.config.padding_color) {
|
||||
.background => {},
|
||||
|
||||
// For extension, assume we are extending in all directions.
|
||||
// For "extend" this may be disabled due to heuristics below.
|
||||
.extend, .@"extend-always" => {
|
||||
self.uniforms.padding_extend = .{
|
||||
.up = true,
|
||||
.down = true,
|
||||
.left = true,
|
||||
.right = true,
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Go through all the rows and rebuild as necessary. If we have
|
||||
// a size mismatch on the state and our grid we just fill what
|
||||
// we can from the BOTTOM of the viewport.
|
||||
const start_idx = state.rows - @min(
|
||||
state.rows,
|
||||
self.cells.size.rows,
|
||||
);
|
||||
const row_data = state.row_data.slice();
|
||||
for (
|
||||
0..,
|
||||
row_data.items(.cells)[start_idx..],
|
||||
row_data.items(.dirty)[start_idx..],
|
||||
) |y, *cell, dirty| {
|
||||
if (!redraw) {
|
||||
// Only rebuild if we are doing a full rebuild or
|
||||
// this row is dirty.
|
||||
if (!dirty) continue;
|
||||
|
||||
// Clear the cells if the row is dirty
|
||||
self.cells.clear(y);
|
||||
}
|
||||
|
||||
_ = cell;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the terminal state to GPU cells stored in CPU memory. These
|
||||
/// are then synced to the GPU in the next frame. This only updates CPU
|
||||
/// memory and doesn't touch the GPU.
|
||||
|
|
|
|||
Loading…
Reference in New Issue