cache font raster flag settings, add additional acceleration to very common repeated cfg lookups - e.g. same window/view -> state structure N times, or same ID -> cfg N times

This commit is contained in:
Ryan Fleury
2025-04-23 16:21:10 -07:00
parent ba29350939
commit 23125dd312
2 changed files with 109 additions and 54 deletions
+82 -37
View File
@@ -366,6 +366,14 @@ internal RD_Cfg *
rd_cfg_from_id(RD_CfgID id) rd_cfg_from_id(RD_CfgID id)
{ {
RD_Cfg *result = &rd_nil_cfg; RD_Cfg *result = &rd_nil_cfg;
if(id != 0 &&
id == rd_state->cfg_last_accessed_id &&
id == rd_state->cfg_last_accessed->id)
{
result = rd_state->cfg_last_accessed;
}
else
{
U64 hash = d_hash_from_string(str8_struct(&id)); U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->cfg_id_slots_count; U64 slot_idx = hash%rd_state->cfg_id_slots_count;
for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next)
@@ -376,6 +384,9 @@ rd_cfg_from_id(RD_CfgID id)
break; break;
} }
} }
}
rd_state->cfg_last_accessed_id = id;
rd_state->cfg_last_accessed = result;
return result; return result;
} }
@@ -1171,6 +1182,29 @@ rd_schemas_from_name(String8 name)
return schemas; return schemas;
} }
internal String8
rd_default_setting_from_names(String8 schema_name, String8 setting_name)
{
String8 result = {0};
{
MD_Node *setting_schema = &md_nil_node;
MD_NodePtrList schemas = rd_schemas_from_name(schema_name);
for(MD_NodePtrNode *n = schemas.first; n != 0 && setting_schema == &md_nil_node; n = n->next)
{
setting_schema = md_child_from_string(n->v, setting_name, 0);
}
if(setting_schema != &md_nil_node)
{
MD_Node *default_tag = md_tag_from_string(setting_schema, str8_lit("default"), 0);
if(default_tag != &md_nil_node)
{
result = default_tag->first->string;
}
}
}
return result;
}
internal String8 internal String8
rd_setting_from_name(String8 name) rd_setting_from_name(String8 name)
{ {
@@ -1193,34 +1227,13 @@ rd_setting_from_name(String8 name)
result = setting->first->string; result = setting->first->string;
// rjf: no result -> look for default in schemas // rjf: no result -> look for default in schemas
if(result.size == 0) ProfScope("default setting schema lookup") if(result.size == 0)
{ {
MD_Node *schema = &md_nil_node; result = rd_default_setting_from_names(view_cfg->string, name);
for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && result.size == 0; cfg = cfg->parent)
{ {
MD_NodePtrList schemas = rd_schemas_from_name(view_cfg->string); result = rd_default_setting_from_names(cfg->string, name);
for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next)
{
schema = md_child_from_string(n->v, name, 0);
} }
for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && schema == &md_nil_node; cfg = cfg->parent)
{
MD_NodePtrList schemas = rd_schemas_from_name(cfg->string);
for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next)
{
schema = md_child_from_string(n->v, name, 0);
}
}
if(schema != &md_nil_node)
{
MD_Node *default_tag = md_tag_from_string(schema, str8_lit("default"), 0);
if(default_tag != &md_nil_node)
{
result = default_tag->first->string;
goto end_default_search;
}
}
}
end_default_search:;
} }
} }
return result; return result;
@@ -2258,11 +2271,19 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval)
internal RD_ViewState * internal RD_ViewState *
rd_view_state_from_cfg(RD_Cfg *cfg) rd_view_state_from_cfg(RD_Cfg *cfg)
{ {
RD_ViewState *view_state = &rd_nil_view_state;
RD_CfgID id = cfg->id; RD_CfgID id = cfg->id;
if(id != 0 &&
id == rd_state->view_state_last_accessed_id &&
id == rd_state->view_state_last_accessed->cfg_id)
{
view_state = rd_state->view_state_last_accessed;
}
else
{
U64 hash = d_hash_from_string(str8_struct(&id)); U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->view_state_slots_count; U64 slot_idx = hash%rd_state->view_state_slots_count;
RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx];
RD_ViewState *view_state = &rd_nil_view_state;
for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next)
{ {
if(v->cfg_id == id) if(v->cfg_id == id)
@@ -2271,6 +2292,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg)
break; break;
} }
} }
}
if(view_state == &rd_nil_view_state) if(view_state == &rd_nil_view_state)
{ {
view_state = rd_state->free_view_state; view_state = rd_state->free_view_state;
@@ -2283,6 +2305,9 @@ rd_view_state_from_cfg(RD_Cfg *cfg)
view_state = push_array(rd_state->arena, RD_ViewState, 1); view_state = push_array(rd_state->arena, RD_ViewState, 1);
} }
MemoryCopyStruct(view_state, &rd_nil_view_state); MemoryCopyStruct(view_state, &rd_nil_view_state);
U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->view_state_slots_count;
RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx];
DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev);
view_state->cfg_id = id; view_state->cfg_id = id;
view_state->arena = arena_alloc(); view_state->arena = arena_alloc();
@@ -2293,6 +2318,8 @@ rd_view_state_from_cfg(RD_Cfg *cfg)
{ {
view_state->last_frame_index_touched = rd_state->frame_index; view_state->last_frame_index_touched = rd_state->frame_index;
} }
rd_state->view_state_last_accessed = view_state;
rd_state->view_state_last_accessed_id = id;
return view_state; return view_state;
} }
@@ -5201,12 +5228,20 @@ rd_window_state_from_cfg(RD_Cfg *cfg)
//- rjf: unpack //- rjf: unpack
RD_Cfg *window_cfg = rd_window_from_cfg(cfg); RD_Cfg *window_cfg = rd_window_from_cfg(cfg);
RD_CfgID id = window_cfg->id; RD_CfgID id = window_cfg->id;
U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->window_state_slots_count;
RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx];
//- rjf: scan for existing window //- rjf: scan for existing window
RD_WindowState *ws = &rd_nil_window_state; RD_WindowState *ws = &rd_nil_window_state;
if(id != 0 &&
id == rd_state->window_state_last_accessed_id &&
id == rd_state->window_state_last_accessed->cfg_id)
{
ws = rd_state->window_state_last_accessed;
}
else
{
U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->window_state_slots_count;
RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx];
for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next)
{ {
if(w->cfg_id == id) if(w->cfg_id == id)
@@ -5215,6 +5250,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg)
break; break;
} }
} }
}
//- rjf: allocate/open new window if one was not found //- rjf: allocate/open new window if one was not found
if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state) if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state)
@@ -5288,6 +5324,9 @@ rd_window_state_from_cfg(RD_Cfg *cfg)
} }
// rjf: hook up window links // rjf: hook up window links
U64 hash = d_hash_from_string(str8_struct(&id));
U64 slot_idx = hash%rd_state->window_state_slots_count;
RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx];
DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev);
DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev);
@@ -5301,6 +5340,8 @@ rd_window_state_from_cfg(RD_Cfg *cfg)
ws->last_frame_index_touched = rd_state->frame_index; ws->last_frame_index_touched = rd_state->frame_index;
} }
rd_state->window_state_last_accessed_id = ws->cfg_id;
rd_state->window_state_last_accessed = ws;
return ws; return ws;
} }
@@ -5473,6 +5514,15 @@ rd_window_frame(void)
} }
} }
//////////////////////////////
//- rjf: @window_frame_part compute window's font raster flags
//
{
ws->font_slot_raster_flags[RD_FontSlot_Icons] = FNT_RasterFlag_Smooth;
ws->font_slot_raster_flags[RD_FontSlot_Main] = (rd_setting_b32_from_name(str8_lit("smooth_ui_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_ui_text"))*FNT_RasterFlag_Hinted);
ws->font_slot_raster_flags[RD_FontSlot_Code] = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);
}
////////////////////////////// //////////////////////////////
//- rjf: @window_frame_part pre-emptively rasterize common glyphs on the first frame //- rjf: @window_frame_part pre-emptively rasterize common glyphs on the first frame
// //
@@ -10283,14 +10333,9 @@ rd_font_from_slot(RD_FontSlot slot)
internal FNT_RasterFlags internal FNT_RasterFlags
rd_raster_flags_from_slot(RD_FontSlot slot) rd_raster_flags_from_slot(RD_FontSlot slot)
{ {
FNT_RasterFlags flags = FNT_RasterFlag_Smooth|FNT_RasterFlag_Hinted; RD_Cfg *window = rd_cfg_from_id(rd_regs()->window);
switch(slot) RD_WindowState *ws = rd_window_state_from_cfg(window);
{ FNT_RasterFlags flags = ws->font_slot_raster_flags[slot];
default:{}break;
case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break;
case RD_FontSlot_Main: {flags = (rd_setting_b32_from_name(str8_lit("smooth_ui_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_ui_text"))*FNT_RasterFlag_Hinted);}break;
case RD_FontSlot_Code: {flags = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break;
}
return flags; return flags;
} }
+10
View File
@@ -501,6 +501,9 @@ struct RD_WindowState
// rjf: theme (recomputed each frame) // rjf: theme (recomputed each frame)
UI_Theme *theme; UI_Theme *theme;
// rjf: font raster flags (recomputed each frame)
FNT_RasterFlags font_slot_raster_flags[RD_FontSlot_COUNT];
// rjf: dev interface state // rjf: dev interface state
B32 dev_menu_is_open; B32 dev_menu_is_open;
@@ -700,6 +703,8 @@ struct RD_State
RD_CfgSlot *cfg_id_slots; RD_CfgSlot *cfg_id_slots;
RD_CfgNode *free_cfg_id_node; RD_CfgNode *free_cfg_id_node;
U64 cfg_id_gen; U64 cfg_id_gen;
RD_CfgID cfg_last_accessed_id;
RD_Cfg *cfg_last_accessed;
// rjf: window state cache // rjf: window state cache
U64 window_state_slots_count; U64 window_state_slots_count;
@@ -708,11 +713,15 @@ struct RD_State
RD_CfgID last_focused_window; RD_CfgID last_focused_window;
RD_WindowState *first_window_state; RD_WindowState *first_window_state;
RD_WindowState *last_window_state; RD_WindowState *last_window_state;
RD_CfgID window_state_last_accessed_id;
RD_WindowState *window_state_last_accessed;
// rjf: view state cache // rjf: view state cache
U64 view_state_slots_count; U64 view_state_slots_count;
RD_ViewStateSlot *view_state_slots; RD_ViewStateSlot *view_state_slots;
RD_ViewState *free_view_state; RD_ViewState *free_view_state;
RD_CfgID view_state_last_accessed_id;
RD_ViewState *view_state_last_accessed;
// rjf: bind change // rjf: bind change
Arena *bind_change_arena; Arena *bind_change_arena;
@@ -870,6 +879,7 @@ internal String8 rd_path_from_cfg(RD_Cfg *cfg);
internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg);
internal MD_NodePtrList rd_schemas_from_name(String8 name); internal MD_NodePtrList rd_schemas_from_name(String8 name);
internal String8 rd_default_setting_from_names(String8 schema_name, String8 setting_name);
internal String8 rd_setting_from_name(String8 name); internal String8 rd_setting_from_name(String8 name);
internal B32 rd_setting_b32_from_name(String8 name); internal B32 rd_setting_b32_from_name(String8 name);