Skip to content

renderer: vsync unfocused surfaces while dirty - #14068

Merged
mitchellh merged 1 commit into
ghostty-org:mainfrom
j-c-m:renderer-unfocused-vsync
Aug 30, 2026
Merged

mitchellh merged 1 commit into
ghostty-org:mainfrom
j-c-m:renderer-unfocused-vsync

Conversation

@j-c-m

@j-c-m j-c-m commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

A follow on for #14035, we can now fix a long standing effiency/performance bug now that we park the display link while idle. This actually could cause "animated" un-focused windows to use more GPU than their focused counterparts. (AI Agent interfaces seem to love animation).

6ae1784

Unfocused surfaces stopped the CVDisplayLink and encoded a GPU frame on every PTY wakeup. A burst of close writes became that many Metal submits instead of one vsync.

Keep the link running while the surface is visible and dirty or animating, whether or not it is focused. Idle surfaces still park.

6ae1784

Unfocused surfaces stopped the CVDisplayLink and encoded a GPU
frame on every PTY wakeup. A burst of close writes became that many
Metal submits instead of one vsync.

Keep the link running while the surface is visible and dirty or
animating, whether or not it is focused. Idle surfaces still park.
Focus continues to gate cursor blink, custom-shader animation, and
QoS.
@j-c-m
j-c-m requested a review from a team as a code owner August 29, 2026 14:22
@ghostty-bot ghostty-bot Bot added the renderer label Aug 29, 2026

@mitchellh mitchellh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually makes sense to me.

@mitchellh
mitchellh merged commit 83c5671 into ghostty-org:main Aug 30, 2026
98 checks passed
@github-actions github-actions Bot added this to the 1.4.0 milestone Aug 30, 2026
danielitus added a commit to danielitus/ghostty that referenced this pull request Sep 5, 2026
The installed app hard-froze on 2026-09-04: a render thread was stuck
forever inside CVDisplayLinkStop (exposed by upstream's per-frame
display-link parking, ghostty-org#14035/ghostty-org#14068), its 64-slot mailbox filled, and
the app thread then blocked forever in occlusionCallback.

- Keep the display link running while visible and stop it only on
  occlusion, and never call CVDisplayLinkStop on a link that is not
  running (deinit, loopExit).
- Bound every app-thread push to the render mailbox (including the
  macOS display-id change) and the IO thread's resize push. After the
  first timeout the surface is marked wedged and later pushes fail fast
  instead of stalling the UI again.
- Never lose state-carrying messages: undelivered visibility, focus,
  display, config and font-grid messages are kept and retried in order
  before the next push and on every render request, so a recovered
  render thread converges. Ownership of the config allocation and the
  font grid ref stays with the surface until delivered; the cell size
  is applied only once the renderer holds the new grid.
- Closing a surface whose render thread is wedged detaches the thread
  and leaks the surface instead of joining it (embedded apprt), so a
  dead tab can be closed without hanging the app.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants