Skip to content

feat(examples): auto-sweep mode for stress-tv (find the FPS sweet spot)#80

Merged
chiefcll merged 1 commit into
mainfrom
feat/stress-tv-autosweep
Jun 9, 2026
Merged

feat(examples): auto-sweep mode for stress-tv (find the FPS sweet spot)#80
chiefcll merged 1 commit into
mainfrom
feat/stress-tv-autosweep

Conversation

@chiefcll

@chiefcll chiefcll commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

Adds an automatic sweep to the stress-tv example. Instead of driving the grid by hand with the remote, ?autosweep=true ramps card count across every tier, measures FPS at each step, and reports the highest count that still holds the target frame rate — the "sweet spot."

?test=stress-tv&autosweep=true              # target 60 fps (default)
?test=stress-tv&autosweep=true&targetfps=30

How it works

  • Sweeps each tier (rect → +image → +title → full card) up the count ladder.
  • Measures median FPS per step via rAF timing, discarding a short warm-up so the rebuild spike / first-frame upload don't skew it.
  • Bisects between the last good rung and the first bad one for a sharper number.
  • Reports two distinct ceilings so they're never conflated:
    • performance wall — the measured FPS knee (CPU- or GPU-bound)
    • correctness wall — the Uint16 index-buffer cap (16384 quads / glyphs)
    • reported sweet spot = min(perf, correctness); counts are clamped to the cap so the sweep never builds a scene whose own text would drop out.
  • Output to console.table and an on-screen panel.

VAO A/B

VAO is fixed at renderer construction, so the runner measures the current setting and you compare two runs:

?test=stress-tv&autosweep=true   vs   ?test=stress-tv&autosweep=true&novao=true

This is the honest way to settle "is VAO on actually faster on this device" — a strict win when CPU/driver-bound, neutral when GPU/fill-bound, and occasionally a wash on flaky embedded WebGL1 VAO drivers (which is exactly what disableVertexArrayObject is for).

Verified

On a 120 Hz dev machine (target 60 fps), the sweep reported:

tier sweet spot limiter
1 rect 16 384 index cap
2 +img 8 192 index cap
3 +title 2 010 index cap
4 full 804 index cap

These match the analytical caps exactly. This machine is fast enough that FPS never dipped below 60, so the index cap binds on every tier; on a slower 60 Hz TV the FPS wall would bind first at lower counts, which the tool distinguishes.

Notes for reviewer

🤖 Generated with Claude Code

Adds `?autosweep=true` to the stress-tv example. Instead of driving the grid
by hand with the remote, it sweeps every tier from low to high card count,
measures median FPS per step (rAF timing, with a short warm-up to skip the
rebuild spike), and bisects between the last good rung and the first bad one
to report the highest count that holds the target frame rate.

  ?test=stress-tv&autosweep=true              # target 60 fps (default)
  ?test=stress-tv&autosweep=true&targetfps=30

Results print to the console (console.table) and an on-screen panel. The sweep
reports two distinct ceilings so they are never conflated:
  - performance wall: the measured FPS knee (CPU- or GPU-bound)
  - correctness wall: the Uint16 index-buffer cap (16384 quads / glyphs)
The reported sweet spot is min(perf wall, correctness wall), and counts are
clamped to the cap so the sweep never builds a scene whose own text would drop.

VAO is fixed at renderer construction, so A/B it with two runs and compare:
  ?test=stress-tv&autosweep=true  vs  ?test=stress-tv&autosweep=true&novao=true

Also refactors buildGrid to take an explicit count so the sweep can drive
arbitrary values; interactive remote controls are unchanged.

Note: the correctness-wall math assumes the index-buffer fix (#79). Best
reviewed/merged alongside it; without it the real cap is ~4167 and high-count
tiers would drop text mid-sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chiefcll chiefcll merged commit a312f6e into main Jun 9, 2026
1 check passed
@chiefcll chiefcll deleted the feat/stress-tv-autosweep branch June 9, 2026 02:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant