Repository navigation
Read Android touch input between frames when drawing falls behind vsync - #931
Conversation
Choreographer queues a Frame host event every vsync, and the drain drew one frame per queued event. Whenever drawing outlasted a vsync (about 11 ms against 8.3 ms at 120 Hz), the backlog grew with every drain, and the loop drew frame after frame without reading input. On a Galaxy S20 FE, touch moves waited up to 100 ms and then reached GPUI microseconds apart. GPUI times its velocity samples on arrival, so a short drag flung far, and a swipe made during a fling stopped it while its own moves arrived late. A drain now draws once, as the loop did before frames followed Choreographer. Measured on the same device, touch moves reach GPUI within 18 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Let's hold this until two upstream gpui-base fixes land: longbridge/gpui-kit#3631 and longbridge/gpui-kit#3632. The sticking after a swipe during a running fling matches a bug in gpui-base's The frame backlog this PR fixes inflates release speeds. Touch has no stretch limit, so on Android that makes the phantom throw bigger: this PR shrinks the symptom but can't remove it. Once both fixes are in, we can see what this change fixes on its own. The short flick that flings thousands of pixels should still come from the backlog. |
|
Update to my earlier comment: we're no longer waiting on upstream. #933 works around both gpui-base behaviours inside Tcode: page viewports let their content scroll itself, so ScrollBounce stretches only by what is left over at an end. With that merged, this PR went in on its own merits: it fixes the Android frame backlog. |
On Android, a short flick in a long chat could fling thousands of pixels, and a swipe made during a running fling would stop it and seem to stick.
Since #897, Choreographer queues a
Framehost event every vsync, andprocess_host_eventsdrew one frame per queued event. When a frame takes longer than a vsync (about 11 ms against 8.3 ms at 120 Hz on a Galaxy S20 FE), the backlog grows with each drain. The loop then draws frame after frame without reading input. Touch moves waited up to 100 ms and reached GPUI microseconds apart. GPUI timestamps velocity samples when they arrive, so it read those bursts as near-cap release speeds.A drain now draws at most once, so input is polled between frames, as the loop did before #897. Frame pacing is unchanged.
No test: the loop runs only on a device, and no headless entry point drives it.
Checks run:
cargo fmt --all --checkcargo check -p tcode-android --target aarch64-linux-android --lockedwithRUSTFLAGS='-D warnings'gpui-androidonaarch64-linux-androidwith-D warningsNot run: the workspace clippy and test suite. Nothing they compile changed.
PROTOCOL_VERSIONbump: a note was added under "Unreleased" above theconstant in
crates/protocol/src/lib.rs(the number itself changes onlywhen the release is cut — CONTRIBUTING.md, principle 9).
🤖 Generated with Claude Code