From 4e224b7c7e67fafcbe7359fcf534048e254b701d Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 13:19:08 -0300 Subject: The theme's chrome is worked out once, not per grapheme; still post passes let the GUI rest; a perf gate somtrmsz's contrast floors made ChromeTheme.fromTheme run its focus-tint and separator searches (pow calls each), and Output's RowDecoration.styleAt called it for every grapheme of every highlighted row: the 50k-line file's render went from 0.11 ms to 13 ms. Pardes.bodyChrome now keeps the theme's chrome, worked out again only when the theme differs; recolorSyntax asks for it once a decorated row, and a plain row (nearly every row of a file) never asks. ReleaseFast, medium fixture, median us, before -> after (main): render 13150 -> 76 (111), key-down 14658 -> 79 (110), wheel 13589 -> 76 (109), open 14891 -> 2095 (2055), edit-char 16703 -> 3006 (1251; the rest of that gap is editing and tree-sitter, not this). Post.animating asked for frames whenever the window had focus and any pass was ready, so a still pass kept the GUI drawing at the display's rate (Bloom: 49% of a core idle, in a hidden test window). A pass now says whether it moves on its own: the CRT (its hum and dither) and a Shadertoy file whose source reads iTime, iFrame or iDate (shader_build.readsTime; the flag rides the wire's post message); Bloom, Vignette and Grain are still. Bloom idle: 49% -> 1.2%, as with no pass. zig build perf-gate: the 50k-line file's gestures, each's fastest sample within 3x of the recorded baseline's (test/perf-baseline-- .json, recorded from this build), run with every unit-test. On the regressed code it fails at 180x for render. --- src/pardes.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/pardes.zig') diff --git a/src/pardes.zig b/src/pardes.zig index 1f136f2b..ae04b4e7 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -4380,6 +4380,8 @@ pub const Pardes = struct { tty_filter_palette: panes.Terminal.FilterPalette = .{}, font_request_taken: bool = false, custom_theme: ?Theme = null, + /// bodyChrome's: the theme it was worked out for, and it. + body_chrome: ?struct { theme: Theme, chrome: ChromeTheme } = null, theme_file_path: config.Runtime.Text(limits.host_path_cap) = .{}, theme_file_generation: u32 = 0, theme_file_pane: u8 = 0, @@ -7063,6 +7065,16 @@ pub const Pardes = struct { return &p.chrome_animation.displayed; } + /// The theme's own chrome, not a fade's (`theme()`'s, worked out once + /// per theme: its contrast searches take pow calls, too many for a + /// grapheme or a row). + pub fn bodyChrome(p: *Pardes) *const ChromeTheme { + const th = p.theme(); + if (p.body_chrome) |*cached| if (std.meta.eql(cached.theme, th.*)) return &cached.chrome; + p.body_chrome = .{ .theme = th.*, .chrome = ChromeTheme.fromTheme(th) }; + return &p.body_chrome.?.chrome; + } + /// When core animation next needs a frame, on the `stepped_ns` /// timeline: a frame from now while anything moves, the end of the /// wait while something only waits (a message lingering, a look-hover -- cgit v1.3