Successfuly hard-segmented the three different situations for enquing glyphs of a shape
This commit is contained in:
parent
4adbfaa9fd
commit
fa881a263a
@ -149,12 +149,10 @@ atlas_reserve_slot :: #force_inline proc ( region : ^Atlas_Region, lru_code : u6
|
||||
return
|
||||
}
|
||||
|
||||
check_and_reserve_slot_in_atlas :: #force_inline proc( ctx : ^Context, font : Font_ID, entry : ^Entry, glyph_index : Glyph,
|
||||
check_and_reserve_slot_in_atlas :: #force_inline proc( ctx : ^Context, glyph_index : Glyph,
|
||||
lru_code : u64,
|
||||
atlas_index : ^i32,
|
||||
region_kind : Atlas_Region_Kind,
|
||||
region : ^Atlas_Region,
|
||||
over_sample : Vec2
|
||||
) -> (found, should_cache : b8 )
|
||||
{
|
||||
profile(#procedure)
|
||||
@ -172,7 +170,6 @@ check_and_reserve_slot_in_atlas :: #force_inline proc( ctx : ^Context, font : Fo
|
||||
success : bool
|
||||
found, success = ctx.temp_codepoint_seen[next_evict_codepoint]
|
||||
assert(success != false)
|
||||
|
||||
if (found) {
|
||||
return
|
||||
}
|
||||
|
@ -341,8 +341,8 @@ cache_glyph_to_atlas :: proc ( ctx : ^Context,
|
||||
lru_code : u64,
|
||||
atlas_index : i32,
|
||||
entry : ^Entry,
|
||||
region_kind : Atlas_Region_Kind,
|
||||
region : ^Atlas_Region,
|
||||
// region_kind : Atlas_Region_Kind,
|
||||
// region : ^Atlas_Region,
|
||||
over_sample : Vec2
|
||||
)
|
||||
{
|
||||
@ -354,14 +354,6 @@ cache_glyph_to_atlas :: proc ( ctx : ^Context,
|
||||
glyph_buffer_size := Vec2 { f32(glyph_buffer.width), f32(glyph_buffer.height) }
|
||||
glyph_padding := cast(f32) atlas.glyph_padding
|
||||
|
||||
if ctx.debug_print
|
||||
{
|
||||
@static debug_total_cached : i32 = 0
|
||||
logf("glyph %v%v( %v ) caching to atlas region %v at idx %d. %d total glyphs cached.\n",
|
||||
i32(glyph_index), rune(glyph_index), cast(rune) region_kind, atlas_index, debug_total_cached)
|
||||
debug_total_cached += 1
|
||||
}
|
||||
|
||||
// Draw oversized glyph to glyph render target (FBO)
|
||||
glyph_draw_scale := over_sample * entry.size_scale
|
||||
glyph_draw_translate := -1 * bounds.p0 * glyph_draw_scale + vec2( glyph_padding )
|
||||
@ -555,29 +547,12 @@ draw_text_batch :: #force_inline proc (ctx: ^Context, entry: ^Entry, shaped: ^Sh
|
||||
atlas_size := Vec2{ f32(atlas.width), f32(atlas.height) }
|
||||
glyph_padding := atlas.glyph_padding
|
||||
|
||||
// for glyph, index in glyph_pack
|
||||
// {
|
||||
// profile("oversized")
|
||||
// if glyph.region_kind != .E do continue
|
||||
// directly_draw_massive_glyph(ctx, entry, glyph.index,
|
||||
// glyph.bounds,
|
||||
// glyph.bounds_size,
|
||||
// glyph.over_sample, glyph.translate, scale )
|
||||
// }
|
||||
call := Draw_Call_Default
|
||||
call.pass = .Target
|
||||
call.colour = ctx.colour
|
||||
|
||||
for glyph, index in glyph_pack
|
||||
{
|
||||
// profile_begin("oversized")
|
||||
// if glyph.region_kind == .E
|
||||
// {
|
||||
// directly_draw_massive_glyph(ctx, entry, glyph.index,
|
||||
// glyph.bounds,
|
||||
// glyph.bounds_size,
|
||||
// glyph.over_sample, glyph.translate, scale )
|
||||
// continue
|
||||
// }
|
||||
// profile_end()
|
||||
|
||||
profile("cached")
|
||||
|
||||
glyph_scale := glyph.bounds_size * entry.size_scale + glyph_padding
|
||||
@ -588,9 +563,6 @@ draw_text_batch :: #force_inline proc (ctx: ^Context, entry: ^Entry, shaped: ^Sh
|
||||
|
||||
textspace_x_form( & src_pos, & glyph_scale, atlas_size )
|
||||
|
||||
call := Draw_Call_Default
|
||||
call.pass = .Target
|
||||
call.colour = ctx.colour
|
||||
call.start_index = u32(len(ctx.draw_list.indices))
|
||||
|
||||
blit_quad(& ctx.draw_list,
|
||||
@ -623,6 +595,11 @@ GlyphPackEntry :: struct {
|
||||
should_cache : b8,
|
||||
}
|
||||
|
||||
Glyph_Sub_Pack :: struct {
|
||||
pack : #soa[]GlyphPackEntry,
|
||||
num : i32
|
||||
}
|
||||
|
||||
// Helper for draw_text, all raw text content should be confirmed to be either formatting or visible shapes before getting cached.
|
||||
draw_text_shape :: #force_inline proc( ctx : ^Context,
|
||||
font : Font_ID,
|
||||
@ -634,122 +611,111 @@ draw_text_shape :: #force_inline proc( ctx : ^Context,
|
||||
{
|
||||
profile(#procedure)
|
||||
|
||||
glyph_pack, glyph_pack_alloc_error := make_soa( #soa[]GlyphPackEntry, len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
oversized_pack, oversized_pack_alloc_error := make_soa( #soa[dynamic]GlyphPackEntry, length = 0, capacity = len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
oversized : Glyph_Sub_Pack = {}
|
||||
to_cache : Glyph_Sub_Pack = {}
|
||||
cached : Glyph_Sub_Pack = {}
|
||||
|
||||
profile_begin("soa allocation")
|
||||
glyph_pack, glyph_pack_alloc_error := make_soa( #soa[]GlyphPackEntry, len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
|
||||
alloc_error : Allocator_Error
|
||||
oversized.pack, alloc_error = make_soa( #soa[]GlyphPackEntry, len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
to_cache.pack, alloc_error = make_soa( #soa[]GlyphPackEntry, len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
cached.pack, alloc_error = make_soa( #soa[]GlyphPackEntry, len(shaped.glyphs), allocator = context.temp_allocator )
|
||||
profile_end()
|
||||
|
||||
append_sub_pack :: #force_inline proc "contextless" ( sub : ^Glyph_Sub_Pack, entry : GlyphPackEntry )
|
||||
{
|
||||
sub.pack[sub.num] = entry
|
||||
sub.num += 1
|
||||
}
|
||||
sub_slice :: #force_inline proc "contextless" ( sub : Glyph_Sub_Pack) -> #soa[]GlyphPackEntry { return sub.pack[: sub.num] }
|
||||
|
||||
atlas := & ctx.atlas
|
||||
|
||||
profile_begin("SOA setup")
|
||||
|
||||
profile_begin("index & translate")
|
||||
for & glyph, index in glyph_pack
|
||||
SOA_Setup:
|
||||
{
|
||||
glyph.shape_id = cast(i32) index
|
||||
glyph.index = shaped.glyphs[ index ]
|
||||
}
|
||||
profile_end()
|
||||
profile("SOA setup")
|
||||
|
||||
profile_begin("translate")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.translate = position + (shaped.positions[index]) * scale
|
||||
}
|
||||
profile_end()
|
||||
|
||||
profile_begin("bounds")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.lru_code = font_glyph_lru_code(entry.id, glyph.index)
|
||||
glyph.bounds = parser_get_bounds( & entry.parser_info, glyph.index )
|
||||
glyph.bounds_size = glyph.bounds.p1 - glyph.bounds.p0
|
||||
}
|
||||
profile_end()
|
||||
|
||||
profile_begin("region")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.region_kind,
|
||||
glyph.over_sample = decide_codepoint_region( ctx.atlas, ctx.glyph_buffer, entry.size_scale, glyph.index, glyph.bounds_size )
|
||||
}
|
||||
profile_end()
|
||||
|
||||
profile_begin("atlas region slot check & reservation")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
region := atlas.regions[glyph.region_kind]
|
||||
|
||||
if glyph.region_kind == .E do continue
|
||||
|
||||
glyph.atlas_index = lru_get( & region.state, glyph.lru_code )
|
||||
glyph.in_atlas, glyph.should_cache = check_and_reserve_slot_in_atlas( ctx, font, entry, glyph.index, glyph.lru_code, & glyph.atlas_index, glyph.region_kind, region, glyph.over_sample )
|
||||
glyph.region_pos, glyph.region_size = atlas_region_bbox(region ^, glyph.atlas_index)
|
||||
}
|
||||
profile_end()
|
||||
|
||||
profile_begin("caching to atlas")
|
||||
for glyph, index in glyph_pack
|
||||
{
|
||||
if glyph.region_kind == .E do continue
|
||||
if ! glyph.should_cache do continue
|
||||
cache_glyph_to_atlas(ctx, font, glyph.index, glyph.bounds, glyph.bounds_size, glyph.region_pos, glyph.region_size, glyph.lru_code, glyph.atlas_index, entry, glyph.region_kind, atlas.regions[glyph.region_kind], glyph.over_sample)
|
||||
}
|
||||
profile_end()
|
||||
|
||||
profile_end()
|
||||
|
||||
|
||||
// First batch the other cached glyphs
|
||||
// flush_glyph_buffer_to_atlas(ctx)
|
||||
// draw_text_batch( ctx, entry, shaped, glyph_pack[batch_start_idx : index], position, scale, snap_width, snap_height )
|
||||
// reset_batch_codepoint_state( ctx )
|
||||
|
||||
|
||||
// Prepare uncached glyphs for caching
|
||||
batch_start_idx : i32 = 0
|
||||
for glyph, index in glyph_pack
|
||||
{
|
||||
profile("caching glyph")
|
||||
|
||||
if glyph.region_kind == .E {
|
||||
append_soa( & oversized_pack, glyph )
|
||||
continue
|
||||
profile_begin("index & translate")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.shape_id = cast(i32) index
|
||||
glyph.index = shaped.glyphs[ index ]
|
||||
}
|
||||
profile_end()
|
||||
|
||||
if glyph.in_atlas {
|
||||
profile("glyph in atlas")
|
||||
// assert( lru_get( & atlas.regions[glyph.region_kind].state, glyph.lru_code ) != -1 )
|
||||
mark_batch_codepoint_seen( ctx, glyph.lru_code)
|
||||
continue
|
||||
profile_begin("translate")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.translate = position + (shaped.positions[index]) * scale
|
||||
}
|
||||
profile_end()
|
||||
|
||||
// We can no longer directly append the shape as it has missing glyphs in the atlas
|
||||
profile_begin("bounds")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.lru_code = font_glyph_lru_code(entry.id, glyph.index)
|
||||
glyph.bounds = parser_get_bounds( & entry.parser_info, glyph.index )
|
||||
glyph.bounds_size = glyph.bounds.p1 - glyph.bounds.p0
|
||||
}
|
||||
profile_end()
|
||||
|
||||
// First batch the other cached glyphs
|
||||
// flush_glyph_buffer_to_atlas(ctx)
|
||||
// draw_text_batch( ctx, entry, shaped, glyph_pack[batch_start_idx : index], position, scale, snap_width, snap_height )
|
||||
// reset_batch_codepoint_state( ctx )
|
||||
profile_begin("region & oversized segregation")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
glyph.region_kind,
|
||||
glyph.over_sample = decide_codepoint_region( ctx.atlas, ctx.glyph_buffer, entry.size_scale, glyph.index, glyph.bounds_size )
|
||||
}
|
||||
profile_end()
|
||||
|
||||
cache_glyph_to_atlas( ctx, font, glyph.index, glyph.bounds, glyph.bounds_size, glyph.region_pos, glyph.region_size, glyph.lru_code, glyph.atlas_index, entry, glyph.region_kind, atlas.regions[glyph.region_kind], glyph.over_sample )
|
||||
mark_batch_codepoint_seen( ctx, glyph.lru_code)
|
||||
|
||||
batch_start_idx = glyph.shape_id
|
||||
profile_begin("caching setup")
|
||||
for & glyph, index in glyph_pack
|
||||
{
|
||||
region := atlas.regions[glyph.region_kind]
|
||||
if glyph.region_kind == .E {
|
||||
append_sub_pack(& oversized, glyph)
|
||||
continue
|
||||
}
|
||||
|
||||
glyph.atlas_index = lru_get( & region.state, glyph.lru_code )
|
||||
glyph.in_atlas, glyph.should_cache = check_and_reserve_slot_in_atlas( ctx, glyph.index, glyph.lru_code, & glyph.atlas_index, region )
|
||||
glyph.region_pos, glyph.region_size = atlas_region_bbox(region ^, glyph.atlas_index)
|
||||
|
||||
if glyph.should_cache {
|
||||
profile("append to_cache")
|
||||
append_sub_pack(& to_cache, glyph)
|
||||
mark_batch_codepoint_seen(ctx, glyph.lru_code)
|
||||
cache_glyph_to_atlas( ctx, font, glyph.index, glyph.bounds, glyph.bounds_size, glyph.region_pos, glyph.region_size, glyph.lru_code, glyph.atlas_index, entry, glyph.over_sample )
|
||||
continue
|
||||
}
|
||||
else {
|
||||
profile("append cached")
|
||||
append_sub_pack(& cached, glyph)
|
||||
mark_batch_codepoint_seen(ctx, glyph.lru_code)
|
||||
}
|
||||
}
|
||||
profile_end()
|
||||
}
|
||||
|
||||
draw_text_batch( ctx, entry, shaped, glyph_pack[batch_start_idx : len(glyph_pack)], position, scale, snap_width , snap_height )
|
||||
|
||||
draw_text_batch( ctx, entry, shaped, sub_slice(to_cache), position, scale, snap_width, snap_height )
|
||||
reset_batch_codepoint_state( ctx )
|
||||
|
||||
profile_begin("draw oversized glyphs")
|
||||
draw_text_batch( ctx, entry, shaped, sub_slice(cached), position, scale, snap_width , snap_height )
|
||||
reset_batch_codepoint_state( ctx )
|
||||
|
||||
profile_begin("generate oversized glyphs draw_list")
|
||||
flush_glyph_buffer_to_atlas(ctx)
|
||||
|
||||
for & glyph, index in oversized_pack
|
||||
for & glyph, index in sub_slice(oversized)
|
||||
{
|
||||
directly_draw_massive_glyph(ctx, entry, glyph.index,
|
||||
glyph.bounds,
|
||||
glyph.bounds_size,
|
||||
glyph.over_sample, glyph.translate, scale )
|
||||
}
|
||||
|
||||
reset_batch_codepoint_state( ctx )
|
||||
|
||||
profile_end()
|
||||
|
||||
cursor_pos = position + shaped.end_cursor_pos * scale
|
||||
|
@ -67,7 +67,6 @@ mark_batch_codepoint_seen :: #force_inline proc "contextless" ( ctx : ^Context,
|
||||
}
|
||||
|
||||
reset_batch_codepoint_state :: #force_inline proc( ctx : ^Context ) {
|
||||
profile(#procedure)
|
||||
clear_map( & ctx.temp_codepoint_seen )
|
||||
ctx.temp_codepoint_seen_num = 0
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user