cube
The OpenGL-Renderer demo, compiled to WebAssembly — single-threaded and browser-paced, on purpose.
Click the cube to give it keyboard focus, then: Space pauses the spin · ← → yaw · ↑ ↓ pitch.
This build strips the two systems the project is
actually about — the frame pacer (no high-resolution
sleep or busy-spin on a browser main thread;
requestAnimationFrame owns the frame clock) and the
threaded render (Emscripten's offscreen-canvas paths
don't support GLFW) — so every number below comes from native
builds: the desktop run of record plus weekly CI runs (full writeup
on GitHub).
Frame pacing
10,000 frames per cell, first 500 dropped as warmup; intervals are frame start-to-start (the cadence a viewer experiences), 50 µs bins, log count axis. Binned from the 2026-07-27 pacing-matrix run's raw logs (the README's figures come from a separate run — per-run shapes differ slightly).
Input handoff: mutex vs lock-free
Rate-independent — this section's x-axis is the publish rate, so the rate filter above doesn't apply here.
Uncontended per-op cost (ns, batched median)
Amortized throughput from 1 M-iteration batches — comparable to each other, not "what one isolated call costs."
Contended sweep — reader p99 vs publish rate
Points sit at each run's achieved publish rate; the unthrottled cells land at what each backend actually reached. Below ≈100 k publishes/s the mutex's read tail is at the 100 ns measurement floor — the crossover from the committed handoff results.