Commit Graph
3 Commits
Author SHA1 Message Date
337d0b51bc refactor(engine,producer): adopt requestPaint contract, retire autoAlpha rewrite (#2021)
* refactor(engine,producer): adopt requestPaint contract, retire autoAlpha rewrite

crbug 529829538 was closed "working as intended": the html-in-canvas API's
contract is mutate -> canvas.requestPaint() -> await the canvas paint event ->
drawElementImage, which refreshes the subtree's paint records including
compositor-applied properties. Verified on the pinned 151 floor and 152
canary: root opacity, root filter, nested group opacity, and child transforms
(incl. will-change-promoted) all capture exactly; the root element's own
TRANSFORM is the one property still never baked.

- Paint invalidation: all three paint-wait sites (serial capture, worker
  produce, batch produce) now call canvas.requestPaint() when available and
  fall back to the __hf_de_tick sentinel background toggle on builds without
  it. The 250ms unsynchronized-draw safety net is unchanged.
- Root-opacity ratio correction REMOVED (all three draw sites + base-opacity
  recording at injection). Since 151 the paint wait bakes current root opacity
  into the snapshot as pixel alpha, so the ratio correction DOUBLE-APPLIED
  animated root fades: a root-fade A/B tripped the runtime self-verify at
  30.1dB (frame 24, ~0.92 expected vs ~0.85 rendered). Post-removal the same
  comp self-verifies at inf and matches the screenshot render at PSNR=inf.
  The root TRANSFORM correction stays — verified still required.
- autoAlpha rewrite machinery DELETED: the opt-in opacity->autoAlpha tween
  rewrite (default-off since the retraction fix; measured ~28dB damage on
  comps whose fades it touched), its flush-time transparent-target hiding,
  the __HF_FAST_CAPTURE_AUTOALPHA__ flag plumbing, and the deferral-time
  retract/re-assert dance. The stub keeps tween-target tracking (3D
  projection + at-risk scans depend on it).

Validation: canary suite 7/7 with PSNRs identical to baseline (58.30 /
43.13 / 54.15 dB); root-fade A/B PSNR=inf vs screenshot; engine suite 905
passed (1 pre-existing color-grading failure); tsc/oxlint/oxfmt clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(engine,producer): review fixes — gate opacity correction by paint mechanism

Max code-review findings on the requestPaint adoption:

- Root-opacity ratio correction RESTORED, gated per frame on how the paint
  was produced: it applies on BeginFrame (sync=false) captures and on builds
  without canvas.requestPaint() — the two paths where the snapshot holds the
  root's load-time opacity — and is skipped only on requestPaint-driven
  paints, where the snapshot bakes the current opacity and the ratio
  double-applies (the proven 30.1dB root-fade failure). Base opacity is
  recorded at injection again.
- Invalidation extracted to a page-scope helper (__hfDeInvalidate, installed
  by injectDrawElementCanvas) shared by all three paint-wait sites: sentinel
  toggle ALWAYS (a paint is guaranteed even if requestPaint elides one on a
  clean subtree) + requestPaint() in a try/catch (a throwing implementation
  degrades to sentinel-only instead of rejecting the capture). Returns
  whether requestPaint ran, feeding the opacity-correction gate. Also removes
  the triplicated inline block and its three anonymous `as T` casts.
- HF_FAST_CAPTURE_AUTOALPHA now logs a retirement warning instead of being a
  silent no-op (the deleted rewrite's comment documented it as an operator
  escape hatch).
- Batch producer docstring updated (still described the tick-toggle-only
  paint wait); stub tween observer reshaped to a void fn (observeTweenCall)
  so no arg-rewriting seam survives.

Validation: canary suite 7/7 (58.30/43.13/54.15dB, d95f20b6 clean);
root-fade A/B self-verify 4x inf + whole-video PSNR=inf; engine suite 905
passed (1 pre-existing); tsc/oxlint/oxfmt clean; stub regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: WaterrrForever <miao.yang@heygen.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 01:52:26 -07:00
Vance IngallsandClaude Opus 4.8 d5ecb013d7 perf(engine,producer): batch N drawElement frames per CDP round-trip (HF_DE_BATCH) (#1928)
Amortizes per-frame CDP protocol overhead (~3.5-9ms/frame) by looping
seek -> paint-wait -> drawElementImage -> createImageBitmap in ONE
page.evaluate for runs of consecutive frames; bitmaps still post to the
encode worker per frame. Validated on 19 stratified DE comps: median
1.20x on top of worker-encode (to 1.56x), zero damaged frames, edge
comps (static-dedup-heavy, clip-cut) bit-identical; mid-batch failure
re-captures via the per-frame path (screenshot-fallback semantics
preserved). Off by default; opt in with HF_DE_BATCH=4.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 16:27:31 -07:00
Vance IngallsandClaude Fable 5 795934adba feat(engine): drawElementImage capture service (#1917)
* feat(engine): drawElementImage capture service

* chore(ci): ignore drawElementService exports pending upstack consumers

Fallow's per-PR audit diffs against the merge base, so the bottom of the
fast-capture stack (#1917) sees drawElementService's exports as unused —
their consumers (frameCapture) land in #1919, two PRs upstack. ignoreExports
entry documents this and can be dropped once #1919 merges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:19:17 -07:00