Skip to content

revert: stop releasing a WebGL context when its clip's window has ended - #7020

Merged
miguel-heygen merged 1 commit into
mainfrom
revert/webgl-context-release
Nov 2, 2026
Merged

miguel-heygen merged 1 commit into
mainfrom
revert/webgl-context-release

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Stops the renderer from releasing a WebGL context when its clip's window has ended (the behaviour #6984 added), by removing the lines in frameCapture.ts that wire it in. The module, its unit tests, clipWindow and the size budget stay, so the follow-up fix can build on them.

Why

A report says 3D (Three.js/WebGL) visuals vanish from some exports made with 0.9.2 and later. It is not reproduced yet: a first check on two Three.js fixtures with 1 and 3 workers found 3D present and the frames byte-identical on 0.8.230 and 0.9.2. #6984 is the one change that can blank a canvas for the rest of a render: it calls loseContext() on a canvas whose clip's window ended at the current capture time, and a lost context never comes back, so parallel or out-of-order capture, or a wrong nested window, could release a canvas a later frame still needs. This ships by the maintainer's decision to remove that risk now.

The real fix follows: release a context only when no later frame of any worker can need it, and recreate it on demand if one does.

Test

fails without the fix:

  • webglRelease.test.ts › capturing a frame › "a WebGL canvas in a hidden clip whose window has ended keeps its context (never loseContext)"

It drives a frame capture with a page holding an ended hidden clip's canvas and asserts loseContext is never called; with frameCapture.ts as on main it is called once. It passes 3 runs in a row with this change; the frame-capture tests (349) pass, tsc and oxfmt are clean.

Size

Four lines of wiring removed and one test added.

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 114 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 (2)

  • seqplainkeys-none-center-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true
  • seqplainkeys-none-pct-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo false, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true

@heygengenesis heygengenesis Bot 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.

Requesting changes at 095217fd. The code is fine; this is a merge-gate block.

Blockers

  1. The PR is held, but approving it would merge it. The body says it is "held, not for merge, until a repro shows 3D blank on 0.9.x and back with the revert". In this lane, one approval on the head is enough for the merge loop to merge. The PR is not a draft and has no hold label. Its own evidence so far points the other way: two Three.js fixtures, with 1 and 3 workers, rendered byte-identical frames on 0.8.230 and 0.9.2. Approving now would ship the revert without the evidence the PR asks for.
  2. There is no fails without the fix: line. The PR is a fix for the "3D vanishes from exports" report, so it has to name a test that fails without it. That test is the missing repro: a Three.js/WebGL fixture that renders blank on 0.9.x and renders 3D with this revert, for example with several workers or a nested clip whose window ends early.

What I checked (no code concerns)

  • The diff is the exact inverse of #6984 (26d6e3ee), apart from the packed size budget (461788 → 456397). It is current with main (ahead 1, behind 0).

To clear this: add the repro test and the fails without the fix: line, then re-pin the head here. I'll re-review it. Until then, keep it in draft or add a hold label so another approval can't merge it.

@miguel-heygen
miguel-heygen force-pushed the revert/webgl-context-release branch from 095217f to ebfb8fb Compare November 2, 2026 15:06
@miguel-heygen miguel-heygen changed the title revert: a scene that has ended gives up its WebGL context so the next scene is not slowed revert: stop releasing a WebGL context when its clip's window has ended Nov 2, 2026
@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

Pushed ebfb8fb. What changed since the last head:

  • The CI red was "Reject accidental file deletions": the plain revert deleted webglRelease.ts and its test. They stay now; only the lines that wire the release into frameCapture.ts are removed (the import, the recorder registration and the call after the seek).
  • Added the pin the review asked for: a WebGL canvas in a hidden clip whose window has ended keeps its context (never loseContext) in webglRelease.test.ts. It drives a frame capture and fails with expected ['3d'] to deeply equal [] when frameCapture.ts is as on main; it passes 3 runs in a row here.
  • Body rewritten: the report is not yet reproduced, and this ships by the maintainer's decision to remove the risk now; the real fix follows.

@heygengenesis heygengenesis Bot 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.

Approving at ebfb8fba. I found no blockers. The earlier hold is lifted by the maintainer's decision to ship it today.

  • Change: it removes only the three places where frameCapture.ts wires in the release (the import, evaluateOnNewDocument(recordWebglContexts) and releaseEndedWebglContexts(page, quantizedTime)). webglRelease.ts, its unit tests, clipWindow and the size budget stay for the follow-up fix. Nothing outside tests still calls the module.
  • Fail-without-fix check: the fails without the fix: line names one test, and I ran it both ways.
    • With this head, webglRelease.test.ts passes (4/4).
    • With frameCapture.ts put back as on main, the named test fails with expected [ '3d' ] to deeply equal [], meaning loseContext was called once, as the body says.
  • Dead code: webglRelease.ts is now only imported by its test. I ran fallow audit --base origin/main --fail-on-issues locally on this head: "No issues in 50 changed files".
  • Main: the branch is one commit behind main, and that commit is #7015 (CLI catalog files only), so there's no overlap.
  • Nit (not blocking): the test's page mock only acts on functions whose source contains __hf_gl_contexts. That makes it a guard against the wiring coming back, not a 3D render repro. The repro is still owed for the real fix.

CI: CI, regression, Windows render verification and CodeQL were still pending or running when I reviewed. The runs that had finished passed, apart from one cancelled duplicate PR captures run (its rerun passed).

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 2, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 2, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 6fd96dd Nov 2, 2026
135 of 147 checks passed
@miguel-heygen
miguel-heygen deleted the revert/webgl-context-release branch November 2, 2026 16:05
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