Skip to content

renderer: run DisplayLink only while a frame is pending - #14033

Closed
j-c-m wants to merge 1 commit into
ghostty-org:mainfrom
j-c-m:renderer-demand-vsync
Closed

j-c-m wants to merge 1 commit into
ghostty-org:mainfrom
j-c-m:renderer-demand-vsync

Conversation

@j-c-m

@j-c-m j-c-m commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

A focused vsync window currently keeps CVDisplayLink running at the display cadence. Idle frames still hop the render thread for a Metal no-op presentLastTarget.

Start the link from updateFrame when cells_rebuilt or an animation wake is set, so Thread.drawFrame(false) still waits for vsync. Stop it after a draw that leaves nothing pending. Unfocused, occluded, and window-vsync=false are unchanged.

Idle focused Time Profiler (t ≥ 5s): renderer plus CVDisplayLink went from 0.80% of one core on main to 0.13% on this branch (6.3×; 257 ms / 32 s vs 29 ms / 23 s).

This is from #14030 (comment), this looks like a clean win with minimal change for focused window efficiency.

AI - extensive use of grok 4.6 and some Claude in the experiments, this small change was all human after the research.

A focused vsync window currently keeps CVDisplayLink running at
the display cadence. Idle frames still hop the render thread for
a Metal no-op presentLastTarget.

Start the link from updateFrame when cells_rebuilt or an
animation wake is set, so Thread.drawFrame(false) still waits
for vsync. Stop it after a draw that leaves nothing pending.
Unfocused, occluded, and window-vsync=false are unchanged.

Idle focused Time Profiler (t ≥ 5s): renderer plus
CVDisplayLink went from 0.80% of one core on main to 0.13%
on this branch (6.3×; 257 ms / 32 s vs 29 ms / 23 s).
@j-c-m
j-c-m requested a review from a team as a code owner August 26, 2026 17:40
@ghostty-bot ghostty-bot Bot added the renderer label Aug 26, 2026
@mitchellh

Copy link
Copy Markdown
Contributor

Looks good, made some changes and replaced it with this #14035 kept you as coauthor

@mitchellh mitchellh closed this Aug 26, 2026
mitchellh added a commit that referenced this pull request Aug 26, 2026
#14033

Pause the CVDisplayLink when there isn't any real work to do.

Start the link after updateFrame rebuilds cells, keep it running while
cell changes or animations remain pending, and resync it from the
no-redraw path to sleep it again.

I also did some benchmark to measure the cost of starting/stopping the
display link since this includes a lot more of that and I found that a
continuously running link used 29 to 35 us of CPU per callback, while
starting and stopping it for every frame used 103 to 121 us. So, in some
pathological case this can be worse, but its still microseconds, and in
the normal case this helps Ghostty sleep a lot more.
pull Bot pushed a commit to fucheng-guo-sun/ghostty that referenced this pull request Aug 26, 2026
ghostty-org#14033

Pause the CVDisplayLink when there isn't any real work to do.

Start the link after updateFrame rebuilds cells, keep it running while
cell changes or animations remain pending, and resync it from the
no-redraw path to sleep it again. 

I also did some benchmark to measure the cost of starting/stopping the
display link since this includes a lot more of that and I found that
a continuously running link used 29 to 35 us of CPU per callback, while
starting and stopping it for every frame used 103 to 121 us. So, in some
pathological case this can be worse, but its still microseconds, and in
the normal case this helps Ghostty sleep a lot more.

Co-authored-by: Jesse Miller <jmiller@jmiller.com>
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