From 94ebc972ce1db6075f2ae17ca5461b03abaa3f95 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 8 Jul 2024 22:05:44 +0530 Subject: [PATCH] move sprite position map to verstable --- kitty/fonts.c | 13 +++--- kitty/glyph-cache.c | 92 +++++++++++++++++++++++++++-------------- kitty/glyph-cache.h | 15 +++---- kitty/kitty-verstable.h | 6 --- 4 files changed, 76 insertions(+), 50 deletions(-) diff --git a/kitty/fonts.c b/kitty/fonts.c index cd6595ebf..b10a94e51 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -58,7 +58,7 @@ typedef enum { SPACER_STRATEGY_UNKNOWN, SPACERS_BEFORE, SPACERS_AFTER, SPACERS_I typedef struct { PyObject *face; // Map glyphs to sprite map co-ords - SpritePosition *sprite_position_hash_table; + SPRITE_POSITION_MAP_HANDLE sprite_position_hash_table; hb_feature_t* ffs_hb_features; size_t num_ffs_hb_features; GlyphProperties *glyph_properties_hash_table; @@ -142,9 +142,7 @@ font_group_is_unused(FontGroup *fg) { void free_maps(Font *font) { free_sprite_position_hash_table(&font->sprite_position_hash_table); - font->sprite_position_hash_table = NULL; free_glyph_properties_hash_table(&font->glyph_properties_hash_table); - font->glyph_properties_hash_table = NULL; } static void @@ -169,7 +167,7 @@ del_font_group(FontGroup *fg) { fg->fallback_font_map = NULL; } for (size_t i = 0; i < fg->fonts_count; i++) del_font(fg->fonts + i); - free(fg->fonts); fg->fonts = NULL; + free(fg->fonts); fg->fonts = NULL; fg->fonts_count = 0; } static void @@ -256,7 +254,7 @@ do_increment(FontGroup *fg, int *error) { static SpritePosition* sprite_position_for(FontGroup *fg, Font *font, glyph_index *glyphs, unsigned glyph_count, uint8_t ligature_index, unsigned cell_count, int *error) { bool created; - SpritePosition *s = find_or_create_sprite_position(&font->sprite_position_hash_table, glyphs, glyph_count, ligature_index, cell_count, &created); + SpritePosition *s = find_or_create_sprite_position(font->sprite_position_hash_table, glyphs, glyph_count, ligature_index, cell_count, &created); if (!s) { *error = 1; return NULL; } if (created) { s->x = fg->sprite_tracker.x; s->y = fg->sprite_tracker.y; s->z = fg->sprite_tracker.z; @@ -360,6 +358,8 @@ static bool init_font(Font *f, PyObject *face, bool bold, bool italic, bool emoji_presentation) { f->face = face; Py_INCREF(f->face); f->bold = bold; f->italic = italic; f->emoji_presentation = emoji_presentation; + f->sprite_position_hash_table = create_sprite_position_hash_table(); + if (!f->sprite_position_hash_table) { PyErr_NoMemory(); return false; } const FontFeatures *features = features_for_face(face); f->ffs_hb_features = calloc(1 + features->count, sizeof(hb_feature_t)); if (!f->ffs_hb_features) { PyErr_NoMemory(); return false; } @@ -1278,6 +1278,7 @@ test_shape(PyObject UNUSED *self, PyObject *args) { if (face == NULL) return NULL; font = calloc(1, sizeof(Font)); font->face = face; + font->sprite_position_hash_table = create_sprite_position_hash_table(); } else { FontGroup *fg = font_groups; font = fg->fonts + fg->medium_font_idx; @@ -1537,6 +1538,8 @@ initialize_font_group(FontGroup *fg) { fg->fonts = calloc(fg->fonts_capacity, sizeof(Font)); if (fg->fonts == NULL) fatal("Out of memory allocating fonts array"); fg->fonts_count = 1; // the 0 index font is the box font + fg->fonts[0].sprite_position_hash_table = create_sprite_position_hash_table(); + if (!fg->fonts[0].sprite_position_hash_table) fatal("Out of memory"); #define I(attr) if (descriptor_indices.attr) fg->attr##_font_idx = initialize_font(fg, descriptor_indices.attr, #attr); else fg->attr##_font_idx = -1; fg->medium_font_idx = initialize_font(fg, 0, "medium"); I(bold); I(italic); I(bi); diff --git a/kitty/glyph-cache.c b/kitty/glyph-cache.c index e7bcc32ea..982223f9b 100644 --- a/kitty/glyph-cache.c +++ b/kitty/glyph-cache.c @@ -6,62 +6,90 @@ */ #include "glyph-cache.h" -#include "kitty-uthash.h" - -typedef struct SpritePosItem { - SpritePositionHead - UT_hash_handle hh; +typedef struct SpritePosKey { + size_t keysz_in_bytes; glyph_index key[]; -} SpritePosItem; +} SpritePosKey; -static glyph_index *scratch = NULL; -static unsigned scratch_sz = 0; +#define NAME sprite_pos_map +#define KEY_TY const SpritePosKey* +#define VAL_TY SpritePosition* +static uint64_t sprite_pos_map_hash(KEY_TY key); +#define HASH_FN sprite_pos_map_hash +static bool sprite_pos_map_cmpr(KEY_TY a, KEY_TY b); +#define CMPR_FN sprite_pos_map_cmpr +static void free_const(const void* x) { free((void*)x); } +#define KEY_DTOR_FN free_const +#define VAL_DTOR_FN free_const + +#include "kitty-verstable.h" + +static uint64_t +sprite_pos_map_hash(const SpritePosKey *key) { + return vt_hash_bytes(key->key, key->keysz_in_bytes); +} + +static bool +sprite_pos_map_cmpr(const SpritePosKey *a, const SpritePosKey *b) { + return a->keysz_in_bytes == b->keysz_in_bytes && memcmp(a->key, b->key, a->keysz_in_bytes) == 0; +} + + +static SpritePosKey *scratch = NULL; +static size_t scratch_key_capacity = 0; void free_glyph_cache_global_resources(void) { - free(scratch); - scratch = NULL; scratch_sz = 0; + free(scratch); scratch = NULL; scratch_key_capacity = 0; } static unsigned key_size_for_glyph_count(unsigned count) { return count + 3; } +SPRITE_POSITION_MAP_HANDLE +create_sprite_position_hash_table(void) { + sprite_pos_map *ans = calloc(1, sizeof(sprite_pos_map)); + if (ans) vt_init(ans); + return (SPRITE_POSITION_MAP_HANDLE)ans; +} SpritePosition* -find_or_create_sprite_position(SpritePosition **head_, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created) { - SpritePosItem **head = (SpritePosItem**)head_, *p; - const unsigned key_sz = key_size_for_glyph_count(count); - if (key_sz > scratch_sz) { - scratch = realloc(scratch, sizeof(glyph_index) * (key_sz + 16)); - if (!scratch) return NULL; - scratch_sz = key_sz + 16; +find_or_create_sprite_position(SPRITE_POSITION_MAP_HANDLE map_, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created) { + sprite_pos_map *map = (sprite_pos_map*)map_; + const size_t keysz_in_bytes = key_size_for_glyph_count(count) * sizeof(glyph_index); + if (!scratch || keysz_in_bytes > scratch_key_capacity) { + scratch = realloc(scratch, sizeof(scratch[0]) + keysz_in_bytes + 64); + if (!scratch) { scratch_key_capacity = 0; return NULL; } + scratch_key_capacity = keysz_in_bytes + 64; } - const unsigned key_sz_bytes = key_sz * sizeof(glyph_index); - scratch[0] = count; scratch[1] = ligature_index; scratch[2] = cell_count; - memcpy(scratch + 3, glyphs, count * sizeof(glyph_index)); - HASH_FIND(hh, *head, scratch, key_sz_bytes, p); - if (p) { *created = false; return (SpritePosition*)p; } + scratch->keysz_in_bytes = keysz_in_bytes; + scratch->key[0] = count; scratch->key[1] = ligature_index; scratch->key[2] = cell_count; + memcpy(scratch->key + 3, glyphs, count * sizeof(glyph_index)); + sprite_pos_map_itr n = vt_get(map, scratch); + if (!vt_is_end(n)) { *created = false; return n.data->val; } - p = calloc(1, sizeof(SpritePosItem) + key_sz_bytes); - if (!p) return NULL; - memcpy(p->key, scratch, key_sz_bytes); - HASH_ADD(hh, *head, key, key_sz_bytes, p); + SpritePosition *val = calloc(1, sizeof(SpritePosition)); + SpritePosKey *key = malloc(sizeof(SpritePosKey) + scratch->keysz_in_bytes); + if (!val || ! key) return NULL; + memcpy(key, scratch, sizeof(scratch[0]) + scratch->keysz_in_bytes); + if (vt_is_end(vt_insert(map, key, val))) return NULL; *created = true; - return (SpritePosition*)p; + return val; } void -free_sprite_position_hash_table(SpritePosition **head_) { - SpritePosItem **head = (SpritePosItem**)head_, *s, *tmp; - HASH_ITER(hh, *head, s, tmp) { - HASH_DEL(*head, s); - free(s); +free_sprite_position_hash_table(SPRITE_POSITION_MAP_HANDLE *map) { + sprite_pos_map **mapref = (sprite_pos_map**)map; + if (*mapref) { + vt_cleanup(*mapref); *mapref = NULL; } } +#include "kitty-uthash.h" + typedef struct GlyphPropertiesItem { GlyphPropertiesHead UT_hash_handle hh; diff --git a/kitty/glyph-cache.h b/kitty/glyph-cache.h index 1fda2a00c..5ed910806 100644 --- a/kitty/glyph-cache.h +++ b/kitty/glyph-cache.h @@ -10,18 +10,19 @@ void free_glyph_cache_global_resources(void); -#define SpritePositionHead \ - bool rendered, colored; \ - sprite_index x, y, z; \ - typedef struct SpritePosition { - SpritePositionHead + bool rendered, colored; + sprite_index x, y, z; } SpritePosition; +typedef struct {int x;} *SPRITE_POSITION_MAP_HANDLE; -void free_sprite_position_hash_table(SpritePosition **head); +SPRITE_POSITION_MAP_HANDLE +create_sprite_position_hash_table(void); +void +free_sprite_position_hash_table(SPRITE_POSITION_MAP_HANDLE *handle); SpritePosition* -find_or_create_sprite_position(SpritePosition **head, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created); +find_or_create_sprite_position(SPRITE_POSITION_MAP_HANDLE map, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created); #define GlyphPropertiesHead \ uint8_t data; diff --git a/kitty/kitty-verstable.h b/kitty/kitty-verstable.h index df0d2fb3e..bb54b7538 100644 --- a/kitty/kitty-verstable.h +++ b/kitty/kitty-verstable.h @@ -18,10 +18,4 @@ vt_hash_bytes(const void *data, const size_t size) { return hash; } -#define vt_hash_struct(s) vt_hash_bytes(&s, sizeof(s)) -#define vt_cmpr_struct(s) memcmp(&s, &s, sizeof(s)) - -#define vt_hash_ptr(s) vt_hash_bytes(s, sizeof(s[0])) -#define vt_cmpr_ptr(s) memcmp(s, s, sizeof(s[0])) - #endif