The Choreographer vsync callback reaches the UI thread only 2.5-6 ms AFTER the vsync edge (measured on the phone). With a 2.5-5 ms Skia render plus present, that left no phase margin inside the 8.3 ms slot: 51% of frames landed one slot late (judder) and ~4% two slots late (hitches), on every build tested so far. Attempted fixes, all measured and retired (see commit history): - render-ahead hold (present previous frame at next render start): the held present lands after the NEXT wake's 3.2-6 ms Choreographer latency -> 52% one-slot late. - present-at-end + present GATE (sleep on the UI thread to quantize the present to the vsync grid): the gate sleep (2.5-4 ms) added to the slot budget (wake 5.3 + core 3 + gate 3 + present 1 = 12.3 ms > 8.3 ms) -> cadence collapsed to 60 Hz. Working fix (this commit): - vsync.rs: an 'early waker' thread learns the vsync grid from the callback's frame_time_nanos (vkprobe::note_vsync_edge) and wakes the main looper ~0.8 ms BEFORE each edge while animating. Render start moves from edge+2.5..6 to edge-0.8..+0.5, so the present lands at a natural ~edge+3..5 ms phase with no UI-thread sleep. - lib.rs: a render freshness guard (min gap = period - 1.5 ms) makes the FIRST wake of each slot (early or the late Choreographer fallback) render and rejects the second (double render = 60 Hz collapse). Threshold sits between late-after-early (5.8 ms, reject) and early-after-late (7.5 ms, accept). - lib.rs: locked renders no longer consume pending_redraw (it carried the motion invalidations; consuming it starved the follow-up unlocked iteration -> 60 Hz collapse). - stg.rs: IT lines now log the render decision (locked/saw_wake/ pr_before/do_render); vkprobe logs gate sleep (GATE_US, now 0). Measured (phone, 8580-file grid, slow 4 s drags): in-burst cadence: 8.29-8.44 ms median, p90 8.6-10.2 ms (was 8.36 median / 10.2 p90 with 3.7-20% two-slot gaps) in-burst >16.7 ms gaps: 0-2 per burst (was 3-13) present-to-present: 27% exact one slot, 33% one-slot-late steady state (imvisible), 3% f-jumps (Skia core 2.5-5 ms variance). Residual judder lever: Skia core cost variance (next step). Test hygiene reminders (HANDOFF 8.10): verify ResumedActivity, keep the task clean (sz=1), record the perf-log byte offset before each run (the file accumulates across process launches). |
||
|---|---|---|
| .. | ||
| LICENSES | ||
| wgpu_29_surface | ||
| wgpu_30_surface | ||
| .cargo_vcs_info.json | ||
| .cargo-ok | ||
| build.rs | ||
| cached_image.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Cargo.toml.orig | ||
| font_cache.rs | ||
| itemrenderer.rs | ||
| lib.rs | ||
| opengl_surface.rs | ||
| README.md | ||
| scn.rs | ||
| software_surface.rs | ||
| vulkan_handle.rs | ||
| wgpu_29_surface.rs | ||
| wgpu_30_surface.rs | ||
| wgpu_renderer.rs | ||
NOTE: This library is an internal crate of the Slint project.
This crate should not be used directly by applications using Slint.
You should use the slint crate instead.
WARNING: This crate does not follow the semver convention for versioning and can
only be used with version = "=x.y.z" in Cargo.toml.