Repository navigation
perf(rendering): reuse word-highlighted caption layouts while their colours are unchanged - #2799
Open
richiemcilroy wants to merge 2 commits into
Open
richiemcilroy wants to merge 2 commits into
richiemcilroy wants to merge 2 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
Member
Author
|
@greptileai review |
richiemcilroy
marked this pull request as ready for review
October 22, 2026 06:21
Member
Author
|
@greptileai review |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Word-highlighted captions (
active_word_highlightwith the colour style) rebuilt aBuffer, ran fullShaping::Advancedshaping and dropped the layout cache on every frame. Plain captions (4577e9d) and the text overlay (164bfef) already reuse the last frame's layout when their inputs are unchanged.Change
set_text/set_rich_text: text, font size, wrap width, family, weight and the colours. For highlighted captions the colours are the exact rich-text spans (byte range plus the u8 RGBA colour of each word and gap), so the active word, the transition blend and the caption fade are all in the key.Bufferis reused. On a miss it is built with the same calls, in the same order, with the same arguments as before. Output is unchanged by construction.shape_caption_textand a smallCaptionTextcache so it can be tested without a GPU. The per-word needle no longer clones when uppercase is off.Why not shape once and recolour at draw time: glyphon 0.9 reads each glyph's colour from
LayoutGlyph::color_opt, which cosmic-text 0.14 sets during shaping and exposes only through&accessors. Recolouring would need a fork of either crate. Keying on the u8 colours keeps output identical. Shaping is skipped on every frame where no word's colour or alpha changes: between transitions, once a fade-in has settled to its final u8 value, and on held words.Tests
shaping_tests::cached_word_highlight_layout_matches_an_uncached_shape_every_frame(CPU, runs incargo test): steps a highlighted caption at 60 fps through fade in, every word change and fade out, switching wrap width every 45 frames, for three variants (default, uppercase with Unicode and a gold highlight with a short transition, zero transition). Every frame it compares each laid out glyph (position, font, glyph id, colour, cluster range) from the cached buffer with a buffer built by a verbatim copy of the old per-frame code. It also asserts the cache reshapes on fewer frames than it draws.shaping_tests::word_highlight_cache_reshapes_when_any_layout_input_changes: text, uppercase, font size, wrap width, family, weight, highlight colour, transition duration, active word and caption fade each force a reshape, the result matches the uncached build, and identical inputs do not reshape. Also covers switching between plain and highlighted text.every_caption_frame_renders_like_a_fresh_layergains two highlighted variants (gold, outline, uppercase, pop; zero transition with a long fade). Newhighlighted_frames_follow_output_size_changes_like_a_fresh_layerchanges the output size every 7 frames.reused_layer_follows_style_and_output_size_changesgains nine highlighted cases. All compare rendered pixels with a fresh layer.benchmark_word_highlight_preparetimesCaptionsLayer::prepareover 600 frames at 1080p and prints an FNV digest of every rendered frame, so base and head output can be compared directly.Measurements
benchmark_word_highlight_prepare, 1920x1080, 600 frames at 60 fps (2204 visible samples over 4 timed passes), base (main plus the bench commit) and head built with the same release profile on the same runner and run interleaved, 6 rounds each. Numbers are the median of the per-round totalCaptionsLayer::preparetime for 600 frames. Scratch run: https://github.com/CapSoftware/Cap/actions/runs/39538547724Linux is blacksmith-8vcpu-ubuntu-2404 (lavapipe), macOS is blacksmith-6vcpu-macos-26. The macOS VM drifts a lot between rounds (plain ranged 7.7 to 20.3 ms on both sides), so read its plain row as unchanged; Linux is stable and shows the plain path is unchanged.
The gain is bounded by how often no colour changes between frames. With the default 0.25 s word transition, a word's fade in keeps changing its u8 colour for most of the word, and a gold highlight changes the blue channel by 255, so it settles even later. Back-to-back words (the usual transcript shape, no fade out between words) hit the cache most.
Pixel output: the bench hashes every rendered frame. Base and head digests match for every case on both platforms (Linux: plain 46a57c3a96ae770f, highlight 07e8a12b482c5927, gold outline d0669b00b3f7ff1a, back-to-back 0070e1ef26b7663b; macOS: ab266f7b1fd93bfb, 5185a2325fe0539d, 741779ddcc4df37c, c76e43bfd068fbeb). The ignored GPU tests pass on both runners in the same run.
CI
crash/recorder-kill/*/static-screenfragment-span flake fails.crates/rendering/tests/display_layout.rsstill passes&ProjectConfigurationtoProjectUniforms::new(test added in 19de9e5). Not touched here.

Confidence Score: 5/5
The PR appears safe to merge; no actionable issues were found.Summary
Highlighted captions now reuse their shaped text when the text, font settings, width, and exact span colours stay unchanged.
Reviews (1) · Last reviewed commit: "perf(rendering): reuse word-highlighted ..." · Reviewed by Greptile