Metal: warm the glyph atlas with ASCII at enable time

The first big redraw with new content (e.g. the first tab switch)
rasterized a burst of new glyphs into the atlas, which showed as a
one-time whole-frame blink; subsequent switches were fluid because the
cache was hot. Pre-rasterize printable ASCII for the frame's default
face in mtl-enable-for-frame so that cost is paid up front.
This commit is contained in:
Andros Fenollosa 2026-06-03 17:09:08 +02:00
parent e139b04f16
commit 0b23c907dd
3 changed files with 22 additions and 0 deletions

View file

@ -111,6 +111,11 @@ FRAME must be a live graphical NS frame. */)
The NS terminal still handles events, menus, and scrollbars. */
mtl_patch_terminal_rif (f);
/* Warm the glyph atlas with printable ASCII for the default face so the
first big redraw (e.g. first tab switch) doesn't rasterize everything at
once, which showed as a visible blink. */
mtl_warm_glyph_cache (f);
/* Begin Metal rendering for this frame */
[fd beginFrame];
[fd endFrame];

View file

@ -263,6 +263,9 @@ extern MtlFrameData *mtl_get_frame_data (struct frame *f);
MtlGlyphCacheEntry *mtl_cache_glyph (CTFontRef font, uint32_t codepoint);
/* Pre-rasterize printable ASCII for FRAME's default face (atlas warm-up). */
extern void mtl_warm_glyph_cache (struct frame *f);
extern bool mtl_render_offscreen_png (const char *path, int w, int h,
void (^draw)(id<MTLRenderCommandEncoder>));
extern bool mtl_render_text_png (const char *path);

View file

@ -1820,6 +1820,20 @@ mtl_ctfont_for_face (struct face *face)
return (CTFontRef)ptr;
}
/* Pre-rasterize the printable ASCII range for FRAME's default face into the
glyph atlas. Called from mtl-enable-for-frame so the first full redraw of
new content (e.g. the first tab switch) does not pay the whole rasterization
cost at once, which showed up as a visible blink. */
void
mtl_warm_glyph_cache (struct frame *f)
{
struct face *face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
CTFontRef ctfont = mtl_ctfont_for_face (face);
if (!ctfont) return;
for (uint32_t c = 32; c < 127; c++)
mtl_cache_glyph (ctfont, c);
}
/* -----------------------------------------------------------------------
Phase 5: inline image support NSImage (EmacsImage) MTLTexture
----------------------------------------------------------------------- */