cache font _files_ as well to avoid duplicate buffers

This commit is contained in:
wanp 2024-10-13 21:34:05 -03:00
parent 82bad550e5
commit ffab6a3924
2 changed files with 36 additions and 9 deletions

View File

@ -31,6 +31,19 @@ typedef struct StringArena {
static StringArena string_arena; static StringArena string_arena;
typedef struct FontFileBuffer {
size_t len;
unsigned char *buffer;
} FontFileBuffer;
typedef struct FontFileCacheItem {
char *key;
FontFileBuffer value;
} FontFileCacheItem;
static FontFileCacheItem *font_file_cache_hash;
static void string_arena_init(StringArena *arena) { static void string_arena_init(StringArena *arena) {
arena->head = cmalloc(sizeof *arena->head); arena->head = cmalloc(sizeof *arena->head);
arena->current_block = arena->head; arena->current_block = arena->head;
@ -103,12 +116,22 @@ static FontData *text_load_font_data(const char *path, int height_px) {
{ {
unsigned char *buf = NULL; unsigned char *buf = NULL;
int64_t buf_len = file_to_bytes(path, &buf); int64_t buf_len = 0;
/* if the file was already loaded just get it */
FontFileCacheItem *font_file_ptr = shgetp_null(font_file_cache_hash, path);
if (font_file_ptr != NULL) {
buf = font_file_ptr->value.buffer;
buf_len = font_file_ptr->value.len;
} else {
buf_len = file_to_bytes(path, &buf);
FontFileBuffer buffer = { buf_len, buf };
shput(font_file_cache_hash, path, buffer);
}
stbtt_InitFont(&font_data->info, buf, stbtt_GetFontOffsetForIndex(buf, 0)); stbtt_InitFont(&font_data->info, buf, stbtt_GetFontOffsetForIndex(buf, 0));
/* might as well get these now, for later */ /* might as well get these now, for later */
font_data->file_bytes = buf;
font_data->file_bytes_len = buf_len;
font_data->scale_factor = stbtt_ScaleForPixelHeight(&font_data->info, (float)height_px); font_data->scale_factor = stbtt_ScaleForPixelHeight(&font_data->info, (float)height_px);
stbtt_GetFontVMetrics( stbtt_GetFontVMetrics(
&font_data->info, &font_data->info,
@ -142,7 +165,6 @@ static FontData *text_load_font_data(const char *path, int height_px) {
static void text_destroy_font_data(FontData *font_data) { static void text_destroy_font_data(FontData *font_data) {
SDL_free(font_data->file_bytes);
delete_gpu_texture(font_data->texture); delete_gpu_texture(font_data->texture);
SDL_free(font_data); SDL_free(font_data);
} }
@ -192,7 +214,7 @@ static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color
static void ensure_font_cache(const char *font_path, int height_px) { static void ensure_font_cache(const char *font_path, int height_px) {
/* HACK: stupid, bad, don't do this */ /* HACK: don't */
bool is_cached = false; bool is_cached = false;
for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) { for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) {
FontData *font_data = ctx.text_cache.data[i]; FontData *font_data = ctx.text_cache.data[i];
@ -229,6 +251,8 @@ void render_text(const TextPrimitive *text) {
void text_cache_init(TextCache *cache) { void text_cache_init(TextCache *cache) {
arrsetlen(cache->data, 0); arrsetlen(cache->data, 0);
string_arena_init(&string_arena); string_arena_init(&string_arena);
sh_new_arena(font_file_cache_hash);
} }
@ -237,8 +261,13 @@ void text_cache_deinit(TextCache *cache) {
text_destroy_font_data(ctx.text_cache.data[i]); text_destroy_font_data(ctx.text_cache.data[i]);
} }
arrfree(cache->data); for (size_t i = 0; i < shlenu(font_file_cache_hash); ++i) {
SDL_free(font_file_cache_hash[i].value.buffer);
}
shfree(font_file_cache_hash);
string_arena_deinit(&string_arena); string_arena_deinit(&string_arena);
arrfree(cache->data);
} }

View File

@ -22,8 +22,6 @@ typedef struct FontData {
stbtt_fontinfo info; stbtt_fontinfo info;
const char *file_path; const char *file_path;
unsigned char *file_bytes;
size_t file_bytes_len;
GPUTexture texture; GPUTexture texture;