Repository navigation
fix(core): a mover holding a fixed child stays sharp in the filter tier - #7292
Conversation
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head 90528fb6
The fix is right for the left mover, but it also drops movers that auto sends to the filter tier today, where they already blur correctly. ↓ inline
Scope
Read the full diff, filterTier.ts, discover.ts (scanMovers), and the auto hand-off in index.ts (handOff, translationOnly). Probed headless Chromium 1237: a fixed child of a mover with transform: translate(40px,0) is at 250,110 with or without filter: blur(1px), while a fixed child of a left mover moves from 10,10 to 210,310 once the filter is added. At review time CI, PR captures, preview-regression and the Player perf/audio runs were green; CodeQL, regression, Windows render verification and Player Safari perf were still running.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ready a containing block Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
90528fb to
1d4d398
Compare
There was a problem hiding this comment.
Verdict: APPROVE — 1 resolved, 0 open, 0 new · 90528fb6 → 1d4d3985
Scope
Re-read filterTier.ts at head: the containing-block check runs after readMoverFrames restores frame t, so it sees the frame's own pose and not the temporary UNTRANSFORMED read style. Core captureMotionBlur 215/215 pass locally. CI, regression, preview-regression, CodeQL, Player perf/Safari audio are green; Windows render verification, Player Safari perf and a duplicate CI run were still running at review time.
…view Adopts heygen-com#7294 (line_unread findings carry the measured frames), heygen-com#7271 (blur mutes discrete callbacks instead of undoing them), heygen-com#7293 (the filter tier's svg keeps the last child), heygen-com#7292 (a mover holding a fixed child stays sharp), heygen-com#7288 (auto motion blur draws with the filter tier) and heygen-com#7298 (Shift no longer re-renders the timeline). The fork's seek recovery in captureMotionBlur stays. Defers heygen-com#7134 (no packages/share) and heygen-com#7295 (needs the heygen-com#7080 crop pipeline). Watermark advances to 66cbabc. Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com> Co-authored-by: Vance Ingalls <vance@heygen.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-com#7288) 537b88d adopted heygen-com#7288, which makes auto motion blur draw with the filter tier, but left out the engine side. Pixel tests that expect the capture tier then failed on Windows CI. Take upstream e2bb7da's change to captureMotionBlur.pixels.browser.test.ts, which asks those tests for the capture tier explicitly. The other engine files that heygen-com#7271/heygen-com#7288/heygen-com#7292/heygen-com#7293 touch (fixtures, thresholds, sweep and differential tests) do not exist in this fork. Co-authored-by: Vance Ingalls <vance@heygen.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
In the filter tier, a mover that holds a
position: fixeddescendant is now left sharp instead of blurred. The filter tier puts a CSSfilteron the mover, which makes the mover the containing block of its fixed children, so a badge that should stay put jumps into the mover (sweep defect F: 3495 px differ from the 32-sample oracle for the filter tier against 721 for capture, for a fixed child of a mover that moves vialeft). Sharp is correct; a jumped badge is wrong, and nothing done in place can avoid the jump. The other movers still blur, and the capture tier is unchanged.holdsFixedChild(el)walks the mover's descendants (capped atCONTENT_NODE_LIMIT, 256, now exported fromframes.ts, the same capgrownBoxuses) and reads each computedposition. It runs once per scan indiscover, not per frame.Why now: #7288 makes
autodraw with the filter tier, which would put this defect on the default path (before that changeautokept aleft-moving mover on capture). This PR is independent of #7288 and fixes the same defect for anyone who already forcesdata-motion-blur-tier="filter"or hits the filter fallback.Tests
index.test.ts:leaves a mover with a fixed descendant out of the filter tier and blurs the others: two movers, one with aposition: fixedchild;report().moverNameslists only the other and the dropped mover gets no filter style.fixed-child-left(filter tier) loses itsbugfield andS.F_FILTERand now passes as an ordinary outside-the-trail check. Its old region included the child's true spot, which is outside every trail, so it still fails if the child jumps.captureMotionBlur213 pass; engine sweep 17 pass on Chrome 153.Update after review
Genesis found that dropping every mover that holds a fixed child also stopped blurring transform-moved movers, where the filter does nothing to the fixed child (any
transform,translate,rotate,scaleorperspectiveother thannonealready makes the mover its containing block). Fixed in 32368adeb:discoveronly flags the movers that hold a fixed descendant, andplansAtleaves a flagged mover sharp on a frame only when it is not already a containing block at that frame's own pose (computedtransform/translate/rotate/scale/perspectiveallnone, nowill-changeof transform/perspective/filter, nocontainof paint/layout/strict/content). A GSAP-xcard with a fixed badge keeps its blur.report().moversandmoverNamesstay the scan's full list, including movers held sharp on a frame.Tests added: the
left-moved holder stays sharp, a transform mover with a fixed child still getsurl(#hf-mb-, and a mover whose transform isnoneat one frame and set at the next is sharp then blurred. Known limit: an author-setfilteron a flagged mover is not counted as a containing block (computedfiltercannot be told apart from our own smear), so such a mover stays sharp.Limits
hyperframes checksaysmotion_blur_no_movers("nothing moves fast enough") when every mover is dropped this way; a follow-up would report which movers were left sharp and why.🤖 Generated with Claude Code