diff options
Diffstat (limited to 'src/font.cpp')
| -rw-r--r-- | src/font.cpp | 151 |
1 files changed, 65 insertions, 86 deletions
diff --git a/src/font.cpp b/src/font.cpp index 9ca42c5..496c052 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -29,7 +29,6 @@ const char *PKE_PROJECT_FONT_SPACING_UNDERLINE_Y = "spacing_underline_y: "; const char *PKE_PROJECT_FONT_SPACING_UNDERLINE_THICKNESS = "spacing_underline_thickness: "; TypeSafeInt_B(FontTypeIndex); -TypeSafeInt_B(FontRenderIndex); TypeSafeInt_B(FONT_GLYPH_CHAR_FLAG); TypeSafeInt_B(FONT_RENDER_SURFACE_AREA_TYPE_FLAG); @@ -37,6 +36,7 @@ struct FontTypeData { FontType *arr_ft = nullptr; uint64_t unused_fts = 0xFFFFFFFFFFFFFFFF; FontTypeIndex n_ft{0}; + pk_membucket *bkt; } ftd; struct FontInstanceBufferItem { @@ -322,12 +322,13 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta void FontType_Init() { FontTypeIndex fti; + ftd.bkt = pk_mem_bucket_create(__FILE__, PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); ftd.n_ft = FontTypeIndex{8}; - ftd.arr_ft = pk_new_arr<FontType>(8); + ftd.arr_ft = pk_new_arr<FontType>(8, ftd.bkt); for (FontTypeIndex_T i = 0; i < 8; ++i) { FontType *ft = &ftd.arr_ft[i]; ft->glyphs = nullptr; - ft->renders = nullptr; + new (&ft->renders) pk_bkt_arr_t<FontRender>{pk_bkt_arr_handle_MAX, ftd.bkt, ftd.bkt}; } union pke_asset_details ak_img_details { .texture = { @@ -359,7 +360,9 @@ void FontType_Teardown() { if ((ftd.unused_fts & (1llu << i)) != 0) continue; FontType_Unload(FontTypeIndex{(FontTypeIndex_T)i}); } - if (ftd.arr_ft != nullptr) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)ftd.n_ft); + if (ftd.arr_ft != nullptr) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)ftd.n_ft, ftd.bkt); + pk_mem_bucket_destroy(ftd.bkt); + ftd.bkt = nullptr; } // TODO - Memory Pressure @@ -369,10 +372,8 @@ void FontType_Teardown() { void FontType_Tick(double delta) { (void)delta; VkResult vkResult; - FontInstanceBufferItem *fibis = nullptr; size_t index; FontType *ft; - FontRender *fr; for (FontTypeIndex_T i = 0; i < (FontTypeIndex_T)ftd.n_ft; ++i) { if ((ftd.unused_fts & (1llu << i)) != 0) continue; @@ -380,24 +381,17 @@ void FontType_Tick(double delta) { index = 0; ft = &ftd.arr_ft[i]; - for (FontRenderIndex_T k = 0; k < (FontRenderIndex_T)ft->n_render; ++k) { - if ((ft->unused_frs & (1llu << k)) != 0) continue; - fr = &ft->renders[k]; + pk_bkt_arr_t<FontRender>::FN_Iter iter_fn; + iter_fn.func = [&ft, &index](FontRender *fr) { if (fr->isMarkedForRemoval == true) { - if (fr->text.reserved > 0) { - // 2025-04-16 - JCB - // not passing a specific bucket because pk_cstr doesn't store it. - // FontType_AddStringRender requires a `pk_cstr &&`, so we are the proper owner. - // It's up to us to free it. - pk_delete_arr<char>(fr->text.val, fr->text.reserved); - } - ft->unused_frs |= (1llu << k); - new (fr) FontRender{}; + if (fr->text.reserved > 0) { pk_delete_arr<char>(fr->text.val, fr->text.reserved); } + pk_bkt_arr_free_handle(&ft->renders, fr->fr_handle); ft->gr.should_update_instance_buffer = true; - continue; + return; } index += fr->n_glyphs; - } + }; + pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); if (ft->isMarkedForRemoval == true) { FontType_Unload(FontTypeIndex{i}); @@ -408,22 +402,27 @@ void FontType_Tick(double delta) { continue; } + ft->bindings.instance_counter = index; if (index == 0) { - ft->bindings.instance_counter = index; continue; } ft->gr.should_update_instance_buffer = false; - fibis = pk_new_arr<FontInstanceBufferItem>(index); - ft->bindings.instance_counter = index; + pk_arr_t<FontInstanceBufferItem> fibis{}; + pk_arr_resize(&fibis, index); index = 0; - for (FontRenderIndex_T k = 0; k < (FontRenderIndex_T)ft->n_render; ++k) { - if ((ft->unused_frs & (1llu << k)) != 0) continue; - fr = &ft->renders[k]; + + iter_fn.func = [&ft, &index, &fibis](FontRender *fr) { + if (fr->isMarkedForRemoval == true) { + return; + } + pk_arr_resize(&fibis, index + fr->n_glyphs); if (FontType_Inner_CalcTransforms(ft, fr, &fibis[index])) { index += fr->n_glyphs; } - } + }; + pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); + ft->bindings.instance_counter = index; // check recreate buffer if (ft->bindings.instance_buffer_max_count < index) { @@ -436,7 +435,7 @@ void FontType_Tick(double delta) { } pkvk_buffer_create_data create_data{}; - create_data.buffer_byte_length[0] = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; + create_data.buffer_byte_length[0] = fibis.stride * fibis.next; create_data.n_buffers = 1; create_data.index_instance = 0; create_data.index_index = -1; @@ -450,7 +449,7 @@ void FontType_Tick(double delta) { } PKVK_TmpBufferDetails tmpBufferDetails{}; - PKVK_BeginBuffer(graphicsFamilyIndex, sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter, tmpBufferDetails); + PKVK_BeginBuffer(graphicsFamilyIndex, fibis.stride * fibis.next, tmpBufferDetails); assert(tmpBufferDetails.buffer != VK_NULL_HANDLE); { VkCommandBufferBeginInfo vkCommandBufferBeginInfo; @@ -462,12 +461,12 @@ void FontType_Tick(double delta) { vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); assert(vkResult == VK_SUCCESS); - memcpy(tmpBufferDetails.deviceData, fibis, sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter); + memcpy(tmpBufferDetails.deviceData, fibis.data, fibis.stride * fibis.next); VkBufferCopy vk_buffer_copy{}; vk_buffer_copy.srcOffset = 0; vk_buffer_copy.dstOffset = 0; - vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; + vk_buffer_copy.size = fibis.stride * fibis.next; vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy); vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); @@ -489,7 +488,7 @@ void FontType_Tick(double delta) { assert(vkResult == VK_SUCCESS); } PKVK_EndBuffer(tmpBufferDetails); - pk_delete_arr<FontInstanceBufferItem>(fibis, ft->bindings.instance_counter); + pk_arr_reset(&fibis); } } @@ -653,7 +652,6 @@ FontType* FontType_GetFonts(uint64_t &idx_unused) { FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing) { VkResult vkResult; - constexpr VkDeviceSize startingGlyphCount = 4; const Asset *fontTexture = nullptr; const Asset *glyphs = nullptr; FontTypeIndex idx{0}; @@ -680,11 +678,11 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle throw "[font.cpp] out of font type slots"; } ftd.n_ft = FontTypeIndex{8}; - FontType *arr = pk_new_arr<FontType>((FontTypeIndex_T)ftd.n_ft); + FontType *arr = pk_new_arr<FontType>((FontTypeIndex_T)ftd.n_ft, ftd.bkt); if (idx > FontTypeIndex{0}) { memcpy(arr, ftd.arr_ft, sizeof(FontType) * (FontTypeIndex_T)idx); } - if (ftd.arr_ft != nullptr && ftd.arr_ft != CAFE_BABE(FontType)) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)idx); + if (ftd.arr_ft != nullptr && ftd.arr_ft != CAFE_BABE(FontType)) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)idx, ftd.bkt); ftd.arr_ft = arr; } @@ -695,9 +693,7 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle ft->title = title; ft->fontTextureAssetHandle = fontTextureHandle; ft->glyphDetailsAssetHandle = glyphsHandle; - ft->renders = pk_new_arr<FontRender>(startingGlyphCount); - ft->n_render = FontRenderIndex{startingGlyphCount}; - ft->unused_frs = 0xFFFFFFFFFFFFFFFF; + new (&ft->renders) pk_bkt_arr_t<FontRender>{pk_bkt_arr_handle_MAX, ftd.bkt, ftd.bkt}; ft->msdf_settings = *msdf_settings; ft->spacing = *spacing; @@ -832,15 +828,15 @@ void FontType_Unload(FontTypeIndex idx) { FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)idx]; - // TODO specific bucket - if (ft->renders != nullptr) { - for (FontRenderIndex_T i = 0; i < (FontRenderIndex_T)ft->n_render; ++i) { - if ((ft->unused_frs & (1llu << i)) != 0) continue; - if (ft->renders[i].glyph_indices != nullptr) { - pk_delete_arr<uint32_t>(ft->renders[i].glyph_indices, ft->renders[i].n_glyphs); + if (ft->renders.head_r.b > 0 || ft->renders.head_r.i > 0) { + pk_bkt_arr_t<FontRender>::FN_Iter iter_fn{}; + iter_fn.func = [](FontRender *fr) { + if (fr->glyph_indices != nullptr) { + pk_delete_arr<uint32_t>(fr->glyph_indices, fr->n_glyphs, ftd.bkt); } - } - pk_delete_arr<FontRender>(ft->renders, (FontTypeIndex_T)ft->n_render); + }; + pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); + pk_bkt_arr_teardown(&ft->renders); } if (ft->gr.vkDescriptorSet != VK_NULL_HANDLE && ft->gr.vkDescriptorPool != VK_NULL_HANDLE) { @@ -962,44 +958,27 @@ void FontType_cstr_to_unicode(const FontType &ft, pk_arr_t<uint32_t> &arr, const // However, the new buffer is exactly the length it needs to be and no greater. // Consider using a heuristic to allocate a buffer larger than needed. // At the time of writing, the only way to do this is to un-register text. -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { +FontTypeRender FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { assert(settings != nullptr); FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)idx_ft]; FontRender *fr; - FontRenderIndex_T fri; + FontTypeRender ret{}; uint32_t i, count; - FontRenderIndex idx_fr = FontRenderIndex{0}; - for (fri = 0; fri < (FontRenderIndex_T)ft->n_render; ++fri) { - if ((ft->unused_frs & (1llu << fri)) != 0) { - ft->unused_frs &= ~(1llu << fri); - idx_fr = FontRenderIndex{fri}; - break; - } - } + ret.index_ft = idx_ft; + ret.handle_fr = (FontRenderHandle)pk_bkt_arr_new_handle(&ft->renders); + fr = &ft->renders[ret.handle_fr]; - if (idx_fr >= ft->n_render) { - if (idx_fr >= FontRenderIndex{PKE_FONT_MAX_FONT_RENDERS}) { - throw "[font.cpp] out of FontRender slots"; - } - FontRenderIndex_T old_count{static_cast<FontRenderIndex_T>(ft->n_render)}; - ft->n_render += FontRenderIndex{8}; - FontRender *arr = pk_new_arr<FontRender>((FontRenderIndex_T)ft->n_render); - memcpy(arr, ft->renders, sizeof(FontRender) * old_count); - pk_delete_arr<FontRender>(ft->renders, old_count); - ft->renders = arr; - } - fr = &ft->renders[(FontRenderIndex_T)idx_fr]; new (fr) FontRender{}; fr->uuid = uuid; ECS_CreateEntity(fr, parent); - fr->fr_handle.index_ft = idx_ft; - fr->fr_handle.index_fr = idx_fr; + fr->index_ft = idx_ft; + fr->fr_handle = ret.handle_fr; fr->settings = *settings; fr->text = str; if (window == NULL) { - return fr->fr_handle; + return ret; } // insert new characters into tmp buffer @@ -1013,7 +992,7 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && // TODO specific bucket count = glyph_indices.next; fr->n_glyphs = count; - fr->glyph_indices = pk_new_arr<uint32_t>(count); + fr->glyph_indices = pk_new_arr<uint32_t>(count, ftd.bkt); for (i = 0; i < count; ++i) { fr->glyph_indices[i] = glyph_indices[i]; } @@ -1021,35 +1000,35 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && ft->gr.should_update_instance_buffer = true; - return fr->fr_handle; + return ret; } -FontRender *FontType_GetFontRender(FontRenderHandle frh) { +FontRender *FontType_GetFontRender(FontTypeRender frh) { if ((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) != 0) { return nullptr; } FontType *ft = &ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; - if ((ft->unused_frs & (1llu << (FontRenderIndex_T)frh.index_fr)) != 0) { + if (pk_bkt_arr_handle_validate(&ft->renders, frh.handle_fr) != PK_BKT_ARR_HANDLE_VALIDATION_VALID) { return nullptr; } - return &ft->renders[static_cast<FontRenderIndex_T>(frh.index_fr)]; + return &ft->renders[frh.handle_fr]; } -void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings) { +void FontType_UpdateStringRender(FontTypeRender frh, FontRenderSettings *settings) { assert(settings != nullptr); assert((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) == 0); FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)frh.index_ft]; - assert((ft->unused_frs & (1llu << (FontTypeIndex_T)frh.index_fr)) == 0); + assert(pk_bkt_arr_handle_validate(&ft->renders, frh.handle_fr) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); ft->gr.should_update_instance_buffer = true; - ft->renders[(FontRenderIndex_T)frh.index_fr].settings = *settings; + ft->renders[frh.handle_fr].settings = *settings; } -void FontType_UpdateStringRenderText(FontRenderHandle frh, pk_cstr &&cstr) { +void FontType_UpdateStringRenderText(FontTypeRender frh, pk_cstr &&cstr) { uint32_t i, count; assert((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) == 0); FontType &ft = ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; - assert((ft.unused_frs & (1llu << (FontTypeIndex_T)frh.index_fr)) == 0); - FontRender &fr = ft.renders[static_cast<FontRenderIndex_T>(frh.index_fr)]; + assert(pk_bkt_arr_handle_validate(&ft.renders, frh.handle_fr) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + FontRender &fr = ft.renders[frh.handle_fr]; pk_cstr old_str = fr.text; if (window == NULL) { return; @@ -1063,23 +1042,23 @@ void FontType_UpdateStringRenderText(FontRenderHandle frh, pk_cstr &&cstr) { // TODO specific bucket count = glyph_indices.next; fr.n_glyphs = count; - fr.glyph_indices = pk_new_arr<uint32_t>(count); + fr.glyph_indices = pk_new_arr<uint32_t>(count, ftd.bkt); for (i = 0; i < count; ++i) { fr.glyph_indices[i] = glyph_indices[i]; } glyph_indices.data = nullptr; - if (fr.text.reserved > 0 && fr.text.val != NULL) pk_delete_arr<char>(fr.text.val, fr.text.reserved); + if (fr.text.reserved > 0 && fr.text.val != NULL) pk_delete_arr<char>(fr.text.val, fr.text.reserved, ftd.bkt); fr.text = cstr; ft.gr.should_update_instance_buffer = true; } -void FontType_RemoveStringRender(FontRenderHandle handle) { +void FontType_RemoveStringRender(FontTypeRender handle) { FontRender *fr; FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)handle.index_ft]; // hack, but works ft->gr.should_update_instance_buffer = true; - fr = &ft->renders[(FontRenderIndex_T)handle.index_fr]; + fr = &ft->renders[handle.handle_fr]; ECS_MarkForRemoval(fr); } |
