fix(renderer): rebuild font grid and reset shaper cache on hot reload

When hot reloading config with a new font, shaper cache data needs to be
invalidated and the font grid needs to be rebuilt. This change just
makes that happen on all config reloads since it's a rare action so it's
not a performance concern.
This commit is contained in:
Qwerasd
2024-05-10 00:15:10 -04:00
committed by Mitchell Hashimoto
parent f410c9535f
commit ac5725d582
3 changed files with 38 additions and 2 deletions

View File

@ -757,6 +757,13 @@ fn changeConfig(self: *Surface, config: *const configpkg.Config) !void {
self.showMouse();
}
// Before sending any other config changes, we give the renderer a new font
// grid. We could check to see if there was an actual change to the font,
// but this is easier and pretty rare so it's not a performance concern.
//
// (Calling setFontSize builds and sends a new font grid to the renderer.)
try self.setFontSize(self.font_size);
// We need to store our configs in a heap-allocated pointer so that
// our messages aren't huge.
var renderer_message = try renderer.Message.initChangeConfig(self.alloc, config);

View File

@ -783,7 +783,7 @@ pub fn setVisible(self: *Metal, visible: bool) void {
}
}
/// Set the new font size.
/// Set the new font grid.
///
/// Must be called on the render thread.
pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
@ -812,6 +812,13 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
log.err("error resizing cells buffer err={}", .{err});
};
// Reset our shaper cache. If our font changed (not just the size) then
// the data in the shaper cache may be invalid and cannot be used, so we
// always clear the cache just in case.
const font_shaper_cache = font.ShaperCache.init();
self.font_shaper_cache.deinit(self.alloc);
self.font_shaper_cache = font_shaper_cache;
// Reset our viewport to force a rebuild
self.cells_viewport = null;
@ -1726,6 +1733,12 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void {
self.font_shaper = font_shaper;
}
// We also need to reset the shaper cache so shaper info
// from the previous font isn't re-used for the new font.
const font_shaper_cache = font.ShaperCache.init();
self.font_shaper_cache.deinit(self.alloc);
self.font_shaper_cache = font_shaper_cache;
// Set our new minimum contrast
self.uniforms.min_contrast = config.min_contrast;
@ -1736,6 +1749,9 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void {
self.config.deinit();
self.config = config.*;
// Reset our viewport to force a rebuild, in case of a font change.
self.cells_viewport = null;
}
/// Resize the screen.

View File

@ -595,7 +595,7 @@ pub fn setVisible(self: *OpenGL, visible: bool) void {
_ = visible;
}
/// Set the new font size.
/// Set the new font grid.
///
/// Must be called on the render thread.
pub fn setFontGrid(self: *OpenGL, grid: *font.SharedGrid) void {
@ -610,6 +610,13 @@ pub fn setFontGrid(self: *OpenGL, grid: *font.SharedGrid) void {
self.texture_color_modified = 0;
self.texture_color_resized = 0;
// Reset our shaper cache. If our font changed (not just the size) then
// the data in the shaper cache may be invalid and cannot be used, so we
// always clear the cache just in case.
const font_shaper_cache = font.ShaperCache.init();
self.font_shaper_cache.deinit(self.alloc);
self.font_shaper_cache = font_shaper_cache;
// Defer our GPU updates
self.deferred_font_size = .{ .metrics = grid.metrics };
}
@ -1577,6 +1584,12 @@ pub fn changeConfig(self: *OpenGL, config: *DerivedConfig) !void {
self.font_shaper = font_shaper;
}
// We also need to reset the shaper cache so shaper info
// from the previous font isn't re-used for the new font.
const font_shaper_cache = font.ShaperCache.init();
self.font_shaper_cache.deinit(self.alloc);
self.font_shaper_cache = font_shaper_cache;
// Set our new colors
self.background_color = config.background;
self.foreground_color = config.foreground;