fps: Cap the headline by asking the platform what the panel runs at - #2956
Merged
Conversation
`MAX FPS` was capped by a refresh rate inferred from the gaps between presents. It cannot be: those gaps are whole multiples of the panel's period, so they bound it from below and never from above — 41.7ms is six refreshes at 144Hz and one at 24Hz, and nothing in the timing says which. Four estimators, four wrong readings on real windows. The shortest gap ever seen read 169 on a 144Hz panel, because a compositor catch-up is not a refresh. The densest group of gaps read 149, because bucketing truncates the distribution it measures, and 75 on a window drawing every other refresh, because the densest thing a window that draws on demand does is idle. The fastest sustained run read 24 on an application whose own timer fired every 41.7ms, which is a cadence held perfectly steady and has nothing to do with the display. Falling back to the frame budget until a cadence was established read 60 against a 6ms frame — a ceiling under the truth, which hides the figure the reader came for. So the headline is what the frame cost can prove and claims nothing more. Capping it needs the refresh rate from the platform, which every backend already has — xrandr mode info on X11, `CVTimeStamp`'s video refresh period on macOS, the `wl_output` mode event on Wayland — and which the display trait does not carry. The warm-up stays: the frames from before the HUD was mounted, and the cold ones right after, are still dropped rather than measured, so a window that just opened still reads healthy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USSMRpQ5W58YP3UKUCzrri
huacnlee
force-pushed
the
fps-cap-only-on-a-sustained-cadence
branch
from
September 4, 2026 16:28
8160774 to
cecb4e7
Compare
Nothing about a window's own frames can establish its display's refresh rate. The gaps between presents are whole multiples of the panel's period, so they bound it from below and never from above — 41.7ms is six refreshes at 144Hz and one at 24Hz — and every estimate tried read a real window wrong: 169 and 149 from the shortest and the densest gaps, 75 from a window drawing every other refresh, and 24 from an application whose own timer fired every 41.7ms. So the platform is asked. GPUI hands out its display handle through `DisplayId`: a `CGDirectDisplayID` on macOS, an `HMONITOR` on Windows. Wayland gives out per-connection object ids that mean nothing to a second connection, so the outputs are enumerated again there and matched to GPUI's displays by the identity it derives from their names. X11 and everything else have no query and stay uncapped, as does a panel that reports no fixed rate — which is what a ProMotion display honestly is. The answer is re-asked when the window moves to another display, and not otherwise: it is a property of the panel, and on some platforms asking is a round trip. Measured on Wayland against two panels: 143.998Hz and 59.997Hz discovered, against 143.999 and 59.997 from the compositor, and a window whose frames cost 4.3ms — 232 uncapped — reading MAX 144 on the faster one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01USSMRpQ5W58YP3UKUCzrri
Co-authored-by: Codex <codex@openai.com>
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.
Summary
Follow-up to #2954.
MAX FPSwas capped by a refresh rate inferred from the gaps between presents. That inference cannot work: those gaps are whole multiples of the panel's period, so they bound it from below and never from above — 41.7ms is six refreshes at 144Hz and one at 24Hz, and nothing in the timing distinguishes them.Four estimators, four wrong readings on real windows, the last three found in longbridge-lite:
A steady 41.7ms application tick is indistinguishable from a 24Hz panel. No tuning gets past that.
Changes
The guessing is gone, and the platform is asked instead. GPUI hands out the platform's own display handle through
DisplayId, and the HUD takes it from there:CGDisplayCopyDisplayModeon theCGDirectDisplayIDEnumDisplaySettingsWon the monitor's device nameA panel that reports no fixed rate — which is what ProMotion honestly is through CoreGraphics — is read as no cap. Where nobody will say, the reading is left uncapped rather than held to a guess.
The answer is re-asked when the window moves to another display, and not otherwise: it is a property of the panel, and on some platforms asking is a round trip.
The warm-up stays. Frames from before the HUD was mounted, and the cold ones right after it, are dropped rather than measured, so a window that just opened still reads healthy.
Verified
On Wayland against two panels, with a temporary probe:
and the HUD on that window,
FRAME 4.3ms— 232 uncapped — reading MAX 144, from the moment it opened and with no interaction.Not verified on hardware: the macOS and Windows queries could not be compiled here, let alone run. The Wayland path and everything above it is measured.
Test plan
MAXstops at the panel's rate on an external display; a built-in ProMotion panel reads uncappedMAXstops at the panel's rateMAXfollowsDROP 0.0%and a greenP95AI Assistance
🤖 Generated with Claude Code
https://claude.ai/code/session_01USSMRpQ5W58YP3UKUCzrri