perf: build nothing while the window is hidden - #24
Merged
Conversation
When the window is fully covered, macOS refuses to hand out a drawable. draw() only found out at step 3 (get_current_texture); steps 1 and 2 -- laying out the sidebar, the grid and the bottom bar, then glyphon's prepare -- had already run and were thrown away, 26 times a second on the 32ms retry. Track WindowEvent::Occluded, which was not handled at all, and return at the top of draw() while hidden. Redraw when the window comes back; no timer is needed, winit tells us. --bench now also reports the build phase, which is the part the skip saves alongside prepare: 0.57ms per discarded frame at 1280x800 and 1.20ms at 1920x1200, so 1.5-4% of a core was going into frames that could not be shown. That figure is the cost per frame times the observed rate, not a before/after measurement: this machine cannot occlude a window on command, so the honest limits are written down in docs/performance.md 7.11. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GvMacYD6T9EoWqc7C247Hr
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.
What
WindowEvent::Occludedwas never handled. When the window is fully covered by another window, macOS refuses to hand out a drawable, anddraw()only discovered that at the last step:prepare(glyphon: shaping + glyph atlas upload)get_current_texture— failsSteps 1 and 2 were done and thrown away, once every 32 ms, for as long as the window stayed hidden.
Evidence
TERMIT_FRAME_LOG=1on a window launched behind other windows:The counters reset every second, so that is 26 discarded frames per second.
--benchnow reports the build phase too, so the discarded work can be priced:At 26–31 frames a second that is 1.5–2% of a core, 3–4% on a large window, spent on frames that cannot be shown.
Limits, stated honestly
This is the per-frame cost times the observed rate — not a before/after CPU measurement. A window cannot be occluded on command from a shell on this machine (synthetic input and window activation are not permitted), so the occluded state cannot be reproduced for an A/B.
docs/performance.md7.11 says so in the same words.Change
State.occluded, set fromWindowEvent::Occluded; redraw on un-occlude (no timer — winit reports it).draw()while occluded, keepingneeds_redrawset.get_current_textureback-off stays as the fallback, so a wrong occlusion report cannot freeze the window permanently.--bench: build-phase column.docs/performance.md7.11.Test
cargo test— 200 pass.cargo clippy --all-targets -- -D warnings— clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01GvMacYD6T9EoWqc7C247Hr