ghostty-next: pin 12ec155e1 (fork PRs #77, #79): an off-main present commits only a frame it shows

Merged
LA
2d ago
+26-14

Summary

FRAME OWNER REFACTOR S4 (cmux-ad m6), the next step before the default flip of motion.frameOwner.terminals. GhosttyNextKit and the ghostty-next gitlink move together from 6cc749a8a to 12ec155e1 on release/cmux-9ce9b7d0-e2:

  • manaflow-ai/ghostty-next#79: an off-main present begins a Core Animation transaction only for a frame it shows. Before, setSurfaceOffMain began and committed a transaction before its checks. So each frame that went through main (with the switch on, every frame of a new size) committed an empty transaction on the GPU completion thread, against main's own commit. Profile 4b41c42c (held keys-stress, switch on) measured 405 ms of CA::Context::commit_transaction there in one round; the new IOSurface per size cost only about +100 ms. Reviews: independent subagent SHIP at 7f2dcbf36 (comment 6647855551).
  • manaflow-ai/ghostty-next#77: a test and one shared drop rule (no behavior change).

With the switch off (the default), nothing a person sees changes: the only off-path change is that a frame a newer frame superseded no longer commits an empty transaction.

The release: xcframework-12ec155e1e67f8f33a1cee5fd2e129f59277465c-apple-v6 (run 41955494921), zip sha256 5defd8f8b83a4fc8a7f74d805be380d5c566702cf35a19c2b92c0adda1730aa7. It agrees with the release's SHA256SUMS, the GitHub asset digest and the manifest's commit. The changed fork files (src/renderer/metal/IOSurfaceLayer.zig, src/renderer/Metal.zig) are not in the libghostty-vt link graph, so vt-link-graph.json changes only its commit. package-notices.json names the new paths (no license file or dependency change). check_ghostty_vt_notices.py --check-link-graph and package_notices.py check-data pass at this head.

Coordination: the same two commits are merged on the sync line as manaflow-ai/ghostty-next#80 (706c6963a). cmux #35478 must pin 706c6963a or later.

Testing

  • Fork: red at 694f7ffb7 (run 41953548703: only the new test fails, IOSurfaceLayer.zig:862, expected 0 commits, found 1); green at 7f2dcbf36 (run 41953551466: 111/111, lib-vt 97/97).
  • The gate A/B for the flip (pixel-perfect's 8-row rule), old pin 6cc749a8a against this pin, both from feat 4c35e528520 with the same bench file (scratch branches scratch/frame-owner-s4-gate-{old,new}-nomerge), on cmux24-perf, interleaved, 6 rounds, switch OFF and ON in each launch, background CPU per round (a round over 1 s is dropped and named): single presses b18904f4 (new) / 6d9dd1c4 (old); held keys 9acc4c56 (new) / efdb32f3 (old); profile at this pin f34e6860. Results replace this line.

Observed / Not run

  • Observed: the fork runs above; the two notice checks; prepush-gate.py passes.
  • Observed also: the 42 terminal suites at a1cf441095c (step 50f6ed920256d3914d8f0d46): all 42 suites ran, 224 tests pass, 0 fail. Independent review: SHIP at a1cf441095c (comment 6648707100). Its one finding (the fork doc's conflict note named the old order) is fixed in 0ba3948e9e4, a docs-only commit.
  • Observed also: the display suites at a1cf441095c (step 8a1efc6f628c9a44e6e2d4bc): TerminalKeyResizeFrameTests, TerminalFrameOwnerMainThreadTests and TerminalSurfaceCommitSizeTests pass. Gate A/B: single presses at this pin (b18904f4) pass 4 of 4 rows; the old pin's single run (6d9dd1c4, same day) failed keys and keys-stress. Held keys at this pin (9acc4c56): keys, light and STRESS drag pass; keys-stress still fails (OFF 20 / ON 42 over 4 valid pairs), so the flip stays off. The old pin's held run (efdb32f3) failed keys, STRESS drag and keys-stress. Profile at this pin: f34e6860.
  • Films (pixel-perfect, STATUS 13709; cmux22, the same kit, m14 judge f2497414978c): this head 0ba3948e9e45 against its base 4c35e528520 (old pin): single-3k, rk-3t and lowprompt-reverse equal within 1 frame in every film, so no new red. held-2 at this head (requeued alone as ab-fixah2, after the first try did not record): terminal frame fails 2/2/0/0 against the base's 2/2/0/0, page frame fails 127/130/79/80 against 124/128/84/81. No new red in any film (STATUS 13726).
  • Not run: the flip. It needs the remaining held keys-stress cost gone (STATUS 13630, 13658). The flip PR turns the switch on only if the gate A/B shows no layout worse with ON.

Frames: terminal: with the switch off (the default), what the person sees in each frame does not change from the old pin 6cc749a8a. With the switch on (not shipped), the frames shown are the same; a frame that goes through main no longer costs an empty transaction on the GPU completion thread.

No capture: the change is behind a Debug switch that is off by default, and with it off no frame changes.

Changelog

none