gpui: Journal platform frame requests and skipped frames (#64958)
## Summary
Pass captured platform frame request timing to `on_request_frame` and
emit foreground journal records. This PR provides timing data; it does
not classify platform waits or change latency histogram/reporting
policy.
`RequestFrameOptions` carries an optional captured time and a
native-callback/local-schedule source. A per-window atomic preserves the
earliest coalesced request timestamp and its matching source until
main-thread delivery. Journal records include window identity, captured
time when available, foreground handling time, and source. No request
IDs or second journal stream are introduced.
## Completed frame skips (retained for review)
Keep completed GPUI decisions not to render as sealing boundaries, with
no-render-needed, inactive-throttle, and thermal-throttle reasons. They
seal at foreground completion without satisfying or clearing pending
demand. Hang serialization uses `sealed_by: "frame_skipped"`.
Platform frame requests do not seal or count as foreground work.
Reentrant deferrals remain non-sealing raw diagnostic records with their
own window/time payload; they cannot be represented as completed skip
reasons or sealing skip boundaries. Raw point diagnostics are not copied
into snapshots. Hang qualification still uses foreground execution
durations and occupancy; infinite foreground hang detection remains
follow-up work.
The skip-sealing portion is intentionally retained for review and can be
split out if requested. The signal-to-present histogram, refresh
estimation, platform-wait filtering, and Frame Duration Report changes
are deferred. The complete prior checkpoint is preserved on
`platform-frame-latency-followup`; it is not a second PR yet.
## Platform sources
- **macOS:** CoreVideo’s supplied current host timestamp is converted to
an `Instant` using paired host-clock/local-clock samples, with
receipt-time fallback for invalid timestamps. Capture happens before
registry locking/coalescing; synchronous `displayLayer` and key-window
draws use call time. `WindowFrameSource::stop()` clears stale signals
after detaching the subscription.
- **Windows:** VSyncProvider time immediately after waiting, before
redraw invalidation. Compositor-paced waits are tagged `NativeCallback`;
failed or short waits followed by the existing fallback sleep are tagged
`LocalSchedule`. Coalescing retains the earliest timestamp and its
matching source together; hidden/minimized slots are cleared. Wait and
redraw behavior are unchanged.
- **Wayland:** compositor milliseconds converted against CLOCK_MONOTONIC
with wrapping subtraction and a 60-second plausibility bound;
receipt-time fallback. Demand pings retain enqueue time; retries retain
scheduled deadlines.
- **X11:** scheduled calloop refresh deadline; expose requests have no
captured time.
- **Web:** no captured timestamp yet, but requests are still journaled
with foreground handling time.
Captured-time option fields remain available regardless of the profiler
feature so independently featured backends share one API shape. Built-in
backends collect timestamps only with `gpui/profiler`: disabled capture
does not evaluate clock/conversion closures, the accumulator has no
timestamp storage or atomic operations, and callback delivery and actual
scheduling clocks remain unchanged.
Wayland's protocol does not guarantee the clock epoch. Windows fully
covered-window behavior and X11 compositor gating beyond the timer
remain limitations of these sources. Live compositor/display-off/lock
workflows remain unverified. Skip-boundary changes touch `journal.rs`
and `hang.rs`. This PR will merge before the parallel hang-watchdog
work; that follow-up PR will resolve its conflicts against these
changes.
## Verification
Latest feature-gating checks: the profiler-disabled capture regression
passed; enabled coalescing and window integration tests passed; macOS
and GPUI/Web Wasm compiled with profiling both disabled and enabled. An
optimized probe built from the shared implementation confirmed disabled
capture/accumulator paths contain no calls or atomic instructions.
Clippy, formatting, and whitespace checks passed. Latest-head CI passed
Linux, Windows, and macOS tests and Clippy, along with Wasm and style
checks.
Latest type/guard cleanup: seven focused journal, hang, and window tests
passed, along with the profiler-disabled GPUI library check, Clippy,
formatting, and whitespace checks. The consecutive profiler guards are
grouped without shortening the foreground-turn guard lifetime.
- Previous extracted checkpoint: `cargo test -p gpui --features profiler
--lib -- --test-threads=1`: **431 passed**.
- Focused TestPlatform tests exercise request/source emission and
pending demand surviving throttling, observing callback execution and
draw counts. No wall-clock sleeps are used by the new window tests.
- `corgi check -p gpui_macos --lib`: passed.
- `./script/clippy -p gpui -p gpui_macos -p input_latency_ui`: passed,
including repository hygiene checks.
- GPUI + Web Wasm check with profiler and repository CI
build-std/atomics flags: passed.
- Formatting and `git diff --check`: passed.
Corgi's parallel suite passed 436 of 437 tests but encountered the
previously observed hang-monitor shutdown channel timing failure. That
test passed in the serial Cargo suite and was not changed or disabled.
The preceding checkpoint passed Linux, Windows, macOS, and Wasm CI. CI
also passed on the current head, `3641f14ab0`. Local cross-target checks
remain constrained by missing Linux system libraries and Windows SDK
tooling on the macOS host.
## Suggested .rules additions
When manually driving platform frame requests in GPUI tests, account for
test-mode automatic draws during effect flushing. For throttle-routing
tests, configure a comfortably long throttle interval instead of relying
on wall-clock sleeps or short scheduling deadlines.
Release Notes:
- [GPUI] Added captured platform frame request timing and foreground
journal records, including sealing boundaries for completed decisions
not to render.
cd4fc8de4cAnthony Eid committed on 10/1/2026, 7:52:10 PM· committed by GitHubparent7bbd162