From 3b8ee10301e0b83013a38d93516a345622a93aaa Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 26 Aug 2026 12:00:20 -0300 Subject: Make the chrome fade a build option, and compile it out for the board A theme change moves the anchored chrome palette - taglines, boxes, line numbers, scroll bars - from the old colors to the new ones over ten display frames. On a screen that repaints in microseconds that is a short legible transition, and it is why the code exists: a palette that teleports reads as a glitch. On a 115200 serial line it is not a fade. Each of the ten steps recolors every anchored cell, so the diff finds the whole chrome dirty and spends a frame's worth of wire on it, ten times over, with nothing else on screen to look at. Measured on the die, one `NextColor`: fade on 12,593 bytes 1,097 ms of saturated wire fade off 2,425 bytes 215 ms A second of the editor talking to itself about a color, on the one transport where a second is noticeable, for a gradient nobody can watch arrive at 11.5 KB/s. ## Comptime, so the code is not there `ChromeAnimation` now selects between `animation.Transition` and a new `animation.Immediate` - the same interface with the animation taken out, a value that is only ever what it was last set to. That is what makes `ChromeTheme.interpolate` unreachable, and unreachable is what makes it absent: the flashed image drops 2,336 bytes, and the object 13,180. A bool tested at runtime would have kept every one of those bytes and still paid the branch. It also would have needed a second meaning bolted onto `animate_theme_changes`, whose job is the startup window and nothing else; that field is untouched here. The option is `-Dtheme-animation`, defaulting to off for `p4` and on everywhere else, and it is an option rather than a platform test because "is a frame expensive" is a property of the transport: a P4 driven over something faster than a UART would want the fade back, and `-Dtheme-animation=true` gives it to them. ## What was checked `Immediate` is new code with one contract worth pinning, and it is the one a caller could get wrong: it must arrive at the SAME palette a completed fade arrives at. An endpoint that differed by a rounding step would make the option a change of colors rather than a change of how long they take. Tested against a fully advanced `Transition` in `animation.zig`. Full suite: unit-test, snap 95/95, hxdiff 481/0, hxparity 561/0, image-harness, pdf-harness, mupdf-check. Builds: tty, p4, gui, and tty/gui with the fade forced off. On the die the canonical verifier reports the screen IDENTICAL across both arms - the workload contains no theme change, so this is the check that ordinary rendering was not perturbed - and `p4-bench --check` stays 4/4. --- build.zig | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'build.zig') diff --git a/build.zig b/build.zig index ed3a2e6a..07c180d3 100644 --- a/build.zig +++ b/build.zig @@ -362,6 +362,33 @@ pub fn build(b: *std.Build) void { // in region l2mem, overflowed by 76036 bytes`, that being the shell's shadow copy of the grid. opts.addOption(u16, "p4_cols", b.option(u16, "p4-cols", "board grid width in cells (p4 only)") orelse 56); opts.addOption(u16, "p4_rows", b.option(u16, "p4-rows", "board grid height in cells (p4 only)") orelse 14); + // ANIMATED THEME CHANGES, off on the board because there the animation is not an animation. + // + // A theme change moves the anchored chrome palette - taglines, boxes, line numbers, scroll bars - + // from the old colors to the new ones over `animation.transition_steps` display frames, which is + // ten. On a screen that repaints in microseconds that is a short legible fade, and it is the + // reason the transition exists: a palette that teleports reads as a glitch. + // + // On a 115200 serial line a frame is not free. Every one of those ten steps recolors every + // anchored cell, so the shell's diff finds the whole chrome dirty and spends a frame's worth of + // wire on it, ten times over, with nothing else to look at in between. Measured on the die, one + // `NextColor`: + // + // fade on 12,593 bytes 1,097 ms of saturated wire + // fade off 2,425 bytes 215 ms + // + // A second of the editor talking to itself about a color, on the one transport where a second is + // noticeable, for a gradient nobody can see arrive gradually at 11.5 KB/s. + // + // COMPTIME, not a runtime flag: `pardes.ChromeAnimation` selects `animation.Immediate` over + // `animation.Transition`, which leaves `ChromeTheme.interpolate` unreachable and out of the image + // (2,336 bytes of it). A bool tested at runtime would have kept every one of those bytes. + // + // A build option rather than a platform test, because "is a frame expensive" is a property of the + // transport and not of the target: a P4 driven over something faster than a UART would want it on, + // and it is off here only as the default that matches the wire this port actually has. + opts.addOption(bool, "theme_animation", b.option(bool, "theme-animation", "animate chrome colors across a theme change (default: off for p4)") orelse + (platform != .p4)); // Meaningful only for the SDL shell. Keeping the platform condition here // prevents Config/EffectCode from describing tty/macOS/web as "prebuilt". opts.addOption(bool, "gui_shader_sources_prebuilt", gui_shader_sources_prebuilt); -- cgit v1.3