Drop the modal scrim's backdrop blur (fixes #36) - #37
Merged
Conversation
Opening the back panel on Linux cost the app its interactivity: about a second of input latency on any press or scroll, and a visibly slower spectrum visualizer. The SDK's modal chrome paints a full-viewport Gaussian backdrop blur behind every sheet, dialog and drawer (emitModalSurfaceScrim, radius from tokens.blur.scrim, default 4). On Linux that runs on the CPU: the GTK host wires only presentGpuSurfacePixels, no GPU packet path, so every frame goes through ReferenceRenderSurface, whose own comment calls drawBlur "the renderer's most expensive command, an O(kernel^2) Gaussian gather per output pixel over what is usually the whole viewport". At 1133x564 on a 1.67 desktop scale that is 1.77M pixels times a 15x15 kernel, roughly 400M weighted samples per frame. The renderer memoizes the result, but the key hashes the destination pixels, and the spectrum visualizer animating behind the sheet at ~25Hz misses that memo almost every frame. Measured with `native automate profile on`: panel closed present p50 17ms p90 19ms panel open, before present p50 16ms p90 571ms (max 1.2s), input 580ms panel open, after present p50 69ms p90 72ms, input 74ms The bimodal p50/p90 before the fix is the memo hitting on quiet frames and missing whenever the backdrop moved, which is also why the reporter saw the visualizer run slower on FLAC than MP3. What differs is how often the backdrop moves, not the decode. The design brief bans blur outright, so this was only ever painting a frosted edge that was never in the design. tokensFn now layers a house_overrides set under the station colors with blur.scrim = 0. The translucent wash stays, so the modal still dims what is behind it. The test asserts no scheme can rearm the blur, and that the wash survives.
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.
Fixes #36. Reproduced on this machine too (Arch, AMD, fractional scale).
What was happening
The back panel is a
<sheet>, and the SDK's modal chrome paints a full-viewport Gaussian backdrop blur behind every modal surface (emitModalSurfaceScrim, radius fromtokens.blur.scrim, default 4).On Linux that lands on the CPU.
platform/linux/root.zigwires onlypresentGpuSurfacePixels, no GPU packet path, so every frame is rasterized byReferenceRenderSurface. A snapshot confirms it:gpu_backend=software,gpu_present_path=pixels. The SDK's own comment ondrawBlurcalls it "the renderer's most expensive command, an O(kernel²) Gaussian gather per output pixel over what is usually the whole viewport".At 1133x564 on a 1.67 desktop scale that is 1.77M pixels x a 15x15 kernel, roughly 400M weighted samples per frame. The renderer memoizes the blur, but the key hashes the destination pixels, and the spectrum visualizer animating behind the sheet at ~25Hz misses that memo almost every frame.
Evidence
Measured with
native automate profile on:The bimodal p50/p90 before the fix is the memo hitting on quiet frames and missing whenever the backdrop moved. That is also why the reporter saw the visualizer run slower on FLAC than on MP3: what differs is how often the backdrop moves, not the decode.
The change
The design brief bans blur outright, so this was only ever painting a frosted edge that was never in the design.
tokensFnnow layers ahouse_overridesset under the station colors withblur.scrim = 0, so a station theme cannot bring it back. The translucent wash stays, so the modal still dims what is behind it.The new test asserts the blur is off in both schemes and that the wash survives. It fails with
expected 0, found 4if the override is removed.Verification
native test: 108/108 pass-Dautomation=true -Dtrace=off, drove the back panel open and took the numbers aboveNot fixed here
With the panel open, present is still 69 ms/frame against 17 ms closed. That is the sheet's own ~135 extra draw commands being re-rasterized on the CPU every frame. I isolated the scrim wash at only ~10 ms of that, so it is the panel content itself. No retained or dirty-rect rendering exists on the Linux pixel path, so it is not fixable from the app. 74 ms is responsive, 580 ms was not. Worth an upstream request alongside
docs/sdk-audio-device-request.md.