summaryrefslogtreecommitdiff
path: root/src/font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/font.cpp')
-rw-r--r--src/font.cpp151
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);
}