mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
opengl: make setting font size thread safe
This commit is contained in:
@ -105,6 +105,7 @@ surface_mailbox: apprt.surface.Mailbox,
|
||||
/// Some runtimes (GTK) do not support multi-threading so to keep our logic
|
||||
/// simple we apply all OpenGL context changes in the render() call.
|
||||
deferred_screen_size: ?SetScreenSize = null,
|
||||
deferred_font_size: ?SetFontSize = null,
|
||||
|
||||
/// If we're drawing with single threaded operations
|
||||
draw_mutex: DrawMutex = drawMutexZero,
|
||||
@ -157,6 +158,19 @@ const SetScreenSize = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const SetFontSize = struct {
|
||||
metrics: font.face.Metrics,
|
||||
|
||||
fn apply(self: SetFontSize, r: *const OpenGL) !void {
|
||||
try r.program.setUniform(
|
||||
"cell_size",
|
||||
@Vector(2, f32){ self.metrics.cell_width, self.metrics.cell_height },
|
||||
);
|
||||
try r.program.setUniform("strikethrough_position", self.metrics.strikethrough_position);
|
||||
try r.program.setUniform("strikethrough_thickness", self.metrics.strikethrough_thickness);
|
||||
}
|
||||
};
|
||||
|
||||
/// The raw structure that maps directly to the buffer sent to the vertex shader.
|
||||
/// This must be "extern" so that the field order is not reordered by the
|
||||
/// Zig compiler.
|
||||
@ -239,14 +253,11 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
);
|
||||
|
||||
// Setup our font metrics uniform
|
||||
const metrics = try resetFontMetrics(alloc, program, options.font_group);
|
||||
const metrics = try resetFontMetrics(alloc, options.font_group);
|
||||
|
||||
// Set our cell dimensions
|
||||
const pbind = try program.use();
|
||||
defer pbind.unbind();
|
||||
try program.setUniform("cell_size", @Vector(2, f32){ metrics.cell_width, metrics.cell_height });
|
||||
try program.setUniform("strikethrough_position", metrics.strikethrough_position);
|
||||
try program.setUniform("strikethrough_thickness", metrics.strikethrough_thickness);
|
||||
|
||||
// Set all of our texture indexes
|
||||
try program.setUniform("text", 0);
|
||||
@ -379,6 +390,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
.focused = true,
|
||||
.padding = options.padding,
|
||||
.surface_mailbox = options.surface_mailbox,
|
||||
.deferred_font_size = .{ .metrics = metrics },
|
||||
};
|
||||
}
|
||||
|
||||
@ -571,8 +583,10 @@ pub fn blinkCursor(self: *OpenGL, reset: bool) void {
|
||||
///
|
||||
/// Must be called on the render thread.
|
||||
pub fn setFontSize(self: *OpenGL, size: font.face.DesiredSize) !void {
|
||||
if (single_threaded_draw) self.draw_mutex.lock();
|
||||
defer if (single_threaded_draw) self.draw_mutex.unlock();
|
||||
|
||||
log.info("set font size={}", .{size});
|
||||
if (apprt.runtime == apprt.gtk) @panic("TODO: make thread safe");
|
||||
|
||||
// Set our new size, this will also reset our font atlas.
|
||||
try self.font_group.setSize(size);
|
||||
@ -581,7 +595,10 @@ pub fn setFontSize(self: *OpenGL, size: font.face.DesiredSize) !void {
|
||||
self.resetCellsLRU();
|
||||
|
||||
// Reset our GPU uniforms
|
||||
const metrics = try resetFontMetrics(self.alloc, self.program, self.font_group);
|
||||
const metrics = try resetFontMetrics(self.alloc, self.font_group);
|
||||
|
||||
// Defer our GPU updates
|
||||
self.deferred_font_size = .{ .metrics = metrics };
|
||||
|
||||
// Recalculate our cell size. If it is the same as before, then we do
|
||||
// nothing since the grid size couldn't have possibly changed.
|
||||
@ -599,7 +616,6 @@ pub fn setFontSize(self: *OpenGL, size: font.face.DesiredSize) !void {
|
||||
/// down to the GPU.
|
||||
fn resetFontMetrics(
|
||||
alloc: Allocator,
|
||||
program: gl.Program,
|
||||
font_group: *font.GroupCache,
|
||||
) !font.face.Metrics {
|
||||
// Get our cell metrics based on a regular font ascii 'M'. Why 'M'?
|
||||
@ -620,13 +636,6 @@ fn resetFontMetrics(
|
||||
.underline_position = @floatToInt(u32, metrics.underline_position),
|
||||
};
|
||||
|
||||
// Set our uniforms that rely on metrics
|
||||
const pbind = try program.use();
|
||||
defer pbind.unbind();
|
||||
try program.setUniform("cell_size", @Vector(2, f32){ metrics.cell_width, metrics.cell_height });
|
||||
try program.setUniform("strikethrough_position", metrics.strikethrough_position);
|
||||
try program.setUniform("strikethrough_thickness", metrics.strikethrough_thickness);
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@ -1173,6 +1182,9 @@ fn gridSize(self: *const OpenGL, screen_size: renderer.ScreenSize) renderer.Grid
|
||||
/// Set the screen size for rendering. This will update the projection
|
||||
/// used for the shader so that the scaling of the grid is correct.
|
||||
pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void {
|
||||
if (single_threaded_draw) self.draw_mutex.lock();
|
||||
defer if (single_threaded_draw) self.draw_mutex.unlock();
|
||||
|
||||
// Recalculate the rows/columns.
|
||||
const grid_size = self.gridSize(dim);
|
||||
|
||||
@ -1329,6 +1341,10 @@ pub fn draw(self: *OpenGL) !void {
|
||||
try v.apply(self);
|
||||
self.deferred_screen_size = null;
|
||||
}
|
||||
if (self.deferred_font_size) |v| {
|
||||
try v.apply(self);
|
||||
self.deferred_font_size = null;
|
||||
}
|
||||
|
||||
try self.drawCells(binding, self.cells_bg);
|
||||
try self.drawCells(binding, self.cells);
|
||||
|
Reference in New Issue
Block a user