Skip to content

Cache font metrics during redraw to reduce Unicode TUI stalls#292

Merged
dakra merged 1 commit into
dakra:mainfrom
Cianidos:fix/font-metric-hot-path
May 19, 2026
Merged

Cache font metrics during redraw to reduce Unicode TUI stalls#292
dakra merged 1 commit into
dakra:mainfrom
Cianidos:fix/font-metric-hot-path

Conversation

@Cianidos
Copy link
Copy Markdown
Contributor

Summary

This reduces redraw stalls for Unicode-heavy TUIs such as btop by avoiding repeated query-font calls for the same font during a single Ghostel redraw.

Fixes #291

Changes

  • Add ghostel--query-font-cached, dynamically backed by a redraw-local hash table.
  • Bind the cache around the native renderer call in ghostel--delayed-redraw.
  • Have the native renderer call ghostel--query-font-cached instead of query-font.
  • Dynamically raise gc-cons-threshold and gc-cons-percentage only while rendering a frame.
  • Add a focused test for the query-font cache.

Why

Profiling a btop session showed redraw spending significant time in repeated Emacs font metric queries and automatic GC. A single redraw could call query-font thousands of times for repeated fonts.

This patch keeps existing glyph adjustment behavior intact. It intentionally does not skip font-at or font-get-glyphs, because an attempted default-font fast path caused visible TUI border artifacts.

Validation

  • zig fmt src/Renderer.zig src/emacs.zig
  • make .build/tests/elisp-ghostel-glyph-kitty-test.ok
  • make .build/tests/native-ghostel-glyph-kitty-test.ok

Manual validation:

  • btop at 100ms update interval remains responsive.
  • No shifted border or visual artifacts observed after removing the unsafe glyph-adjustment skip.

@emil-e
Copy link
Copy Markdown
Collaborator

emil-e commented May 19, 2026

Thanks for the PR. This is a good improvement and I think we should merge it.

Long term, I think it's even better to cache the scaling per glyph but I can take it upon me to implement that, this at least improves the immediate case.

@emil-e
Copy link
Copy Markdown
Collaborator

emil-e commented May 19, 2026

LGTM. @dakra Any concerns?

@dakra
Copy link
Copy Markdown
Owner

dakra commented May 19, 2026

lgtm. I'll simplify the gc-cons-threshold code a bit and then merge.
Don't think we need a defcustom for it and can just use the let* binding we already have for the whole redraw function.
The Emacs native pixel-scroll.el does also just

          ;; The animations are smoother if the GC threshold is
          ;; reduced for the duration of the animation.
          (gc-cons-threshold (min most-positive-fixnum
                                  (* gc-cons-threshold 3)))

to temproarily disable garbage collection. So think the same is fine for us and we don't need 2 more defcustoms.

@dakra dakra force-pushed the fix/font-metric-hot-path branch from 6cc1e41 to 056d5e9 Compare May 19, 2026 15:24
@dakra dakra merged commit 056d5e9 into dakra:main May 19, 2026
37 of 38 checks passed
@dakra
Copy link
Copy Markdown
Owner

dakra commented May 19, 2026

Merged. Thanks ❤️

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.

Unicode-heavy TUI redraws can freeze Emacs due to repeated font metric queries and GC churn

3 participants