Skip to content

fix(engine): apply compositor determinism flags in screenshot mode#865

Closed
miguel-heygen wants to merge 1 commit into
mainfrom
worktree-fix+m1-compositor-shift
Closed

fix(engine): apply compositor determinism flags in screenshot mode#865
miguel-heygen wants to merge 1 commit into
mainfrom
worktree-fix+m1-compositor-shift

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Summary

  • Fixes vertical compositor shift on Apple Silicon reported in Apple Silicon M1: CLI render has vertical compositor shift after ~12s; Studio preview and Intel render are stable #828 — renders on M1 produced downward layout shifts after ~12 seconds
  • Root cause: Chrome's compositor determinism flags (--run-all-compositor-stages-before-draw, --disable-threaded-animation, --enable-surface-synchronization, etc.) were only applied for BeginFrame mode (Linux). Screenshot mode (macOS/Windows) ran without them, allowing Metal's compositor to accumulate state drift over sustained frame captures
  • Fix: Split the 9 flags into two groups — 2 that are genuinely BeginFrame-exclusive (--enable-begin-frame-control, --deterministic-mode) and 7 compositor-determinism flags that are safe for all modes. The 7 are now applied unconditionally

Details

The compositor determinism flags enforce:

  • --run-all-compositor-stages-before-draw — flush all compositor stages before each draw/screenshot
  • --disable-threaded-animation — animations process on main thread, not a separate compositor thread
  • --enable-surface-synchronization — renderer and browser compositor surfaces stay in sync
  • --disable-threaded-scrolling, --disable-checker-imaging, --disable-image-animation-resync, --disable-new-content-rendering-timeout — remove other sources of non-determinism

Without these, Chrome's Metal backend (Apple Silicon) could race between the compositor thread and Page.captureScreenshot, accumulating vertical offset over hundreds of frames.

Test plan

  • Added unit tests verifying compositor flags present in screenshot mode and absent beginFrame-exclusive flags
  • Added unit tests verifying beginframe mode still gets all flags (both groups)
  • All 594 engine tests pass
  • Pre-commit hooks pass (lint, format, typecheck, commitlint)
  • Rendered 30s composition before/after on Apple Silicon (M4 Pro) — no regressions

Closes #828

Chrome's compositor determinism flags (--run-all-compositor-stages-before-draw,
--disable-threaded-animation, --enable-surface-synchronization, etc.) were
previously only applied for BeginFrame mode on Linux. In screenshot mode —
used on macOS/Windows — the compositor ran without these constraints, allowing
Metal on Apple Silicon to accumulate state drift over sustained frame captures.

This produced vertical layout shifts after ~12 seconds of rendering, reported
on M1 machines. The shifts occurred because the compositor's threaded animation
and surface synchronization pipelines could race with Page.captureScreenshot,
and without --run-all-compositor-stages-before-draw, pending compositor stages
weren't flushed before each screenshot.

Split the flags into two groups:
- BEGINFRAME_EXCLUSIVE_FLAGS: --enable-begin-frame-control and
  --deterministic-mode, which pause the compositor or freeze the clock and
  must NOT be used in screenshot mode
- COMPOSITOR_DETERMINISM_FLAGS: the remaining 7 flags that enforce
  deterministic compositor behavior and are safe for all capture modes

The compositor flags are now applied unconditionally in buildChromeArgs.

Closes #828
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.

Apple Silicon M1: CLI render has vertical compositor shift after ~12s; Studio preview and Intel render are stable

1 participant