mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
rename grid to a renderer, extract to subfolder
"Grid" was a really antiquated name when it had both the screen state AND the renderering functionality tied together. This hasn't been true for a LONG time and it is long overdue that this is renamed to its proper name. This also begins setting up a folder structure to anticipate future renderers and rendering functionality. I'm not working on any alternate renderers right now so the interface isn't expected to be good, just laying out the files in this way.
This commit is contained in:
@ -45,13 +45,13 @@ pub fn update(self: *DevMode) !void {
|
|||||||
if (imgui.treeNode("Atlas: Greyscale", .{ .default_open = true })) {
|
if (imgui.treeNode("Atlas: Greyscale", .{ .default_open = true })) {
|
||||||
defer imgui.treePop();
|
defer imgui.treePop();
|
||||||
const atlas = &window.font_group.atlas_greyscale;
|
const atlas = &window.font_group.atlas_greyscale;
|
||||||
try self.atlasInfo(atlas, @intCast(usize, window.grid.texture.id));
|
try self.atlasInfo(atlas, @intCast(usize, window.renderer.texture.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgui.treeNode("Atlas: Color (Emoji)", .{ .default_open = true })) {
|
if (imgui.treeNode("Atlas: Color (Emoji)", .{ .default_open = true })) {
|
||||||
defer imgui.treePop();
|
defer imgui.treePop();
|
||||||
const atlas = &window.font_group.atlas_color;
|
const atlas = &window.font_group.atlas_color;
|
||||||
try self.atlasInfo(atlas, @intCast(usize, window.grid.texture_color.id));
|
try self.atlasInfo(atlas, @intCast(usize, window.renderer.texture_color.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Grid = @import("Grid.zig");
|
const renderer = @import("renderer.zig");
|
||||||
const glfw = @import("glfw");
|
const glfw = @import("glfw");
|
||||||
const gl = @import("opengl.zig");
|
const gl = @import("opengl.zig");
|
||||||
const imgui = @import("imgui");
|
const imgui = @import("imgui");
|
||||||
@ -53,8 +53,8 @@ imgui_ctx: if (DevMode.enabled) *imgui.Context else void,
|
|||||||
/// Whether the window is currently focused
|
/// Whether the window is currently focused
|
||||||
focused: bool,
|
focused: bool,
|
||||||
|
|
||||||
/// The terminal grid attached to this window.
|
/// The renderer for this window.
|
||||||
grid: Grid,
|
renderer: renderer.OpenGL,
|
||||||
|
|
||||||
/// The underlying pty for this window.
|
/// The underlying pty for this window.
|
||||||
pty: Pty,
|
pty: Pty,
|
||||||
@ -368,14 +368,14 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
|
|
||||||
// Create our terminal grid with the initial window size
|
// Create our terminal grid with the initial window size
|
||||||
const window_size = try window.getSize();
|
const window_size = try window.getSize();
|
||||||
var grid = try Grid.init(alloc, font_group);
|
var renderer_impl = try renderer.OpenGL.init(alloc, font_group);
|
||||||
try grid.setScreenSize(.{ .width = window_size.width, .height = window_size.height });
|
try renderer_impl.setScreenSize(.{ .width = window_size.width, .height = window_size.height });
|
||||||
grid.background = .{
|
renderer_impl.background = .{
|
||||||
.r = config.background.r,
|
.r = config.background.r,
|
||||||
.g = config.background.g,
|
.g = config.background.g,
|
||||||
.b = config.background.b,
|
.b = config.background.b,
|
||||||
};
|
};
|
||||||
grid.foreground = .{
|
renderer_impl.foreground = .{
|
||||||
.r = config.foreground.r,
|
.r = config.foreground.r,
|
||||||
.g = config.foreground.g,
|
.g = config.foreground.g,
|
||||||
.b = config.foreground.b,
|
.b = config.foreground.b,
|
||||||
@ -384,14 +384,14 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
// Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app
|
// Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app
|
||||||
// but is otherwise somewhat arbitrary.
|
// but is otherwise somewhat arbitrary.
|
||||||
try window.setSizeLimits(.{
|
try window.setSizeLimits(.{
|
||||||
.width = @floatToInt(u32, grid.cell_size.width * 10),
|
.width = @floatToInt(u32, renderer_impl.cell_size.width * 10),
|
||||||
.height = @floatToInt(u32, grid.cell_size.height * 4),
|
.height = @floatToInt(u32, renderer_impl.cell_size.height * 4),
|
||||||
}, .{ .width = null, .height = null });
|
}, .{ .width = null, .height = null });
|
||||||
|
|
||||||
// Create our pty
|
// Create our pty
|
||||||
var pty = try Pty.open(.{
|
var pty = try Pty.open(.{
|
||||||
.ws_row = @intCast(u16, grid.size.rows),
|
.ws_row = @intCast(u16, renderer_impl.size.rows),
|
||||||
.ws_col = @intCast(u16, grid.size.columns),
|
.ws_col = @intCast(u16, renderer_impl.size.columns),
|
||||||
.ws_xpixel = @intCast(u16, window_size.width),
|
.ws_xpixel = @intCast(u16, window_size.width),
|
||||||
.ws_ypixel = @intCast(u16, window_size.height),
|
.ws_ypixel = @intCast(u16, window_size.height),
|
||||||
});
|
});
|
||||||
@ -434,7 +434,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
try stream.readStart(ttyReadAlloc, ttyRead);
|
try stream.readStart(ttyReadAlloc, ttyRead);
|
||||||
|
|
||||||
// Create our terminal
|
// Create our terminal
|
||||||
var term = try terminal.Terminal.init(alloc, grid.size.columns, grid.size.rows);
|
var term = try terminal.Terminal.init(alloc, renderer_impl.size.columns, renderer_impl.size.rows);
|
||||||
errdefer term.deinit(alloc);
|
errdefer term.deinit(alloc);
|
||||||
|
|
||||||
// Setup a timer for blinking the cursor
|
// Setup a timer for blinking the cursor
|
||||||
@ -463,7 +463,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
.window = window,
|
.window = window,
|
||||||
.cursor = cursor,
|
.cursor = cursor,
|
||||||
.focused = false,
|
.focused = false,
|
||||||
.grid = grid,
|
.renderer = renderer_impl,
|
||||||
.pty = pty,
|
.pty = pty,
|
||||||
.command = cmd,
|
.command = cmd,
|
||||||
.mouse = .{},
|
.mouse = .{},
|
||||||
@ -556,7 +556,7 @@ pub fn destroy(self: *Window) void {
|
|||||||
log.err("error waiting for command to exit: {}", .{err});
|
log.err("error waiting for command to exit: {}", .{err});
|
||||||
|
|
||||||
self.terminal.deinit(self.alloc);
|
self.terminal.deinit(self.alloc);
|
||||||
self.grid.deinit();
|
self.renderer.deinit();
|
||||||
self.window.destroy();
|
self.window.destroy();
|
||||||
|
|
||||||
self.terminal_cursor.timer.close((struct {
|
self.terminal_cursor.timer.close((struct {
|
||||||
@ -662,19 +662,19 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
|
|||||||
|
|
||||||
// Update our grid so that the projections on render are correct.
|
// Update our grid so that the projections on render are correct.
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
const win = window.getUserPointer(Window) orelse return;
|
||||||
win.grid.setScreenSize(.{
|
win.renderer.setScreenSize(.{
|
||||||
.width = px_size.width,
|
.width = px_size.width,
|
||||||
.height = px_size.height,
|
.height = px_size.height,
|
||||||
}) catch |err| log.err("error updating grid screen size err={}", .{err});
|
}) catch |err| log.err("error updating grid screen size err={}", .{err});
|
||||||
|
|
||||||
// Update the size of our terminal state
|
// Update the size of our terminal state
|
||||||
win.terminal.resize(win.alloc, win.grid.size.columns, win.grid.size.rows) catch |err|
|
win.terminal.resize(win.alloc, win.renderer.size.columns, win.renderer.size.rows) catch |err|
|
||||||
log.err("error updating terminal size: {}", .{err});
|
log.err("error updating terminal size: {}", .{err});
|
||||||
|
|
||||||
// Update the size of our pty
|
// Update the size of our pty
|
||||||
win.pty.setSize(.{
|
win.pty.setSize(.{
|
||||||
.ws_row = @intCast(u16, win.grid.size.rows),
|
.ws_row = @intCast(u16, win.renderer.size.rows),
|
||||||
.ws_col = @intCast(u16, win.grid.size.columns),
|
.ws_col = @intCast(u16, win.renderer.size.columns),
|
||||||
.ws_xpixel = @intCast(u16, width),
|
.ws_xpixel = @intCast(u16, width),
|
||||||
.ws_ypixel = @intCast(u16, height),
|
.ws_ypixel = @intCast(u16, height),
|
||||||
}) catch |err| log.err("error updating pty screen size err={}", .{err});
|
}) catch |err| log.err("error updating pty screen size err={}", .{err});
|
||||||
@ -1007,7 +1007,7 @@ fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void {
|
|||||||
|
|
||||||
// Positive is up
|
// Positive is up
|
||||||
const sign: isize = if (yoff > 0) -1 else 1;
|
const sign: isize = if (yoff > 0) -1 else 1;
|
||||||
const delta: isize = sign * @max(@divFloor(win.grid.size.rows, 15), 1);
|
const delta: isize = sign * @max(@divFloor(win.renderer.size.rows, 15), 1);
|
||||||
log.info("scroll: delta={}", .{delta});
|
log.info("scroll: delta={}", .{delta});
|
||||||
win.terminal.scrollViewport(.{ .delta = delta }) catch |err|
|
win.terminal.scrollViewport(.{ .delta = delta }) catch |err|
|
||||||
log.err("error scrolling viewport err={}", .{err});
|
log.err("error scrolling viewport err={}", .{err});
|
||||||
@ -1367,10 +1367,10 @@ fn cursorPosCallback(
|
|||||||
//
|
//
|
||||||
|
|
||||||
// the boundary point at which we consider selection or non-selection
|
// the boundary point at which we consider selection or non-selection
|
||||||
const cell_xboundary = win.grid.cell_size.width * 0.6;
|
const cell_xboundary = win.renderer.cell_size.width * 0.6;
|
||||||
|
|
||||||
// first xpos of the clicked cell
|
// first xpos of the clicked cell
|
||||||
const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.grid.cell_size.width;
|
const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.renderer.cell_size.width;
|
||||||
const cell_start_xpos = win.mouse.left_click_xpos - cell_xstart;
|
const cell_start_xpos = win.mouse.left_click_xpos - cell_xstart;
|
||||||
|
|
||||||
// If this is the same cell, then we only start the selection if weve
|
// If this is the same cell, then we only start the selection if weve
|
||||||
@ -1445,7 +1445,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport {
|
|||||||
return .{
|
return .{
|
||||||
.x = if (xpos < 0) 0 else x: {
|
.x = if (xpos < 0) 0 else x: {
|
||||||
// Our cell is the mouse divided by cell width
|
// Our cell is the mouse divided by cell width
|
||||||
const cell_width = @floatCast(f64, self.grid.cell_size.width);
|
const cell_width = @floatCast(f64, self.renderer.cell_size.width);
|
||||||
const x = @floatToInt(usize, xpos / cell_width);
|
const x = @floatToInt(usize, xpos / cell_width);
|
||||||
|
|
||||||
// Can be off the screen if the user drags it out, so max
|
// Can be off the screen if the user drags it out, so max
|
||||||
@ -1454,7 +1454,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.y = if (ypos < 0) 0 else y: {
|
.y = if (ypos < 0) 0 else y: {
|
||||||
const cell_height = @floatCast(f64, self.grid.cell_size.height);
|
const cell_height = @floatCast(f64, self.renderer.cell_size.height);
|
||||||
const y = @floatToInt(usize, ypos / cell_height);
|
const y = @floatToInt(usize, ypos / cell_height);
|
||||||
break :y @min(y, self.terminal.rows - 1);
|
break :y @min(y, self.terminal.rows - 1);
|
||||||
},
|
},
|
||||||
@ -1584,23 +1584,23 @@ fn renderTimerCallback(t: *libuv.Timer) void {
|
|||||||
|
|
||||||
// Setup our cursor settings
|
// Setup our cursor settings
|
||||||
if (win.focused) {
|
if (win.focused) {
|
||||||
win.grid.cursor_visible = win.terminal_cursor.visible and !win.terminal_cursor.blink;
|
win.renderer.cursor_visible = win.terminal_cursor.visible and !win.terminal_cursor.blink;
|
||||||
win.grid.cursor_style = Grid.CursorStyle.fromTerminal(win.terminal_cursor.style) orelse .box;
|
win.renderer.cursor_style = renderer.OpenGL.CursorStyle.fromTerminal(win.terminal_cursor.style) orelse .box;
|
||||||
} else {
|
} else {
|
||||||
win.grid.cursor_visible = true;
|
win.renderer.cursor_visible = true;
|
||||||
win.grid.cursor_style = .box_hollow;
|
win.renderer.cursor_style = .box_hollow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate foreground and background colors
|
// Calculate foreground and background colors
|
||||||
const bg = win.grid.background;
|
const bg = win.renderer.background;
|
||||||
const fg = win.grid.foreground;
|
const fg = win.renderer.foreground;
|
||||||
defer {
|
defer {
|
||||||
win.grid.background = bg;
|
win.renderer.background = bg;
|
||||||
win.grid.foreground = fg;
|
win.renderer.foreground = fg;
|
||||||
}
|
}
|
||||||
if (win.terminal.modes.reverse_colors) {
|
if (win.terminal.modes.reverse_colors) {
|
||||||
win.grid.background = fg;
|
win.renderer.background = fg;
|
||||||
win.grid.foreground = bg;
|
win.renderer.foreground = bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our background
|
// Set our background
|
||||||
@ -1624,15 +1624,15 @@ fn renderTimerCallback(t: *libuv.Timer) void {
|
|||||||
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// For now, rebuild all cells
|
// For now, rebuild all cells
|
||||||
win.grid.rebuildCells(&win.terminal) catch |err|
|
win.renderer.rebuildCells(&win.terminal) catch |err|
|
||||||
log.err("error calling rebuildCells in render timer err={}", .{err});
|
log.err("error calling rebuildCells in render timer err={}", .{err});
|
||||||
|
|
||||||
// Finalize the cells prior to render
|
// Finalize the cells prior to render
|
||||||
win.grid.finalizeCells(&win.terminal) catch |err|
|
win.renderer.finalizeCells(&win.terminal) catch |err|
|
||||||
log.err("error calling updateCells in render timer err={}", .{err});
|
log.err("error calling updateCells in render timer err={}", .{err});
|
||||||
|
|
||||||
// Render the grid
|
// Render the grid
|
||||||
win.grid.render() catch |err| {
|
win.renderer.render() catch |err| {
|
||||||
log.err("error rendering grid: {}", .{err});
|
log.err("error rendering grid: {}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -1812,7 +1812,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void {
|
|||||||
self.terminal.setDeccolmSupported(enabled);
|
self.terminal.setDeccolmSupported(enabled);
|
||||||
|
|
||||||
// Force resize back to the window size
|
// Force resize back to the window size
|
||||||
self.terminal.resize(self.alloc, self.grid.size.columns, self.grid.size.rows) catch |err|
|
self.terminal.resize(self.alloc, self.renderer.size.columns, self.renderer.size.rows) catch |err|
|
||||||
log.err("error updating terminal size: {}", .{err});
|
log.err("error updating terminal size: {}", .{err});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -105,16 +105,15 @@ fn glfwErrorCallback(code: glfw.Error, desc: [:0]const u8) void {
|
|||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("Atlas.zig");
|
_ = @import("Atlas.zig");
|
||||||
_ = @import("Grid.zig");
|
|
||||||
_ = @import("Pty.zig");
|
_ = @import("Pty.zig");
|
||||||
_ = @import("Command.zig");
|
_ = @import("Command.zig");
|
||||||
_ = @import("TempDir.zig");
|
_ = @import("TempDir.zig");
|
||||||
_ = @import("font/main.zig");
|
_ = @import("font/main.zig");
|
||||||
|
_ = @import("renderer.zig");
|
||||||
_ = @import("terminal/Terminal.zig");
|
_ = @import("terminal/Terminal.zig");
|
||||||
_ = @import("input.zig");
|
_ = @import("input.zig");
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
_ = @import("libuv");
|
|
||||||
_ = @import("segmented_pool.zig");
|
_ = @import("segmented_pool.zig");
|
||||||
_ = @import("terminal/main.zig");
|
_ = @import("terminal/main.zig");
|
||||||
|
|
||||||
|
14
src/renderer.zig
Normal file
14
src/renderer.zig
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//! Renderer implementation and utilities. The renderer is responsible for
|
||||||
|
//! taking the internal screen state and turning into some output format,
|
||||||
|
//! usually for a screen.
|
||||||
|
//!
|
||||||
|
//! The renderer is closely tied to the windowing system which usually
|
||||||
|
//! has to prepare the window for the given renderer using system-specific
|
||||||
|
//! APIs. The renderers in this package assume that the renderer is already
|
||||||
|
//! setup (OpenGL has a context, Vulkan has a surface, etc.)
|
||||||
|
|
||||||
|
pub const OpenGL = @import("renderer/OpenGL.zig");
|
||||||
|
|
||||||
|
test {
|
||||||
|
@import("std").testing.refAllDecls(@This());
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
//! Represents a single terminal grid.
|
//! Rendering implementation for OpenGL.
|
||||||
const Grid = @This();
|
pub const OpenGL = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Atlas = @import("Atlas.zig");
|
const Atlas = @import("../Atlas.zig");
|
||||||
const font = @import("font/main.zig");
|
const font = @import("../font/main.zig");
|
||||||
const terminal = @import("terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const Terminal = terminal.Terminal;
|
const Terminal = terminal.Terminal;
|
||||||
const gl = @import("opengl.zig");
|
const gl = @import("../opengl.zig");
|
||||||
const trace = @import("tracy").trace;
|
const trace = @import("tracy").trace;
|
||||||
const math = @import("math.zig");
|
const math = @import("../math.zig");
|
||||||
const lru = @import("lru.zig");
|
const lru = @import("../lru.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.grid);
|
const log = std.log.scoped(.grid);
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ const GPUCellMode = enum(u8) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(alloc: Allocator, font_group: *font.GroupCache) !Grid {
|
pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL {
|
||||||
// Create the initial font shaper
|
// Create the initial font shaper
|
||||||
var shape_buf = try alloc.alloc(font.Shaper.Cell, 1);
|
var shape_buf = try alloc.alloc(font.Shaper.Cell, 1);
|
||||||
errdefer alloc.free(shape_buf);
|
errdefer alloc.free(shape_buf);
|
||||||
@ -171,8 +171,8 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !Grid {
|
|||||||
|
|
||||||
// Create our shader
|
// Create our shader
|
||||||
const program = try gl.Program.createVF(
|
const program = try gl.Program.createVF(
|
||||||
@embedFile("./shaders/cell.v.glsl"),
|
@embedFile("../shaders/cell.v.glsl"),
|
||||||
@embedFile("./shaders/cell.f.glsl"),
|
@embedFile("../shaders/cell.f.glsl"),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set our cell dimensions
|
// Set our cell dimensions
|
||||||
@ -284,7 +284,7 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !Grid {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Grid{
|
return OpenGL{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.cells = .{},
|
.cells = .{},
|
||||||
.cells_lru = CellsLRU.init(0),
|
.cells_lru = CellsLRU.init(0),
|
||||||
@ -305,7 +305,7 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !Grid {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Grid) void {
|
pub fn deinit(self: *OpenGL) void {
|
||||||
self.font_shaper.deinit();
|
self.font_shaper.deinit();
|
||||||
self.alloc.free(self.font_shaper.cell_buf);
|
self.alloc.free(self.font_shaper.cell_buf);
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ pub fn deinit(self: *Grid) void {
|
|||||||
///
|
///
|
||||||
/// Note this doesn't have to typically be manually called. Internally,
|
/// Note this doesn't have to typically be manually called. Internally,
|
||||||
/// the renderer will do this when it needs more memory space.
|
/// the renderer will do this when it needs more memory space.
|
||||||
pub fn rebuildCells(self: *Grid, term: *Terminal) !void {
|
pub fn rebuildCells(self: *OpenGL, term: *Terminal) !void {
|
||||||
const t = trace(@src());
|
const t = trace(@src());
|
||||||
defer t.end();
|
defer t.end();
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ pub fn rebuildCells(self: *Grid, term: *Terminal) !void {
|
|||||||
/// This should be called prior to render to finalize the cells and prepare
|
/// This should be called prior to render to finalize the cells and prepare
|
||||||
/// for render. This performs tasks such as preparing the cursor, refreshing
|
/// for render. This performs tasks such as preparing the cursor, refreshing
|
||||||
/// the cells if necessary, etc.
|
/// the cells if necessary, etc.
|
||||||
pub fn finalizeCells(self: *Grid, term: *Terminal) !void {
|
pub fn finalizeCells(self: *OpenGL, term: *Terminal) !void {
|
||||||
// If we're out of space or we have no more Z-space, rebuild.
|
// If we're out of space or we have no more Z-space, rebuild.
|
||||||
if (self.cells.items.len == self.cells.capacity) {
|
if (self.cells.items.len == self.cells.capacity) {
|
||||||
log.info("cell cache full, rebuilding from scratch", .{});
|
log.info("cell cache full, rebuilding from scratch", .{});
|
||||||
@ -468,7 +468,7 @@ pub fn finalizeCells(self: *Grid, term: *Terminal) !void {
|
|||||||
try self.flushAtlas();
|
try self.flushAtlas();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addCursor(self: *Grid, term: *Terminal) void {
|
fn addCursor(self: *OpenGL, term: *Terminal) void {
|
||||||
// Add the cursor
|
// Add the cursor
|
||||||
if (self.cursor_visible and term.screen.viewportIsBottom()) {
|
if (self.cursor_visible and term.screen.viewportIsBottom()) {
|
||||||
const cell = term.screen.getCell(
|
const cell = term.screen.getCell(
|
||||||
@ -503,7 +503,7 @@ fn addCursor(self: *Grid, term: *Terminal) void {
|
|||||||
/// or not. If the cell wasn't updated, a full refreshCells call is
|
/// or not. If the cell wasn't updated, a full refreshCells call is
|
||||||
/// needed.
|
/// needed.
|
||||||
pub fn updateCell(
|
pub fn updateCell(
|
||||||
self: *Grid,
|
self: *OpenGL,
|
||||||
term: *Terminal,
|
term: *Terminal,
|
||||||
cell: terminal.Screen.Cell,
|
cell: terminal.Screen.Cell,
|
||||||
shaper_cell: font.Shaper.Cell,
|
shaper_cell: font.Shaper.Cell,
|
||||||
@ -690,7 +690,7 @@ pub fn updateCell(
|
|||||||
|
|
||||||
/// Set the screen size for rendering. This will update the projection
|
/// Set the screen size for rendering. This will update the projection
|
||||||
/// used for the shader so that the scaling of the grid is correct.
|
/// used for the shader so that the scaling of the grid is correct.
|
||||||
pub fn setScreenSize(self: *Grid, dim: ScreenSize) !void {
|
pub fn setScreenSize(self: *OpenGL, dim: ScreenSize) !void {
|
||||||
// Update the projection uniform within our shader
|
// Update the projection uniform within our shader
|
||||||
const bind = try self.program.use();
|
const bind = try self.program.use();
|
||||||
defer bind.unbind();
|
defer bind.unbind();
|
||||||
@ -725,7 +725,7 @@ pub fn setScreenSize(self: *Grid, dim: ScreenSize) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the font texture atlas if it is dirty.
|
/// Updates the font texture atlas if it is dirty.
|
||||||
fn flushAtlas(self: *Grid) !void {
|
fn flushAtlas(self: *OpenGL) !void {
|
||||||
{
|
{
|
||||||
const atlas = &self.font_group.atlas_greyscale;
|
const atlas = &self.font_group.atlas_greyscale;
|
||||||
if (atlas.modified) {
|
if (atlas.modified) {
|
||||||
@ -797,7 +797,7 @@ fn flushAtlas(self: *Grid) !void {
|
|||||||
|
|
||||||
/// Render renders the current cell state. This will not modify any of
|
/// Render renders the current cell state. This will not modify any of
|
||||||
/// the cells.
|
/// the cells.
|
||||||
pub fn render(self: *Grid) !void {
|
pub fn render(self: *OpenGL) !void {
|
||||||
const t = trace(@src());
|
const t = trace(@src());
|
||||||
defer t.end();
|
defer t.end();
|
||||||
|
|
Reference in New Issue
Block a user