Skip to content

Commit 56eeca9

Browse files
jplexerclaude
andcommitted
fw/applib/graphics: only pre-load glyph bitmaps when rendering
text_resources_get_glyph_horiz_advance() loaded the glyph bitmap on every call so the following render_glyph() would find it cached. But the advance is also queried from measure/layout passes (e.g. a text node's get_size walk), so measuring paid the deep glyph-bitmap flash load (resource_load -> pfs_open -> flash). Reached through the launcher's app-glance get_size, nested in the menu render, this overflowed the app task's 2 KB stack. Make the advance metadata-only again and pre-load the bitmap explicitly in walk_line()'s render pass, so the deep flash I/O stays out of the render call chain without charging measure passes for it. walk_line() now references text_resources_get_glyph(), so add the matching stub to stubs_text_resources.h for the layout/iterator unit tests. Fixes FIRM-2160 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Joshua Jun <lets@throw.rocks>
1 parent 02a44b2 commit 56eeca9

3 files changed

Lines changed: 18 additions & 3 deletions

File tree

src/fw/applib/graphics/text_layout.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@ utf8_t* walk_line(GContext* ctx, Line* line, const TextBoxParams* const text_box
580580
CharVisitorCallback char_visitor_cb) {
581581
PBL_ASSERTN(char_visitor_cb);
582582

583+
// Render pre-loads glyph bitmaps below; measure must not, or the deep flash load overflows.
584+
const bool is_render = (char_visitor_cb != update_dimensions_char_visitor_cb);
585+
583586
// We used to check that the line height was <= the container height here - no longer required,
584587
// as the vertical overflow is handled during layout.
585588

@@ -885,6 +888,12 @@ utf8_t* walk_line(GContext* ctx, Line* line, const TextBoxParams* const text_box
885888
};
886889
cursor.origin.x += walked_width_px;
887890

891+
if (is_render && !codepoint_is_zero_width(current_codepoint) &&
892+
!codepoint_is_unicode_space(current_codepoint)) {
893+
// Pre-load here so the deeper render_glyph() is a cache hit, not a deep flash read.
894+
text_resources_get_glyph(&ctx->font_cache, current_codepoint, text_box_params->font);
895+
}
896+
888897
char_visitor_cb(ctx, text_box_params, line, cursor, current_codepoint);
889898

890899
walked_width_px += next_glyph_width_px;
@@ -941,6 +950,9 @@ utf8_t* walk_line(GContext* ctx, Line* line, const TextBoxParams* const text_box
941950
};
942951
cursor.origin.x += walked_width_px;
943952
if (char_visitor_cb) {
953+
if (is_render) {
954+
text_resources_get_glyph(&ctx->font_cache, line->suffix_codepoint, text_box_params->font);
955+
}
944956
char_visitor_cb(ctx, text_box_params, line, cursor, line->suffix_codepoint);
945957
}
946958
}

src/fw/applib/graphics/text_resources.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,8 @@ static const GlyphData *prv_get_glyph(FontCache *font_cache, Codepoint codepoint
613613

614614
int8_t text_resources_get_glyph_horiz_advance(FontCache *font_cache, const Codepoint codepoint,
615615
FontInfo *font_info) {
616-
// Pre-load the bitmap so the subsequent render_glyph() call finds it cached in glyph_buffer,
617-
// avoiding deep flash I/O calls from within the render call chain (prevents app stack overflow).
618-
const GlyphData *g = prv_get_glyph(font_cache, codepoint, font_info, true /* need_bitmap */);
616+
// Metadata only: measuring must not pay the deep bitmap load; render pre-loads it in walk_line().
617+
const GlyphData *g = prv_get_glyph(font_cache, codepoint, font_info, false /* need_bitmap */);
619618
if (!g) {
620619
return 0;
621620
}

tests/stubs/stubs_text_resources.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ int8_t text_resources_get_glyph_height(FontCache* font_cache, Codepoint codepoin
3131
return 10;
3232
}
3333

34+
const GlyphData *text_resources_get_glyph(FontCache* font_cache, Codepoint codepoint, FontInfo* fontinfo) {
35+
return NULL;
36+
}
37+

0 commit comments

Comments
 (0)