perf(capture): poll the framebuffer seed at 240 Hz - #115
Draft
szdziedzic wants to merge 1 commit into
Draft
szdziedzic wants to merge 1 commit into
szdziedzic wants to merge 1 commit into
Conversation
SimulatorKit frame callbacks arrive below display cadence on the virtualized hosts EAS runs (#92 measured ~20 fps idle / ~36 fps scrolling delivered to the encoder), so on those hosts the IOSurface seed poll is often the real change detector. At 60 Hz it added 0–16.7 ms (~8 ms on average) between a framebuffer change and its capture. IOSurfaceGetSeed is a shared-memory read and the poll skips unchanged surfaces, so the timer rate is almost free: poll at 240 Hz by default and cap that delay at ~4 ms. `SERVE_SIM_CAPTURE_POLL_HZ` overrides the rate within [30, 480] so a deployment can A/B it without a release; unparseable values keep the default. The idle floor (5 fps) and the poll-lateness accounting are unchanged; the `pollTicks` counter simply advances four times faster. Measured on an M5 Pro with an idle simulator and capture running: the serve-sim process used 0.07 s CPU per 10 s at 60 Hz and 0.11 s at 240 Hz — about 0.4% of one core for a 4x faster detector. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch has not been deployed
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
The IOSurface seed poll runs at 240 Hz instead of 60 Hz.
SERVE_SIM_CAPTURE_POLL_HZoverrides the rate within [30, 480] for A/B runs; unparseable values keep the default.Why
On the virtualized hosts EAS runs, SimulatorKit frame callbacks arrive below display cadence (#92 measured ~20 fps idle / ~36 fps scrolling delivered to the encoder), so the poll is often the real change detector. At 60 Hz it added 0–16.7 ms (~8 ms on average) between a framebuffer change and its capture.
IOSurfaceGetSeedis a shared-memory read and the poll skips unchanged surfaces, so a faster timer is almost free and caps that delay at ~4 ms.How
SimulatorCapturePollPolicyresolves the rate once from the environment (pollsPerSecond(environmentValue:), clamped) and exposes the interval;FrameCapturearms its strictDispatchSourceTimerfrom it and logs the rate at start.pollTickssimply advances four times faster.Part of the tap-to-photon stack (bottom → top): latency probe → send frames on arrival → 240 Hz seed poll → bitrate floor → playout window → data-channel input → lossy moves lane. Everything is on by default, so a package built from any layer works with the unchanged EAS launch flags (
--transport webrtc --webrtc-codec vp8 --max-dimension 960 --video-bitrate 6000000 --video-fps 60).Measured with
scripts/latency-probe(M5 Pro, loopback, iPhone 17 / iOS 26.5, 25 taps): 0.1.51 p50 32–37 ms / p95 ≈ 43 ms → top of stack p50 27 ms / p95 38 ms, no outliers above 40 ms.🤖 Generated with Claude Code