From 08a8b4b823427d97a9ebf60f4ba9f58c9853e7ab Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 9 Jan 2025 14:54:59 -0500 Subject: [PATCH] Insane perfomrance after tuning the batch and caches. --- code/font/vefontcache/shaper.odin | 2 +- code/font/vefontcache/vefontcache.odin | 30 +++++++++++++------------- code/grime/string_cache.odin | 2 +- code/host/host.odin | 2 +- code/sectr/ui/core/box.odin | 2 +- code/sectr/ui/core/signal.odin | 2 +- code/sectr/ui/tests.odin | 14 ++++++------ 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/code/font/vefontcache/shaper.odin b/code/font/vefontcache/shaper.odin index cd5b46f..06e91bc 100644 --- a/code/font/vefontcache/shaper.odin +++ b/code/font/vefontcache/shaper.odin @@ -6,7 +6,7 @@ Note(Ed): The only reason I didn't directly use harfbuzz is because hamza exists import "core:c" import "thirdparty:harfbuzz" -Shape_Key :: u64 +Shape_Key :: u32 /* A text whose codepoints have had their relevant glyphs and associated data resolved for processing in a draw list generation stage. diff --git a/code/font/vefontcache/vefontcache.odin b/code/font/vefontcache/vefontcache.odin index 5ed3e74..688ad85 100644 --- a/code/font/vefontcache/vefontcache.odin +++ b/code/font/vefontcache/vefontcache.odin @@ -135,12 +135,12 @@ Init_Glyph_Draw_Params :: struct { } Init_Glyph_Draw_Params_Default :: Init_Glyph_Draw_Params { - snap_glyph_height = true, + snap_glyph_height = false, over_sample = 4, draw_padding = Init_Atlas_Params_Default.glyph_padding, - shape_gen_scratch_reserve = 4 * 1024, - buffer_glyph_limit = 16, - batch_glyph_limit = 2 * 1024, + shape_gen_scratch_reserve = 512, + buffer_glyph_limit = 4, + batch_glyph_limit = 32, } Init_Shaper_Params :: struct { @@ -152,7 +152,7 @@ Init_Shaper_Params :: struct { } Init_Shaper_Params_Default :: Init_Shaper_Params { - snap_glyph_position = true, + snap_glyph_position = false, adv_snap_small_font_threshold = 0, } @@ -166,20 +166,20 @@ Init_Shape_Cache_Params :: struct { Init_Shape_Cache_Params_Default :: Init_Shape_Cache_Params { capacity = 10 * 1024, - reserve = 512, + reserve = 128, } //#region("lifetime") // ve_fontcache_init -startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, +startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, // Note(Ed): Only sbt_truetype supported for now. allocator := context.allocator, atlas_params := Init_Atlas_Params_Default, glyph_draw_params := Init_Glyph_Draw_Params_Default, shape_cache_params := Init_Shape_Cache_Params_Default, shaper_params := Init_Shaper_Params_Default, - alpha_sharpen : f32 = 0.15, - px_scalar : f32 = 2.0, + alpha_sharpen : f32 = 0.1, + px_scalar : f32 = 1.89, // Curve quality to use for a font when unspecified, // Affects step size for bezier curve passes in generate_glyph_pass_draw_list @@ -324,19 +324,19 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, glyph_buffer.clear_draw_list.calls, error = make( [dynamic]Draw_Call, len = 0, cap = Kilobyte ) assert( error == .None, "VEFontCache.init : Failed to allocate calls for calls for clear_draw_list" ) - glyph_buffer.shape_gen_scratch, error = make( [dynamic]Vertex, len = 0, cap = 4 * Kilobyte ) + glyph_buffer.shape_gen_scratch, error = make( [dynamic]Vertex, len = 0, cap = glyph_draw_params.shape_gen_scratch_reserve ) assert(error == .None, "VEFontCache.init : Failed to allocate shape_gen_scratch") batch_cache := & glyph_buffer.batch_cache batch_cache.cap = i32(glyph_draw_params.batch_glyph_limit) batch_cache.num = 0 - batch_cache.table, error = make( map[Atlas_Key]b8, uint(glyph_draw_params.shape_gen_scratch_reserve) ) + batch_cache.table, error = make( map[Atlas_Key]b8, uint(glyph_draw_params.batch_glyph_limit) ) assert(error == .None, "VEFontCache.init : Failed to allocate batch_cache") - glyph_buffer.glyph_pack,error = make_soa( #soa[dynamic]Glyph_Pack_Entry, length = 0, capacity = 1 * Kilobyte ) - glyph_buffer.oversized, error = make( [dynamic]i32, len = 0, cap = 1 * Kilobyte ) - glyph_buffer.to_cache, error = make( [dynamic]i32, len = 0, cap = 1 * Kilobyte ) - glyph_buffer.cached, error = make( [dynamic]i32, len = 0, cap = 1 * Kilobyte ) + glyph_buffer.glyph_pack,error = make_soa( #soa[dynamic]Glyph_Pack_Entry, length = 0, capacity = uint(shape_cache_params.reserve) ) + glyph_buffer.oversized, error = make( [dynamic]i32, len = 0, cap = uint(shape_cache_params.reserve) ) + glyph_buffer.to_cache, error = make( [dynamic]i32, len = 0, cap = uint(shape_cache_params.reserve) ) + glyph_buffer.cached, error = make( [dynamic]i32, len = 0, cap = uint(shape_cache_params.reserve) ) } parser_init( & ctx.parser_ctx, parser_kind ) diff --git a/code/grime/string_cache.odin b/code/grime/string_cache.odin index 74d5738..18d6e87 100644 --- a/code/grime/string_cache.odin +++ b/code/grime/string_cache.odin @@ -85,7 +85,7 @@ str_intern_lookup :: #force_inline proc( key : StringKey ) -> (^StrCache str_intern :: #force_inline proc( content : string ) -> StrCached { - profile(#procedure) + // profile(#procedure) cache := Module_String_Cache key := str_intern_key(content) result := hmap_chained_get( cache.table, transmute(u64) key ) diff --git a/code/host/host.odin b/code/host/host.odin index 598e8e5..3a10efe 100644 --- a/code/host/host.odin +++ b/code/host/host.odin @@ -292,7 +292,7 @@ main :: proc() // Setup profiling profiler : SpallProfiler { - buffer_backing := make([]u8, spall.BUFFER_DEFAULT_SIZE * 20) + buffer_backing := make([]u8, spall.BUFFER_DEFAULT_SIZE * 4) profiler.ctx = spall.context_create("sectr.spall") profiler.buffer = spall.buffer_create(buffer_backing) } diff --git a/code/sectr/ui/core/box.odin b/code/sectr/ui/core/box.odin index 39d6c22..8ee5aae 100644 --- a/code/sectr/ui/core/box.odin +++ b/code/sectr/ui/core/box.odin @@ -67,7 +67,7 @@ ui_box_from_key :: #force_inline proc ( cache : ^HMapChained(UI_Box), key : UI_K ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) { - profile(#procedure) + // profile(#procedure) using ui := get_state().ui_context key := ui_key_from_string( label ) diff --git a/code/sectr/ui/core/signal.odin b/code/sectr/ui/core/signal.odin index 0420e16..ba2af5e 100644 --- a/code/sectr/ui/core/signal.odin +++ b/code/sectr/ui/core/signal.odin @@ -30,7 +30,7 @@ UI_Signal :: struct { ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas := true ) -> UI_Signal { - profile(#procedure) + // profile(#procedure) ui := get_state().ui_context input := get_state().input diff --git a/code/sectr/ui/tests.odin b/code/sectr/ui/tests.odin index 8ea017b..09f5bfd 100644 --- a/code/sectr/ui/tests.odin +++ b/code/sectr/ui/tests.odin @@ -209,10 +209,10 @@ test_whitespace_ast :: proc( default_layout : ^UI_Layout, frame_style_default : ui_layout( text_layout ) - profile_begin("label fmt") + // profile_begin("label fmt") str.builder_reset( & builder) label := str_fmt_builder( & builder, "line %d", line_id ) - profile_end() + // profile_end() line_hbox := ui_widget(label, {.Mouse_Clickable}) @@ -278,7 +278,7 @@ test_whitespace_ast :: proc( default_layout : ^UI_Layout, frame_style_default : } else { - profile("line (single-box)") + // profile("line (single-box)") line_hbox.layout.flags |= { .Size_To_Text } @@ -286,23 +286,23 @@ test_whitespace_ast :: proc( default_layout : ^UI_Layout, frame_style_default : head := line.first.next for ; head != nil; { - profile("write ast node") + // profile("write ast node") str.write_string( & builder, head.content ) head = head.next } - profile("intern") + // profile("intern") line_hbox.text = str_intern( to_string( builder ) ) } if len(line_hbox.text) > 0 { - profile("append actual") + // profile("append actual") array_append( widgets_ptr, line_hbox ) text_layout.pos.x = text_layout.pos.x text_layout.pos.y -= size_range2(line_hbox.computed.bounds).y } else { - profile("end") + // profile("end") widget := & widgets.data[ widgets.num - 1 ] if widget.box != nil { text_layout.pos.y -= size_range2( widget.computed.bounds ).y