Skip to content

fix(cli): check skips WebGL draws on its box-only seeks so Three.js scenes finish - #5825

Merged
miguel-heygen merged 1 commit into
mainfrom
scrubfix/checkwebgl
Oct 18, 2026
Merged

miguel-heygen merged 1 commit into
mainfrom
scrubfix/checkwebgl

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

What changes

hyperframes check no longer runs out of time on compositions with several Three.js or WebGL canvases. It used to stop with "Check did not finish within its deadline." and report nothing.

Why it happened

Check's text-overlap pass seeks the timeline about 80 times and reads only element boxes. But every seek runs the composition's own update code, and that redraws each WebGL scene. On software WebGL (no GPU, or --no-browser-gpu), four 960x540 Three.js scenes cost about 0.9 s per seek, plus about 0.3 s more for the box read that waits behind those draws. That pass alone took about 95 s of check's fixed 120 s budget.

The fix

The box-only seek (DENSE_GEOMETRY_SEEK_OPTIONS) now skips WebGL draw calls (clear, draw*, blitFramebuffer) while the seek runs. It does this through a small gate on the WebGL prototypes, installed by the first such seek. Draws outside that seek are untouched.

A skipped draw leaves the canvas stale, and seeking again to the same time redraws nothing: GSAP and the hf-seek dispatch both treat a repeat time as a no-op. So the next pixel-reading seek after a skipped draw first steps 1 ms off the target with draws still skipped, then lands on it, which repaints the scene. Every pixel-reading seek (layout grid, contrast, finding crops, snapshot) draws exactly as before.

Evidence

Fixture: one 1920x1080, 10 s composition with four Three.js canvases (120 torus knots each, shadows, GSAP-driven), software WebGL, same Mac, back to back:

check --no-browser-gpu
0.8.169 (published) 88 s (114 s on a second run under load)
main + this change 16.6 s
main, scene draws disabled by hand after the first frame (cost floor) 11.8 s

On Linux (8-core x86 box, Chrome 152 headless shell, software WebGL), 3 runs each, alternating: 0.8.169 took 51.5 / 50.8 / 51.2 s and this change took 14.0 / 14.9 / 13.9 s. Both passed there; how close a project gets to the 120 s deadline depends on the machine and how heavy the scenes are, and this pass's share of the time is what the change removes.

Per call, before vs after: a box-only seek went from about 900 ms to about 2.5 ms, and the box read after it from about 290 ms to about 1 ms. Findings are unchanged (0 layout issues, 5/5 contrast checks pass).

Tests

captureCompositionFrame.webglDraws.browser.test.ts uses real Chromium with SwiftShader WebGL and a player that, like GSAP, does nothing on a repeat-time seek. It checks:

  • a box-only seek leaves the canvas undrawn;
  • the next pixel seek to the same time repaints it, through one 1 ms step-off;
  • later pixel seeks don't step off again;
  • the page's own draws outside a seek still work.

It fails on main (expected 100 to be +0: the box-only seek drew). With only the step-off removed it fails on the stale canvas (expected +0 to be 100). It passed 3 runs in a row. The existing seek tests pin the page call's arguments, so they now include the new flag.

@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 180 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (1)

  • textedit-none-px-r0-nested-z100: tracking 0, pressJump -, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0, pressJump -, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0, pressJump -, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true

@terencecho terencecho left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed assigned HEAD daf15a46602ed032379bf008ddab894ce6ef99e5 against effective/API base 49671b73dd417f7fe0f3c3f500290df18b447cd0.

No concrete introduced blocker found. I read all changed base files before all changed head files and traced the real dense-geometry caller, overlap collector, runtime transport/adapters, completion boundary, and fresh-page finding crops. Both independent source-review passes reached the same conclusion. In the inspected check flow, pixel sampling precedes the dense geometry pass; the latter reads DOM/text geometry, while the gate restores normal draw forwarding in finally.

Nonblocking test-contract caveat: the new browser fixture compares raw times, whereas the real runtime normally quantizes them. A 1 ms step-off is not always a distinct frame (including at zero), so that fixture does not prove a general next-pixel-seek repaint guarantee. A real-runtime zero/off-grid test would strengthen this contract. I did not establish a production same-page geometry-to-pixel schedule exposing that limitation, so I am not treating it as a served regression.

Source-only review: tests, browser/GL rendering, performance claims, and CI were not executed or independently verified.

— Review by tai (pr-review)

Verdict: APPROVE
Reasoning: The inspected production opt-in is geometry-only and runs after pixel collection, with the normal seek cascade and completion handling retained. No reachable incorrect served result was established; the broader recovery-test limitation is scoped above.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit e9181d0 Oct 18, 2026
111 checks passed
@miguel-heygen
miguel-heygen deleted the scrubfix/checkwebgl branch October 18, 2026 07:26
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.

2 participants