render: PNG sequence can capture pending virtual-rAF DOM updates after seek (0.8.145) · Issue #5888 · heygen-com/hyperframes · GitHub
Skip to content

render: PNG sequence can capture pending virtual-rAF DOM updates after seek (0.8.145) #5888

Open

Description

@jhh3

A reproducible deferred-DOM capture case on hyperframes@0.8.145 (npm gitHead 76f8a567a5f4ff7b5b75b0c67c770b7152bf56b6). Related to #4435, but this is a GSAP + transparent PNG-sequence case and shows pending virtual-rAF work, rather than a duck-typed timeline/ProRes case.

The normal composition is clean. A composition that defers a DOM update through requestAnimationFrame renders successfully but drops visible text/image content from initial frames of each worker. Snapshot/browser checks look correct once deferred updates have settled.

A minimal way to expose the readiness boundary is an onUpdate callback that schedules a reveal through several rAF turns:

<!doctype html><html><head>
<script src="./node_modules/gsap/dist/gsap.min.js"></script>
<style>html,body{margin:0;background:transparent}#text{color:white;font:48px sans-serif}</style>
</head><body>
<div data-composition-id="main" data-start="0" data-duration="2" data-width="640" data-height="360">
  <div id="text">A complete headline</div>
</div>
<script>
const text = document.getElementById('text');
const tl = gsap.timeline({paused:true,onUpdate(){
  text.style.visibility='hidden';
  let pending=10;
  function reveal(){
    if(--pending>0) requestAnimationFrame(reveal);
    else text.style.visibility='visible';
  }
  requestAnimationFrame(reveal);
}});
tl.to('#text',{x:4,duration:2,ease:'none'},0);
window.__timelines={main:tl};
tl.seek(0);
</script></body></html>

Install hyperframes@0.8.145 and gsap@3.15.0, then render with PRODUCER_FORCE_SCREENSHOT=true:

hyperframes render --format png-sequence --output frames --fps 24 --workers 2 --browser-gpu --experimental-fast-capture=false

Measured with a fuller 48-frame regression fixture containing multiple text regions, an image card, and a locally bundled web font:

  • Windows x64, Chrome Headless Shell 152.0.7977.30, Microsoft Basic Render Driver: 18/48 frames have missing content with two workers; 9/48 with one worker.
  • Linux x64, same Chrome, AMD hardware WebGL renderer: 18/48 with two workers.
  • Explicit software capture has the same deferred-work result.
  • After draining finite deferred author callbacks at the current virtual time, waiting for fonts/image decode and two native paint frames: 0/48 missing frames with two workers on both platforms. Ordinary compositions and a deterministic timestamp-based continuous canvas loop also remain clean.

This is an adversarial readiness regression, not a claim that every real-world GPU missing-layer report has this cause. It makes the missing per-seek readiness boundary observable without depending on a random GPU failure.

In the published frame capture implementation, font/image readiness happens during initialization, while subsequent capture can follow the seek without a general native paint barrier. Also, window.requestAnimationFrame is virtualized: awaiting two ordinary rAF callbacks from the capture barrier can stall unless virtual callbacks are explicitly driven. Native compositor waits need the stored originalRequestAnimationFrame (or an equivalent explicit compositor commit).

Could the engine define and enforce a per-frame readiness contract here? A useful fix would settle finite deferred DOM work at the authored time, check newly active assets, commit paint before capture, and recapture/report suspected incomplete frames. Continuous deterministic rAF loops should remain supported. Unconditionally double-capturing every frame adds substantial cost, so confirmation can be reserved for startup or instability signals.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions