diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-31 13:12:38 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-31 13:12:38 +0200 |
commit | 897e8eb967bb2e26410d1a0cb7ca41ce9e3cf953 (patch) | |
tree | 01a0749073cc645471482d634226b09e97ee3caa /src/ui | |
parent | b17a50de97780ab43ca958f9d84200388cac9b90 (diff) |
Text: Clear glyph cache when it fills up
We can use a smaller glyph cache if we clear it when it fills up. Even a large cache would eventually fill up, so clearing is a good strategy anyway. Clears occur still rather infrequently.
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/text.c | 30 | ||||
-rw-r--r-- | src/ui/window.c | 2 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/ui/text.c b/src/ui/text.c index e9ca17e7..2b3e187d 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -130,10 +130,15 @@ static void init_Font(iFont *d, const iBlock *data, int height, float scale, | |||
130 | memset(d->indexTable, 0xff, sizeof(d->indexTable)); | 130 | memset(d->indexTable, 0xff, sizeof(d->indexTable)); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void deinit_Font(iFont *d) { | 133 | static void clearGlyphs_Font_(iFont *d) { |
134 | iForEach(Hash, i, &d->glyphs) { | 134 | iForEach(Hash, i, &d->glyphs) { |
135 | delete_Glyph((iGlyph *) i.value); | 135 | delete_Glyph((iGlyph *) i.value); |
136 | } | 136 | } |
137 | clear_Hash(&d->glyphs); | ||
138 | } | ||
139 | |||
140 | static void deinit_Font(iFont *d) { | ||
141 | clearGlyphs_Font_(d); | ||
137 | deinit_Hash(&d->glyphs); | 142 | deinit_Hash(&d->glyphs); |
138 | delete_Block(d->data); | 143 | delete_Block(d->data); |
139 | } | 144 | } |
@@ -149,6 +154,8 @@ static uint32_t glyphIndex_Font_(iFont *d, iChar ch) { | |||
149 | return stbtt_FindGlyphIndex(&d->font, ch); | 154 | return stbtt_FindGlyphIndex(&d->font, ch); |
150 | } | 155 | } |
151 | 156 | ||
157 | /*----------------------------------------------------------------------------------------------*/ | ||
158 | |||
152 | iDeclareType(Text) | 159 | iDeclareType(Text) |
153 | iDeclareType(CacheRow) | 160 | iDeclareType(CacheRow) |
154 | 161 | ||
@@ -332,11 +339,15 @@ static void deinitFonts_Text_(iText *d) { | |||
332 | } | 339 | } |
333 | } | 340 | } |
334 | 341 | ||
342 | static int maxGlyphHeight_Text_(const iText *d) { | ||
343 | return 2 * d->contentFontSize * fontSize_UI; | ||
344 | } | ||
345 | |||
335 | static void initCache_Text_(iText *d) { | 346 | static void initCache_Text_(iText *d) { |
336 | init_Array(&d->cacheRows, sizeof(iCacheRow)); | 347 | init_Array(&d->cacheRows, sizeof(iCacheRow)); |
337 | const int textSize = d->contentFontSize * fontSize_UI; | 348 | const int textSize = d->contentFontSize * fontSize_UI; |
338 | iAssert(textSize > 0); | 349 | iAssert(textSize > 0); |
339 | const iInt2 cacheDims = init_I2(16, 80); | 350 | const iInt2 cacheDims = init_I2(16, 40); |
340 | d->cacheSize = mul_I2(cacheDims, init1_I2(iMax(textSize, fontSize_UI))); | 351 | d->cacheSize = mul_I2(cacheDims, init1_I2(iMax(textSize, fontSize_UI))); |
341 | SDL_RendererInfo renderInfo; | 352 | SDL_RendererInfo renderInfo; |
342 | SDL_GetRendererInfo(d->render, &renderInfo); | 353 | SDL_GetRendererInfo(d->render, &renderInfo); |
@@ -419,6 +430,14 @@ void setContentFontSize_Text(float fontSizeFactor) { | |||
419 | } | 430 | } |
420 | } | 431 | } |
421 | 432 | ||
433 | static void resetCache_Text_(iText *d) { | ||
434 | deinitCache_Text_(d); | ||
435 | for (int i = 0; i < max_FontId; i++) { | ||
436 | clearGlyphs_Font_(&d->fonts[i]); | ||
437 | } | ||
438 | initCache_Text_(d); | ||
439 | } | ||
440 | |||
422 | void resetFonts_Text(void) { | 441 | void resetFonts_Text(void) { |
423 | iText *d = &text_; | 442 | iText *d = &text_; |
424 | deinitFonts_Text_(d); | 443 | deinitFonts_Text_(d); |
@@ -574,6 +593,13 @@ static const iGlyph *glyph_Font_(iFont *d, iChar ch) { | |||
574 | iGlyph *glyph = new_Glyph(ch); | 593 | iGlyph *glyph = new_Glyph(ch); |
575 | glyph->glyphIndex = glyphIndex; | 594 | glyph->glyphIndex = glyphIndex; |
576 | glyph->font = font; | 595 | glyph->font = font; |
596 | /* If the cache is running out of space, clear it and we'll recache what's needed currently. */ | ||
597 | if (text_.cacheBottom > text_.cacheSize.y - maxGlyphHeight_Text_(&text_)) { | ||
598 | #if !defined (NDEBUG) | ||
599 | printf("[Text] glyph cache is full, clearing!\n"); fflush(stdout); | ||
600 | #endif | ||
601 | resetCache_Text_(&text_); | ||
602 | } | ||
577 | SDL_Texture *oldTarget = SDL_GetRenderTarget(text_.render); | 603 | SDL_Texture *oldTarget = SDL_GetRenderTarget(text_.render); |
578 | SDL_SetRenderTarget(text_.render, text_.cache); | 604 | SDL_SetRenderTarget(text_.render, text_.cache); |
579 | cache_Font_(font, glyph, 0); | 605 | cache_Font_(font, glyph, 0); |
diff --git a/src/ui/window.c b/src/ui/window.c index 2933a47d..c13d5843 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -969,7 +969,7 @@ void draw_Window(iWindow *d) { | |||
969 | #if 0 | 969 | #if 0 |
970 | /* Text cache debugging. */ { | 970 | /* Text cache debugging. */ { |
971 | SDL_Texture *cache = glyphCache_Text(); | 971 | SDL_Texture *cache = glyphCache_Text(); |
972 | SDL_Rect rect = { d->root->rect.size.x - 640, 0, 640, 5 * 640 }; | 972 | SDL_Rect rect = { d->root->rect.size.x - 640, 0, 640, 2.5 * 640 }; |
973 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); | 973 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); |
974 | SDL_RenderFillRect(d->render, &rect); | 974 | SDL_RenderFillRect(d->render, &rect); |
975 | SDL_RenderCopy(d->render, glyphCache_Text(), NULL, &rect); | 975 | SDL_RenderCopy(d->render, glyphCache_Text(), NULL, &rect); |