Repository navigation
perf: stop the graph and a full-window rebuild from stalling frames on integrated GPUs - #95
Merged
Merged
Conversation
…s bounds gpui rasterizes every run of paths it cannot merge into a full-window, 4x-multisampled intermediate texture, then resolves and composites it. The graph painted each row's approach line, occluding ring and node as paths, and let rows paint 4-8px into their neighbours, which chained draw order down the list so no two rows' paths could share a pass. A frame ended up with one such pass per path in view; on an integrated GPU that backed frames up in the GPU queue and put hover feedback 50-150ms behind the pointer. The approach line now uses the lane quad, discs and rings are quads (new `paint` module), and the cell mask clips rows top and bottom as well as at the sides. Unrounded quads are not antialiased, so lane segments in adjacent rows still meet without a seam. Only curves and the pinned-lane chevron remain paths. `GraphView::set_all_loaded` now notifies, so it is correct regardless of what it is called alongside. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…only that panel Nothing used gpui's view caching, so every frame re-rendered, laid out and painted the whole window: a hover changing one row's background cost a full taffy layout of every panel. The sidebar, graph, diff viewer, detail panel and commit panel are now cached views, reused until the panel itself is notified. Cached views do not see globals change, so the workspace now refreshes its windows when ThemeState or SettingsState changes. Adds a `hover` replay step and a `hover-sweep` scenario to measure it. Main thread draw time while hovering: p50 9.3ms -> 1.1ms, p95 10.4ms -> 6.1ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…raw when they land When an image finishes loading, gpui notifies only the view that first asked for it. With the main panels now cached views, a graph row whose avatar the detail panel happened to request first would keep showing initials until something else redrew the graph. The resolver now starts each avatar's image load itself, under the same key `img(url)` uses, and refreshes the windows when it completes, for avatars resolved now and ones remembered from an earlier session. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
noahbclarkson
added a commit
that referenced
this pull request
Nov 5, 2026
Changelog entry for everything since 0.5.0: #57, #89-#92 (already drafted under [Unreleased]), plus new entries for #93, #95 and #98. The version is bumped across the workspace, and the AppStream metainfo lists 0.5.1, which the Linux metadata test requires. The performance numbers are the ones measured in #95 and #98 with the rgitui_perf scenarios on --profile perf builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 of 4 tasks
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.
Problem
On a laptop with an integrated GPU (Ryzen/Renoir, Hyprland, 60Hz) the app felt laggy: hover feedback trailed the pointer by 50–150ms and browsing commits dropped frames. Zed, on the same gpui renderer, was smooth. Two costs were stacking up on every frame:
What changes
rgitui_graph/src/paint.rs). The approach line uses the existing lane quad. Only curves and the pinned-lane›chevron are still paths.graph_cell_masknow clips top and bottom as well as the sides. Unrounded quads are not antialiased, so lane segments in adjacent rows still meet without a seam.workspace/layout.rs).ThemeStateorSettingsStatechanges. Language switches and focus changes already refresh.GraphView::set_all_loadednow notifies. It was only ever called next to methods that do, so this is robustness rather than a fix.hoverreplay step and ahover-sweepscenario that sweeps the pointer over the sidebar, the graph rows and the window at 120Hz. Documented indocs/PERFORMANCE.md.Visible change: the working-tree node's dashed outer ring now uses gpui's dashed border, so it has finer, lighter dashes than the previous 8 bold ones. Keeping the old dashes would add a path pass to every frame where that row is visible.
Measurements
--profile perfbuilds ofmain(cd9c4b4) and this branch, against this repository, laptop on charge, same window size. Path passes were counted with a temporary scene census in a local gpui copy, which isn't part of this PR.mainTesting
cargo test --workspace)cargo clippy --workspace --all-targets -- -D warnings)cargo fmt --all -- --check)Also checked:
mainand this branch line up: line joins, curves and spacing are the same. With caching on and off, the screenshots match pixel for pixel apart from antialiasing noise.?2→?3→?2) with no interaction.Not verified end to end: the avatar preload. While testing, GitHub's search API was rate-limited, so the avatars it affects couldn't resolve on
maineither.🤖 Generated with Claude Code