More offloading to shaper, seeing if its better todo some math in loop...

This commit is contained in:
Edward R. Gonzalez 2025-01-08 08:38:06 -05:00
parent 18d8735c54
commit ce84652417
8 changed files with 150 additions and 107 deletions

View File

@ -54,6 +54,7 @@ Atlas :: struct {
}
// Hahser for the atlas.
@(optimization_mode="favor_size")
atlas_glyph_lru_code :: #force_inline proc "contextless" ( font : Font_ID, px_size : f32, glyph_index : Glyph ) -> (lru_code : Atlas_Key) {
// lru_code = u32(glyph_index) + ( ( 0x10000 * u32(font) ) & 0xFFFF0000 )
font := font
@ -131,7 +132,7 @@ atlas_decide_region_branchless :: #force_inline proc "contextless" (
which_ab := min(score_a, score_b)
which_cd := min(score_c, score_d)
which_region := min(which_ab, which_cd)
resolved := min(which_region, score_buffer) + 6
resolved := min(which_region, score_buffer) + 6
return Atlas_Region_Kind(resolved)
}

View File

@ -21,15 +21,6 @@ Vertex :: struct {
u, v : f32,
}
Transform :: struct {
pos : Vec2,
scale : Vec2,
}
Range2 :: struct {
p0, p1 : Vec2,
}
Glyph_Bounds_Mat :: matrix[2, 2] f32
Glyph_Draw_Quad :: struct {
@ -44,21 +35,21 @@ Glyph_Draw_Quad :: struct {
Glyph_Pack_Entry :: struct #packed {
position : Vec2,
index : Glyph,
lru_code : Atlas_Key,
// index : Glyph,
// lru_code : Atlas_Key,
atlas_index : i32,
in_atlas : b8,
should_cache : b8,
region_kind : Atlas_Region_Kind,
// region_kind : Atlas_Region_Kind,
region_pos : Vec2,
region_size : Vec2,
bounds : Range2,
bounds_scaled : Range2,
bounds_size : Vec2,
bounds_size_scaled : Vec2,
// bounds : Range2,
// bounds_scaled : Range2,
// bounds_size : Vec2,
// bounds_size_scaled : Vec2,
over_sample : Vec2,
scale : Vec2,
// scale : Vec2,
shape : Parser_Glyph_Shape,
draw_transform : Transform,
@ -358,41 +349,12 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
}
sub_slice :: #force_inline proc "contextless" ( pack : ^[dynamic]i32) -> []i32 { return pack[:] }
profile_begin("index")
for & glyph, index in glyph_pack
{
glyph.index = shape.glyph_id[ index ]
glyph.lru_code = atlas_glyph_lru_code(entry.id, px_size, glyph.index)
}
profile_end()
profile_begin("translate")
for & glyph, index in glyph_pack
{
for & glyph, index in glyph_pack {
glyph.position = target_position + (shape.position[index]) * target_scale
}
profile_end()
profile_begin("bounds")
for & glyph, index in glyph_pack
{
glyph.bounds = parser_get_bounds( entry.parser_info, glyph.index )
glyph.bounds_scaled = { glyph.bounds.p0 * font_scale, glyph.bounds.p1 * font_scale }
glyph.bounds_size = glyph.bounds.p1 - glyph.bounds.p0
glyph.bounds_size_scaled = glyph.bounds_size * font_scale
glyph.scale = glyph.bounds_size_scaled + atlas.glyph_padding
}
profile_end()
glyph_padding_dbl := atlas.glyph_padding * 2
profile_begin("region")
for & glyph, index in glyph_pack
{
glyph.region_kind = atlas_decide_region( atlas ^, glyph_buffer_size, glyph.bounds_size_scaled )
}
profile_end()
profile_begin("batching")
clear(oversized)
clear(to_cache)
@ -401,15 +363,20 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
for & glyph, index in glyph_pack
{
if glyph.region_kind == .None {
atlas_key := shape.atlas_lru_code[index]
region_kind := shape.region_kind[index]
bounds := shape.bounds[index]
bounds_size_scaled := size(bounds) * font_scale
if region_kind == .None {
assert(false, "FAILED TO ASSGIN REGION")
continue
}
if glyph.region_kind == .E
if region_kind == .E
{
glyph.over_sample = \
glyph.bounds_size_scaled.x <= glyph_buffer_size.x / 2 &&
glyph.bounds_size_scaled.y <= glyph_buffer_size.y / 2 ? \
bounds_size_scaled.x <= glyph_buffer_size.x / 2 &&
bounds_size_scaled.y <= glyph_buffer_size.y / 2 ? \
{2.0, 2.0} \
: {1.0, 1.0}
append_sub_pack(oversized, cast(i32) index)
@ -417,8 +384,8 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
}
glyph.over_sample = glyph_buffer.over_sample
region := atlas.regions[glyph.region_kind]
glyph.atlas_index = lru_get( & region.state, glyph.lru_code )
region := atlas.regions[region_kind]
glyph.atlas_index = lru_get( & region.state, atlas_key )
// Glyphs are prepared in batches based on the capacity of the batch cache.
Prepare_For_Batch:
@ -441,22 +408,22 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
}
profile("append to_cache")
glyph.atlas_index = atlas_reserve_slot(region, glyph.lru_code)
glyph.atlas_index = atlas_reserve_slot(region, atlas_key)
glyph.region_pos, glyph.region_size = atlas_region_bbox(region ^, glyph.atlas_index)
append_sub_pack(to_cache, cast(i32) index)
mark_glyph_seen(& glyph_buffer.batch_cache, glyph.lru_code)
mark_glyph_seen(& glyph_buffer.batch_cache, atlas_key)
continue
}
profile("append cached")
glyph.region_pos, glyph.region_size = atlas_region_bbox(region ^, glyph.atlas_index)
append_sub_pack(cached, cast(i32) index)
mark_glyph_seen(& glyph_buffer.batch_cache, glyph.lru_code)
mark_glyph_seen(& glyph_buffer.batch_cache, atlas_key)
continue
}
// Batch has been prepared for a set of glyphs time to generate glyphs.
batch_generate_glyphs_draw_list( draw_list, glyph_pack, sub_slice(cached), sub_slice(to_cache), sub_slice(oversized),
batch_generate_glyphs_draw_list( draw_list, shape, glyph_pack, sub_slice(cached), sub_slice(to_cache), sub_slice(oversized),
atlas,
glyph_buffer,
atlas_size,
@ -478,7 +445,7 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
if len(oversized) > 0 || glyph_buffer.batch_cache.num > 0
{
// Last batch pass
batch_generate_glyphs_draw_list( draw_list, glyph_pack, sub_slice(cached), sub_slice(to_cache), sub_slice(oversized),
batch_generate_glyphs_draw_list( draw_list, shape, glyph_pack, sub_slice(cached), sub_slice(to_cache), sub_slice(oversized),
atlas,
glyph_buffer,
atlas_size,
@ -508,7 +475,9 @@ generate_shape_draw_list :: proc( draw_list : ^Draw_List, shape : Shaped_Text,
* Oversized will have a draw call setup to blit directly from the glyph buffer to the target.
* to_cache will blit the glyphs rendered to the buffer to the atlas.
*/
@(optimization_mode = "favor_size")
batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
shape : Shaped_Text,
glyph_pack : ^#soa[dynamic]Glyph_Pack_Entry,
cached : []i32,
to_cache : []i32,
@ -533,22 +502,29 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
for id, index in cached
{
// Quad to for drawing atlas slot to target
glyph := & glyph_pack[id]
glyph := & glyph_pack[id]
bounds := shape.bounds[id]
bounds_scaled := mul(bounds, font_scale)
glyph_scale := size(bounds_scaled) + atlas.glyph_padding
quad := & glyph.draw_quad
quad.dst_pos = glyph.position + (glyph.bounds_scaled.p0) * target_scale
quad.dst_scale = (glyph.scale) * target_scale
quad.src_scale = (glyph.scale)
quad.dst_pos = glyph.position + (bounds_scaled.p0) * target_scale
quad.dst_scale = (glyph_scale) * target_scale
quad.src_scale = (glyph_scale)
quad.src_pos = (glyph.region_pos)
to_target_space( & quad.src_pos, & quad.src_scale, atlas_size )
}
for id, index in to_cache
{
glyph := & glyph_pack[id]
glyph := & glyph_pack[id]
bounds := shape.bounds[id]
bounds_scaled := mul(bounds, font_scale)
glyph_scale := size(bounds_scaled) + glyph_buffer.draw_padding
f32_allocated_x := cast(f32) glyph_buffer.allocated_x
// Resolve how much space this glyph will allocate in the buffer
buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph_buffer.over_sample
buffer_size := glyph_scale * glyph_buffer.over_sample
// Allocate a glyph glyph render target region (FBO)
to_allocate_x := buffer_size.x + 2.0
@ -559,7 +535,7 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
// The glyph buffer space transform for generate_glyph_pass_draw_list
draw_transform := & glyph.draw_transform
draw_transform.scale = font_scale * glyph_buffer.over_sample
draw_transform.pos = -1 * (glyph.bounds.p0) * draw_transform.scale + glyph_buffer.draw_padding
draw_transform.pos = -1 * (bounds.p0) * draw_transform.scale + glyph_buffer.draw_padding
draw_transform.pos.x += glyph.buffer_x
to_glyph_buffer_space( & draw_transform.pos, & draw_transform.scale, glyph_buffer_size )
@ -570,21 +546,25 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
draw_quad := & glyph.draw_quad
// Destination (draw_list's target image)
draw_quad.dst_pos = glyph.position + (glyph.bounds_scaled.p0) * target_scale
draw_quad.dst_scale = (glyph.scale) * target_scale
draw_quad.dst_pos = glyph.position + (bounds_scaled.p0) * target_scale
draw_quad.dst_scale = (glyph_scale) * target_scale
// UV Coordinates for sampling the atlas
draw_quad.src_scale = (glyph.scale)
draw_quad.src_scale = (glyph_scale)
draw_quad.src_pos = (glyph.region_pos)
to_target_space( & draw_quad.src_pos, & draw_quad.src_scale, atlas_size )
}
for id, index in oversized
when ENABLE_OVERSIZED_GLYPHS do for id, index in oversized
{
glyph := & glyph_pack[id]
glyph_padding := vec2(glyph_buffer.draw_padding)
glyph := & glyph_pack[id]
bounds := shape.bounds[id]
bounds_scaled := mul(bounds, font_scale)
bounds_size_scaled := size(bounds_scaled)
f32_allocated_x := cast(f32) glyph_buffer.allocated_x
// Resolve how much space this glyph will allocate in the buffer
buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph.over_sample
buffer_size := (bounds_size_scaled + glyph_padding) * glyph.over_sample
// Allocate a glyph glyph render target region (FBO)
to_allocate_x := buffer_size.x + 2.0
@ -597,40 +577,40 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
// Quad to for drawing atlas slot to target
draw_quad := & glyph.draw_quad
glyph_padding := vec2(glyph_buffer.draw_padding)
// Target position (draw_list's target image)
draw_quad.dst_pos = glyph.position + (glyph.bounds_scaled.p0 - glyph_padding) * target_scale
draw_quad.dst_scale = (glyph.bounds_size_scaled + glyph_padding) * target_scale
draw_quad.dst_pos = glyph.position + (bounds_scaled.p0 - glyph_padding) * target_scale
draw_quad.dst_scale = (bounds_size_scaled + glyph_padding) * target_scale
// The glyph buffer space transform for generate_glyph_pass_draw_list
draw_transform := & glyph.draw_transform
draw_transform.scale = font_scale * glyph.over_sample
draw_transform.pos = -1 * glyph.bounds.p0 * draw_transform.scale + vec2(atlas.glyph_padding)
draw_transform.pos = -1 * bounds.p0 * draw_transform.scale + vec2(atlas.glyph_padding)
draw_transform.pos.x += glyph.buffer_x
to_glyph_buffer_space( & draw_transform.pos, & draw_transform.scale, glyph_buffer_size )
draw_quad.src_pos = Vec2 { glyph.buffer_x, 0 }
draw_quad.src_scale = glyph.bounds_size_scaled * glyph.over_sample + glyph_padding
draw_quad.src_scale = bounds_size_scaled * glyph.over_sample + glyph_padding
to_target_space( & draw_quad.src_pos, & draw_quad.src_scale, glyph_buffer_size )
}
profile_end()
profile_begin("generate oversized glyphs draw_list")
if len(oversized) > 0
when ENABLE_OVERSIZED_GLYPHS do if len(oversized) > 0
{
// colour.r = max(colour.a, enable_debug_vis_type)
// colour.g = max(colour.g, enable_debug_vis_type)
// colour.b = colour.b * f32(cast(i32) ! b32(cast(i32) enable_debug_vis_type))
for id, index in oversized {
for pack_id, index in oversized {
error : Allocator_Error
glyph_pack[id].shape, error = parser_get_glyph_shape(entry.parser_info, glyph_pack[id].index)
glyph_pack[pack_id].shape, error = parser_get_glyph_shape(entry.parser_info, shape.glyph_id[pack_id])
assert(error == .None)
}
for id, index in oversized
{
glyph := & glyph_pack[id]
glyph := & glyph_pack[id]
bounds := shape.bounds[id]
if glyph.flush_glyph_buffer do flush_glyph_buffer_draw_list(draw_list,
& glyph_buffer.draw_list,
& glyph_buffer.clear_draw_list,
@ -640,7 +620,7 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
generate_glyph_pass_draw_list( draw_list, & glyph_buffer.shape_gen_scratch,
glyph_pack[id].shape,
entry.curve_quality,
glyph_pack[id].bounds,
bounds,
glyph_pack[id].draw_transform.pos,
glyph_pack[id].draw_transform.scale
)
@ -691,16 +671,19 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
profile_begin("to_cache: caching to atlas")
if len(to_cache) > 0
{
for id, index in to_cache {
for pack_id, index in to_cache {
error : Allocator_Error
glyph_pack[id].shape, error = parser_get_glyph_shape(entry.parser_info, glyph_pack[id].index)
glyph_pack[pack_id].shape, error = parser_get_glyph_shape(entry.parser_info, shape.glyph_id[pack_id])
assert(error == .None)
}
for id, index in to_cache
{
profile("glyph")
glyph := & glyph_pack[id]
glyph := & glyph_pack[id]
bounds := shape.bounds[id]
bounds_scaled := mul(bounds, font_scale)
bounds_size_scaled := size(bounds_scaled)
if glyph.flush_glyph_buffer do flush_glyph_buffer_draw_list( draw_list,
& glyph_buffer.draw_list,
@ -723,12 +706,12 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
clear_target_region.end_index = cast(u32) len(glyph_buffer.clear_draw_list.indices)
dst_glyph_pos := glyph.region_pos
dst_glyph_size := glyph.bounds_size_scaled + atlas.glyph_padding
dst_glyph_size := bounds_size_scaled + atlas.glyph_padding
dst_glyph_size.y = max(dst_glyph_size.y, ceil(dst_glyph_size.y) * glyph_buffer.snap_glyph_height) // Note(Ed): Seems to improve hinting
to_glyph_buffer_space( & dst_glyph_pos, & dst_glyph_size, atlas_size )
src_position := Vec2 { glyph.buffer_x, 0 }
src_size := (glyph.bounds_size_scaled + atlas.glyph_padding) * glyph_buffer.over_sample
src_size := (bounds_size_scaled + atlas.glyph_padding) * glyph_buffer.over_sample
src_size.y = max(src_size.y, ceil(src_size.y) * glyph_buffer.snap_glyph_height) // Note(Ed): Seems to improve hinting
to_target_space( & src_position, & src_size, glyph_buffer_size )
@ -748,7 +731,7 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
generate_glyph_pass_draw_list( draw_list, & glyph_buffer.shape_gen_scratch,
glyph.shape,
entry.curve_quality,
glyph.bounds,
bounds,
glyph.draw_transform.pos,
glyph.draw_transform.scale
)

View File

@ -58,6 +58,18 @@ Vec2 :: [2]f32
Vec2i :: [2]i32
Vec2_64 :: [2]f64
Transform :: struct {
pos : Vec2,
scale : Vec2,
}
Range2 :: struct {
p0, p1 : Vec2,
}
mul_range2_vec2 :: #force_inline proc "contextless" ( range : Range2, v : Vec2 ) -> Range2 { return { range.p0 * v, range.p1 * v } }
size_range2 :: #force_inline proc "contextless" ( range : Range2 ) -> Vec2 { return range.p1 - range.p0 }
vec2_from_scalar :: #force_inline proc "contextless" ( scalar : f32 ) -> Vec2 { return { scalar, scalar }}
vec2_64_from_vec2 :: #force_inline proc "contextless" ( v2 : Vec2 ) -> Vec2_64 { return { f64(v2.x), f64(v2.y) }}
vec2_from_vec2i :: #force_inline proc "contextless" ( v2i : Vec2i ) -> Vec2 { return { f32(v2i.x), f32(v2i.y) }}

View File

@ -102,6 +102,10 @@ make_soa :: proc {
builtin.make_soa_slice,
}
mul :: proc {
mul_range2_vec2,
}
peek :: proc {
peek_array,
}
@ -110,6 +114,10 @@ resize :: proc {
builtin.resize_dynamic_array,
}
size :: proc {
size_range2,
}
vec2 :: proc {
vec2_from_scalar,
vec2_from_vec2i,

View File

@ -25,12 +25,15 @@ Shape_Key :: u32
If your doing something heavy though (where there is thousands, or tens-of thousands)
your not going to be satisfied with keeping that in the iteration).
*/
Shaped_Text :: struct {
Shaped_Text :: struct #packed {
glyph_id : [dynamic]Glyph,
position : [dynamic]Vec2,
atlas_lru_code : [dynamic]Atlas_Key,
region_kind : [dynamic]Atlas_Region_Kind,
bound : [dynamic]Range2,
bounds : [dynamic]Range2,
// bounds_scaled : [dynamic]Range2,
// bounds_size : [dynamic]Vec2,
// bounds_size_Scaled : [dynamic]Vec2,
end_cursor_pos : Vec2,
size : Vec2,
}
@ -281,28 +284,41 @@ shaper_shape_text_uncached_advanced :: #force_inline proc( ctx : ^Shaper_Context
// Resolve each glyphs: bounds, atlas lru, and the atlas region as we have everything we need now.
resize( & output.atlas_lru_code, len(output.glyph_id) )
resize( & output.region_kind, len(output.glyph_id) )
resize( & output.bounds, len(output.glyph_id) )
// resize( & output.bounds_scaled, len(output.glyph_id) )
profile_begin("bounds")
for id, index in output.glyph_id
{
// glyph.bounds = parser_get_bounds( entry.parser_info, glyph.index )
// glyph.bounds_scaled = { glyph.bounds.p0 * font_scale, glyph.bounds.p1 * font_scale }
// glyph.bounds_size = glyph.bounds.p1 - glyph.bounds.p0
// glyph.bounds_size_scaled = glyph.bounds_size * font_scale
// glyph.scale = glyph.bounds_size_scaled + atlas.glyph_padding
bounds := & output.bounds[index]
// bounds_scaled := & output.bounds_scaled[index]
// bounds_size := & output.bounds_size[index]
// bounds_size_scaled := & output.bounds_size_scaled[index]
// scale := & output.scale[index]
(bounds ^) = parser_get_bounds( entry.parser_info, id )
// (bounds_scaled ^) = { bounds.p0 * font_scale, bounds.p1 * font_scale }
// bounds_size = bounds.p1 - bounds.p0
// bounds_size_scaled = bounds_size * font_scale
// scale = glyph.bounds_size_scaled + atlas.glyph_padding
}
profile_end()
profile_begin("index")
profile_begin("atlas_lru_code")
for id, index in output.glyph_id
{
// output.atlas_lru_code[index] = atlas_glyph_lru_code(entry.id, px_size, glyph.index)
output.atlas_lru_code[index] = atlas_glyph_lru_code(entry.id, font_px_size, id)
}
profile_end()
profile_begin("region")
for id, index in output.glyph_id
{
// output.region_kind[index] = atlas_decide_region_branchless( atlas ^, glyph_buffer_size, glyph.bounds_size_scaled )
bounds := & output.bounds[index]
bounds_size_scaled := (bounds.p1 - bounds.p0) * font_scale
output.region_kind[index] = atlas_decide_region( atlas, glyph_buffer_size, bounds_size_scaled )
}
profile_end()
}

View File

@ -8,7 +8,8 @@ package vetext
import "base:runtime"
// See: mappings.odin for profiling hookup
DISABLE_PROFILING :: false
DISABLE_PROFILING :: false
ENABLE_OVERSIZED_GLYPHS :: true
Font_ID :: distinct i32
Glyph :: distinct i32
@ -158,13 +159,14 @@ Init_Shaper_Params_Default :: Init_Shaper_Params {
Init_Shape_Cache_Params :: struct {
// Note(Ed): This should mostly just be given the worst-case capacity and reserve at the same time.
// If memory is a concern it can easily be 256 - 2k if not much text is going to be rendered often.
// Shapes should really not exceed 1024 glyphs..
capacity : u32,
reserve : u32,
}
Init_Shape_Cache_Params_Default :: Init_Shape_Cache_Params {
capacity = 10 * 1024,
reserve = 10 * 1024,
reserve = 1024,
}
//#region("lifetime")
@ -268,7 +270,8 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType,
shape_cache.storage, error = make( [dynamic]Shaped_Text, shape_cache_params.capacity )
assert(error == .None, "VEFontCache.init : Failed to allocate shape_cache.storage")
for idx : u32 = 0; idx < shape_cache_params.capacity; idx += 1 {
for idx : u32 = 0; idx < shape_cache_params.capacity; idx += 1
{
stroage_entry := & shape_cache.storage[idx]
stroage_entry.glyph_id, error = make( [dynamic]Glyph, len = 0, cap = shape_cache_params.reserve )
@ -276,6 +279,18 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType,
stroage_entry.position, error = make( [dynamic]Vec2, len = 0, cap = shape_cache_params.reserve )
assert( error == .None, "VEFontCache.init : Failed to allocate positions array for shape cache storage" )
stroage_entry.atlas_lru_code, error = make( [dynamic]Atlas_Key, len = 0, cap = shape_cache_params.reserve )
assert( error == .None, "VEFontCache.init : Failed to allocate atlas_lru_code array for shape cache storage" )
stroage_entry.region_kind, error = make( [dynamic]Atlas_Region_Kind, len = 0, cap = shape_cache_params.reserve )
assert( error == .None, "VEFontCache.init : Failed to allocate region_kind array for shape cache storage" )
stroage_entry.bounds, error = make( [dynamic]Range2, len = 0, cap = shape_cache_params.reserve )
assert( error == .None, "VEFontCache.init : Failed to allocate bounds array for shape cache storage" )
// stroage_entry.bounds_scaled, error = make( [dynamic]Range2, len = 0, cap = shape_cache_params.reserve )
// assert( error == .None, "VEFontCache.init : Failed to allocate bounds_scaled array for shape cache storage" )
}
}
@ -365,8 +380,12 @@ hot_reload :: proc( ctx : ^Context, allocator : Allocator )
lru_reload( & shape_cache.state, allocator )
for idx : i32 = 0; idx < i32(len(shape_cache.storage)); idx += 1 {
storage_entry := & shape_cache.storage[idx]
reload_array( & storage_entry.glyph_id, allocator )
reload_array( & storage_entry.position, allocator )
reload_array( & storage_entry.glyph_id, allocator)
reload_array( & storage_entry.position, allocator)
reload_array( & storage_entry.atlas_lru_code, allocator)
reload_array( & storage_entry.region_kind, allocator)
reload_array( & storage_entry.bounds, allocator)
// reload_array( & storage_entry.bounds_scaled, allocator)
}
reload_array( & shape_cache.storage, allocator )
@ -415,6 +434,10 @@ shutdown :: proc( ctx : ^Context )
storage_entry := & shape_cache.storage[idx]
delete( storage_entry.glyph_id )
delete( storage_entry.position )
delete( storage_entry.atlas_lru_code)
delete( storage_entry.region_kind)
delete( storage_entry.bounds)
// delete( storage_entry.bounds_scaled)
}
lru_free( & shape_cache.state )

View File

@ -15,7 +15,7 @@ set_profiler_module_context :: #force_inline proc "contextless" ( ctx : ^SpallPr
Module_Context = ctx
}
DISABLE_PROFILING :: false
DISABLE_PROFILING :: true
@(deferred_none = profile_end, disabled = DISABLE_PROFILING)
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {

View File

@ -205,11 +205,11 @@ push-location $path_root
# $build_args += $flag_micro_architecture_native
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
$build_args += $flag_optimize_none
# $build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed
# $build_args += $falg_optimize_aggressive
$build_args += $flag_debug
$build_args += $falg_optimize_aggressive
# $build_args += $flag_debug
$build_args += $flag_pdb_name + $pdb
$build_args += $flag_subsystem + 'windows'
# $build_args += $flag_show_system_calls