diff --git a/src/mtlfns.m b/src/mtlfns.m index 01be4988138..78f7bc4381a 100644 --- a/src/mtlfns.m +++ b/src/mtlfns.m @@ -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]; diff --git a/src/mtlterm.h b/src/mtlterm.h index 2686dee2ec7..949b64f5236 100644 --- a/src/mtlterm.h +++ b/src/mtlterm.h @@ -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)); extern bool mtl_render_text_png (const char *path); diff --git a/src/mtlterm.m b/src/mtlterm.m index a56d3bfc404..ee4bf3d9130 100644 --- a/src/mtlterm.m +++ b/src/mtlterm.m @@ -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 ----------------------------------------------------------------------- */