VEFontCache: Should be using odin arrays and maps excluisvely now for the package

This commit is contained in:
Edward R. Gonzalez 2024-06-25 23:53:44 -04:00
parent 1533a14a1b
commit 6f034534f3
5 changed files with 131 additions and 125 deletions

View File

@ -16,8 +16,8 @@ PoolListItem :: struct {
}
PoolList :: struct {
items : Array( PoolListItem ),
free_list : Array( PoolListIter ),
items : [dynamic]PoolListItem,
free_list : [dynamic]PoolListIter,
front : PoolListIter,
back : PoolListIter,
size : u32,
@ -28,13 +28,13 @@ PoolList :: struct {
pool_list_init :: proc( pool : ^PoolList, capacity : u32, dbg_name : string = "" )
{
error : AllocatorError
pool.items, error = make( Array( PoolListItem ), u64(capacity) )
pool.items, error = make( [dynamic]PoolListItem, u64(capacity) )
assert( error == .None, "VEFontCache.pool_list_init : Failed to allocate items array")
array_resize( & pool.items, u64(capacity) )
resize( & pool.items, capacity )
pool.free_list, error = make( Array( PoolListIter ), u64(capacity) )
pool.free_list, error = make( [dynamic]PoolListIter, u64(capacity) )
assert( error == .None, "VEFontCache.pool_list_init : Failed to allocate free_list array")
array_resize( & pool.free_list, u64(capacity) )
resize( & pool.free_list, capacity )
pool.capacity = capacity
@ -42,8 +42,8 @@ pool_list_init :: proc( pool : ^PoolList, capacity : u32, dbg_name : string = ""
using pool
for id in 0 ..< capacity {
free_list.data[id] = i32(id)
items.data[id] = {
free_list[id] = i32(id)
items[id] = {
prev = -1,
next = -1,
}
@ -60,30 +60,32 @@ pool_list_free :: proc( pool : ^PoolList )
pool_list_reload :: proc( pool : ^PoolList, allocator : Allocator )
{
pool.items.backing = allocator
pool.free_list.backing = allocator
reload_array( & pool.items, allocator )
reload_array( & pool.free_list, allocator )
}
pool_list_push_front :: proc( pool : ^PoolList, value : PoolListValue )
{
using pool
if size >= capacity do return
assert( free_list.num > 0 )
assert( free_list.num == u64(capacity - size) )
id := array_back( free_list )
length := len(free_list)
assert( length > 0 )
assert( length == int(capacity - size) )
id := free_list[ len(free_list) - 1 ]
if pool.dbg_name != "" {
logf("pool_list: back %v", id)
}
array_pop( free_list )
items.data[ id ].prev = -1
items.data[ id ].next = front
items.data[ id ].value = value
pop( & free_list )
items[ id ].prev = -1
items[ id ].next = front
items[ id ].value = value
if pool.dbg_name != "" {
logf("pool_list: pushed %v into id %v", value, id)
}
if front != -1 do items.data[ front ].prev = id
if front != -1 do items[ front ].prev = id
if back == -1 do back = id
front = id
size += 1
@ -94,14 +96,14 @@ pool_list_erase :: proc( pool : ^PoolList, iter : PoolListIter )
using pool
if size <= 0 do return
assert( iter >= 0 && iter < i32(capacity) )
assert( free_list.num == u64(capacity - size) )
assert( len(free_list) == int(capacity - size) )
iter_node := & items.data[ iter ]
iter_node := & items[ iter ]
prev := iter_node.prev
next := iter_node.next
if iter_node.prev != -1 do items.data[ prev ].next = iter_node.next
if iter_node.next != -1 do items.data[ next ].prev = iter_node.prev
if iter_node.prev != -1 do items[ prev ].next = iter_node.next
if iter_node.next != -1 do items[ next ].prev = iter_node.prev
if front == iter do front = iter_node.next
if back == iter do back = iter_node.prev
@ -121,17 +123,17 @@ pool_list_erase :: proc( pool : ^PoolList, iter : PoolListIter )
}
}
pool_list_peek_back :: #force_inline proc "contextless" ( pool : ^PoolList ) -> PoolListValue {
// assert( pool.back != - 1 )
value := pool.items.data[ pool.back ].value
pool_list_peek_back :: #force_inline proc ( pool : ^PoolList ) -> PoolListValue {
assert( pool.back != - 1 )
value := pool.items[ pool.back ].value
return value
}
pool_list_pop_back :: #force_inline proc( pool : ^PoolList ) -> PoolListValue {
if pool.size <= 0 do return 0
// assert( pool.back != -1 )
assert( pool.back != -1 )
value := pool.items.data[ pool.back ].value
value := pool.items[ pool.back ].value
pool_list_erase( pool, pool.back )
return value
}
@ -198,7 +200,7 @@ LRU_get :: #force_inline proc( cache : ^LRU_Cache, key : u64 ) -> i32 {
return iter.value
}
LRU_get_next_evicted :: #force_inline proc "contextless" ( cache : ^LRU_Cache ) -> u64
LRU_get_next_evicted :: #force_inline proc ( cache : ^LRU_Cache ) -> u64
{
if cache.key_queue.size >= cache.capacity {
evict := pool_list_peek_back( & cache.key_queue )

View File

@ -58,7 +58,7 @@ Context :: struct {
entries : [dynamic]Entry,
temp_path : Array(Vec2),
temp_path : [dynamic]Vec2,
temp_codepoint_seen : map[u64]bool,
temp_codepoint_seen_num : u32,
@ -170,19 +170,19 @@ init :: proc( ctx : ^Context, parser_kind : ParserKind,
entries, error = make( [dynamic]Entry, entires_reserve )
assert(error == .None, "VEFontCache.init : Failed to allocate entries")
temp_path, error = make( Array(Vec2), u64(temp_path_reserve) )
temp_path, error = make( [dynamic]Vec2, temp_path_reserve )
assert(error == .None, "VEFontCache.init : Failed to allocate temp_path")
temp_codepoint_seen, error = make( map[u64]bool, hmap_closest_prime( uint(temp_codepoint_seen_reserve)) )
assert(error == .None, "VEFontCache.init : Failed to allocate temp_path")
draw_list.vertices, error = make( Array(Vertex), 4 * Kilobyte )
draw_list.vertices, error = make( [dynamic]Vertex, 4 * Kilobyte )
assert(error == .None, "VEFontCache.init : Failed to allocate draw_list.vertices")
draw_list.indices, error = make( Array(u32), 8 * Kilobyte )
draw_list.indices, error = make( [dynamic]u32, 8 * Kilobyte )
assert(error == .None, "VEFontCache.init : Failed to allocate draw_list.indices")
draw_list.calls, error = make( Array(DrawCall), 512 )
draw_list.calls, error = make( [dynamic]DrawCall, 512 )
assert(error == .None, "VEFontCache.init : Failed to allocate draw_list.calls")
init_atlas_region :: proc( region : ^AtlasRegion, params : InitAtlasParams, region_params : InitAtlasRegionParams, factor : Vec2i, expected_cap : i32 ) {
@ -225,16 +225,16 @@ init :: proc( ctx : ^Context, parser_kind : ParserKind,
LRU_init( & shape_cache.state, shape_cache_params.capacity )
shape_cache.storage, error = make( Array(ShapedText), u64(shape_cache_params.capacity) )
shape_cache.storage, error = make( [dynamic]ShapedText, 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 {
stroage_entry := & shape_cache.storage.data[idx]
stroage_entry := & shape_cache.storage[idx]
using stroage_entry
glyphs, error = make( Array(Glyph), cast(u64) shape_cache_params.reserve_length )
glyphs, error = make( [dynamic]Glyph, shape_cache_params.reserve_length )
assert( error == .None, "VEFontCache.init : Failed to allocate glyphs array for shape cache storage" )
positions, error = make( Array(Vec2), cast(u64) shape_cache_params.reserve_length )
positions, error = make( [dynamic]Vec2, shape_cache_params.reserve_length )
assert( error == .None, "VEFontCache.init : Failed to allocate positions array for shape cache storage" )
}
@ -247,22 +247,22 @@ init :: proc( ctx : ^Context, parser_kind : ParserKind,
buffer_height = region_d.height * u32(over_sample.y)
draw_padding = glyph_draw_params.draw_padding
draw_list.calls, error = make( Array(DrawCall), cast(u64) glyph_draw_params.buffer_batch * 2 )
draw_list.calls, error = make( [dynamic]DrawCall, cast(u64) glyph_draw_params.buffer_batch * 2 )
assert( error == .None, "VEFontCache.init : Failed to allocate calls for draw_list" )
draw_list.indices, error = make( Array(u32), cast(u64) glyph_draw_params.buffer_batch * 2 * 6 )
draw_list.indices, error = make( [dynamic]u32, cast(u64) glyph_draw_params.buffer_batch * 2 * 6 )
assert( error == .None, "VEFontCache.init : Failed to allocate indices array for draw_list" )
draw_list.vertices, error = make( Array(Vertex), cast(u64) glyph_draw_params.buffer_batch * 2 * 4 )
draw_list.vertices, error = make( [dynamic]Vertex, glyph_draw_params.buffer_batch * 2 * 4 )
assert( error == .None, "VEFontCache.init : Failed to allocate vertices array for draw_list" )
clear_draw_list.calls, error = make( Array(DrawCall), cast(u64) glyph_draw_params.buffer_batch * 2 )
clear_draw_list.calls, error = make( [dynamic]DrawCall, cast(u64) glyph_draw_params.buffer_batch * 2 )
assert( error == .None, "VEFontCache.init : Failed to allocate calls for calls for clear_draw_list" )
clear_draw_list.indices, error = make( Array(u32), cast(u64) glyph_draw_params.buffer_batch * 2 * 4 )
clear_draw_list.indices, error = make( [dynamic]u32, cast(u64) glyph_draw_params.buffer_batch * 2 * 4 )
assert( error == .None, "VEFontCache.init : Failed to allocate calls for indices array for clear_draw_list" )
clear_draw_list.vertices, error = make( Array(Vertex), cast(u64) glyph_draw_params.buffer_batch * 2 * 4 )
clear_draw_list.vertices, error = make( [dynamic]Vertex, glyph_draw_params.buffer_batch * 2 * 4 )
assert( error == .None, "VEFontCache.init : Failed to allocate vertices array for clear_draw_list" )
}
@ -277,14 +277,13 @@ hot_reload :: proc( ctx : ^Context, allocator : Allocator )
using ctx
// entries.backing = allocator
reload_array( & entries, allocator )
temp_path.backing = allocator
reload_array( & temp_path, allocator )
reload_map( & ctx.temp_codepoint_seen, allocator )
draw_list.vertices.backing = allocator
draw_list.indices.backing = allocator
draw_list.calls.backing = allocator
reload_array( & draw_list.vertices, allocator)
reload_array( & draw_list.indices, allocator )
reload_array( & draw_list.calls, allocator )
LRU_reload( & atlas.region_a.state, allocator)
LRU_reload( & atlas.region_b.state, allocator)
@ -292,23 +291,23 @@ hot_reload :: proc( ctx : ^Context, allocator : Allocator )
LRU_reload( & atlas.region_d.state, allocator)
LRU_reload( & shape_cache.state, allocator )
for idx : u32 = 0; idx < u32(shape_cache.storage.capacity); idx += 1 {
stroage_entry := & shape_cache.storage.data[idx]
for idx : u32 = 0; idx < u32(len(shape_cache.storage)); idx += 1 {
stroage_entry := & shape_cache.storage[idx]
using stroage_entry
glyphs.backing = allocator
positions.backing = allocator
reload_array( & glyphs, allocator )
reload_array( & positions, allocator )
}
atlas.draw_list.calls.backing = allocator
atlas.draw_list.indices.backing = allocator
atlas.draw_list.vertices.backing = allocator
reload_array( & atlas.draw_list.calls, allocator )
reload_array( & atlas.draw_list.indices, allocator )
reload_array( & atlas.draw_list.vertices, allocator )
atlas.clear_draw_list.calls.backing = allocator
atlas.clear_draw_list.indices.backing = allocator
atlas.clear_draw_list.vertices.backing = allocator
reload_array( & atlas.clear_draw_list.calls, allocator )
reload_array( & atlas.clear_draw_list.indices, allocator )
reload_array( & atlas.clear_draw_list.vertices, allocator )
shape_cache.storage.backing = allocator
reload_array( & shape_cache.storage, allocator )
LRU_reload( & shape_cache.state, allocator )
}
@ -455,42 +454,41 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
// Note(Original Author): Figure out scaling so it fits within our box.
draw := DrawCall_Default
draw.pass = FrameBufferPass.Glyph
draw.start_index = u32(ctx.draw_list.indices.num)
draw.start_index = u32(len(ctx.draw_list.indices))
// Note(Original Author);
// Draw the path using simplified version of https://medium.com/@evanwallace/easy-scalable-text-rendering-on-the-gpu-c3f4d782c5ac.
// Instead of involving fragment shader code we simply make use of modern GPU ability to crunch triangles and brute force curve definitions.
path := ctx.temp_path
clear(path)
clear( & path)
for edge in shape do switch edge.type
{
case .Move:
path_slice := array_to_slice(path)
if path.num > 0 {
draw_filled_path( & ctx.draw_list, outside, array_to_slice(path), scale, translate, ctx.debug_print_verbose )
if len(path) > 0 {
draw_filled_path( & ctx.draw_list, outside, path[:], scale, translate, ctx.debug_print_verbose )
}
clear(path)
clear( & path)
fallthrough
case .Line:
append( & path, Vec2{ f32(edge.x), f32(edge.y) })
append_elem( & path, Vec2{ f32(edge.x), f32(edge.y) })
case .Curve:
assert( path.num > 0 )
p0 := path.data[ path.num - 1 ]
assert( len(path) > 0 )
p0 := path[ len(path) - 1 ]
p1 := Vec2{ f32(edge.contour_x0), f32(edge.contour_y0) }
p2 := Vec2{ f32(edge.x), f32(edge.y) }
step := 1.0 / f32(ctx.curve_quality)
alpha := step
for index := i32(0); index < i32(ctx.curve_quality); index += 1 {
append( & path, eval_point_on_bezier3( p0, p1, p2, alpha ))
append_elem( & path, eval_point_on_bezier3( p0, p1, p2, alpha ))
alpha += step
}
case .Cubic:
assert( path.num > 0 )
p0 := path.data[ path.num - 1]
assert( len(path) > 0 )
p0 := path[ len(path) - 1]
p1 := Vec2{ f32(edge.contour_x0), f32(edge.contour_y0) }
p2 := Vec2{ f32(edge.contour_x1), f32(edge.contour_y1) }
p3 := Vec2{ f32(edge.x), f32(edge.y) }
@ -498,19 +496,19 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
step := 1.0 / f32(ctx.curve_quality)
alpha := step
for index := i32(0); index < i32(ctx.curve_quality); index += 1 {
append( & path, eval_point_on_bezier4( p0, p1, p2, p3, alpha ))
append_elem( & path, eval_point_on_bezier4( p0, p1, p2, p3, alpha ))
alpha += step
}
case .None:
assert(false, "Unknown edge type or invalid")
}
if path.num > 0 {
draw_filled_path( & ctx.draw_list, outside, array_to_slice(path), scale, translate, ctx.debug_print_verbose )
if len(path) > 0 {
draw_filled_path( & ctx.draw_list, outside, path[:], scale, translate, ctx.debug_print_verbose )
}
// Note(Original Author): Apend the draw call
draw.end_index = cast(u32) ctx.draw_list.indices.num
draw.end_index = cast(u32) len(ctx.draw_list.indices)
if draw.end_index > draw.start_index {
append(& ctx.draw_list.calls, draw)
}
@ -624,16 +622,16 @@ cache_glyph_to_atlas :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph
using call
pass = .Atlas
region = .Ignore
start_index = u32(atlas.clear_draw_list.indices.num)
start_index = cast(u32) len(atlas.clear_draw_list.indices)
blit_quad( & atlas.clear_draw_list, dst_position, dst_position + dst_size, { 1.0, 1.0 }, { 1.0, 1.0 } )
end_index = u32(atlas.clear_draw_list.indices.num)
end_index = cast(u32) len(atlas.clear_draw_list.indices)
append( & atlas.clear_draw_list.calls, call )
// Queue up a blit from glyph_update_FBO to the atlas
region = .None
start_index = u32(atlas.draw_list.indices.num)
start_index = cast(u32) len(atlas.draw_list.indices)
blit_quad( & atlas.draw_list, dst_glyph_position, dst_position + dst_glyph_size, src_position, src_position + src_size )
end_index = u32(atlas.draw_list.indices.num)
end_index = cast(u32) len(atlas.draw_list.indices)
append( & atlas.draw_list.calls, call )
}
@ -664,9 +662,9 @@ measure_text_size :: proc( ctx : ^Context, font : FontID, text_utf8 : string ) -
entry := & ctx.entries[ font ]
padding := cast(f32) atlas.glyph_padding
for index : i32 = 0; index < i32(shaped.glyphs.num); index += 1
for index : i32 = 0; index < i32(len(shaped.glyphs)); index += 1
{
glyph_index := shaped.glyphs.data[ index ]
glyph_index := shaped.glyphs[ index ]
if is_empty( ctx, entry, glyph_index ) do continue
bounds_0, bounds_1 := parser_get_glyph_box( & entry.parser_info, glyph_index )

View File

@ -21,9 +21,9 @@ DrawCall_Default :: DrawCall {
}
DrawList :: struct {
vertices : Array(Vertex),
indices : Array(u32),
calls : Array(DrawCall),
vertices : [dynamic]Vertex,
indices : [dynamic]u32,
calls : [dynamic]DrawCall,
}
FrameBufferPass :: enum u32 {
@ -51,31 +51,31 @@ blit_quad :: proc( draw_list : ^DrawList, p0 : Vec2 = {0, 0}, p1 : Vec2 = {1, 1}
// profile(#procedure)
// logf("Blitting: xy0: %0.2f, %0.2f xy1: %0.2f, %0.2f uv0: %0.2f, %0.2f uv1: %0.2f, %0.2f",
// p0.x, p0.y, p1.x, p1.y, uv0.x, uv0.y, uv1.x, uv1.y);
v_offset := cast(u32) draw_list.vertices.num
v_offset := cast(u32) len(draw_list.vertices)
vertex := Vertex {
{p0.x, p0.y},
uv0.x, uv0.y
}
append( & draw_list.vertices, vertex )
append_elem( & draw_list.vertices, vertex )
vertex = Vertex {
{p0.x, p1.y},
uv0.x, uv1.y
}
append( & draw_list.vertices, vertex )
append_elem( & draw_list.vertices, vertex )
vertex = Vertex {
{p1.x, p0.y},
uv1.x, uv0.y
}
append( & draw_list.vertices, vertex )
append_elem( & draw_list.vertices, vertex )
vertex = Vertex {
{p1.x, p1.y},
uv1.x, uv1.y
}
append( & draw_list.vertices, vertex )
append_elem( & draw_list.vertices, vertex )
quad_indices : []u32 = {
0, 1, 2,
@ -91,9 +91,9 @@ blit_quad :: proc( draw_list : ^DrawList, p0 : Vec2 = {0, 0}, p1 : Vec2 = {1, 1}
// ve_fontcache_clear_drawlist
clear_draw_list :: #force_inline proc ( draw_list : ^DrawList ) {
clear( draw_list.calls )
clear( draw_list.indices )
clear( draw_list.vertices )
clear( & draw_list.calls )
clear( & draw_list.indices )
clear( & draw_list.vertices )
}
directly_draw_massive_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph : Glyph, bounds_0 : Vec2i, bounds_width, bounds_height : i32, over_sample, position, scale : Vec2 )
@ -140,9 +140,9 @@ directly_draw_massive_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph : Gly
using call
pass = .Target_Uncached
colour = ctx.colour
start_index = u32(ctx.draw_list.indices.num)
start_index = u32(len(ctx.draw_list.indices))
blit_quad( & ctx.draw_list, dst, dst + dst_size, glyph_position, glyph_position + glyph_size )
end_index = u32(ctx.draw_list.indices.num)
end_index = u32(len(ctx.draw_list.indices))
append( & ctx.draw_list.calls, call )
}
@ -222,10 +222,10 @@ draw_cached_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph,
using call
pass = .Target
colour = ctx.colour
start_index = cast(u32) ctx.draw_list.indices.num
start_index = cast(u32) len(ctx.draw_list.indices)
blit_quad( & ctx.draw_list, dst, dst + dst_scale, glyph_atlas_position, glyph_atlas_position + glyph_scale )
end_index = cast(u32) ctx.draw_list.indices.num
end_index = cast(u32) len(ctx.draw_list.indices)
}
append( & ctx.draw_list.calls, call )
return true
@ -252,7 +252,7 @@ draw_filled_path :: proc( draw_list : ^DrawList, outside_point : Vec2, path : []
}
}
v_offset := cast(u32) draw_list.vertices.num
v_offset := cast(u32) len(draw_list.vertices)
for point in path {
vertex := Vertex {
pos = point * scale + translate,
@ -262,7 +262,7 @@ draw_filled_path :: proc( draw_list : ^DrawList, outside_point : Vec2, path : []
append( & draw_list.vertices, vertex )
}
outside_vertex := cast(u32) draw_list.vertices.num
outside_vertex := cast(u32) len(draw_list.vertices)
{
vertex := Vertex {
pos = outside_point * scale + translate,
@ -416,8 +416,8 @@ draw_text_batch :: proc( ctx : ^Context, entry : ^Entry, shaped : ^ShapedText, b
for index := batch_start_idx; index < batch_end_idx; index += 1
{
// profile(#procedure)
glyph_index := shaped.glyphs.data[ index ]
shaped_position := shaped.positions.data[index]
glyph_index := shaped.glyphs[ index ]
shaped_position := shaped.positions[index]
glyph_translate := position + shaped_position * scale
glyph_cached := draw_cached_glyph( ctx, entry, glyph_index, glyph_translate, scale)
assert( glyph_cached == true )
@ -430,9 +430,9 @@ draw_text_shape :: proc( ctx : ^Context, font : FontID, entry : ^Entry, shaped :
{
// profile(#procedure)
batch_start_idx : i32 = 0
for index : i32 = 0; index < i32(shaped.glyphs.num); index += 1
for index : i32 = 0; index < i32(len(shaped.glyphs)); index += 1
{
glyph_index := shaped.glyphs.data[ index ]
glyph_index := shaped.glyphs[ index ]
if is_empty( ctx, entry, glyph_index ) do continue
if can_batch_glyph( ctx, font, entry, glyph_index ) do continue
@ -449,7 +449,7 @@ draw_text_shape :: proc( ctx : ^Context, font : FontID, entry : ^Entry, shaped :
batch_start_idx = index
}
draw_text_batch( ctx, entry, shaped, batch_start_idx, i32(shaped.glyphs.num), position, scale )
draw_text_batch( ctx, entry, shaped, batch_start_idx, i32(len(shaped.glyphs)), position, scale )
reset_batch_codepoint_state( ctx )
cursor_pos = position + shaped.end_cursor_pos * scale
return
@ -501,22 +501,24 @@ merge_draw_list :: proc( dst, src : ^DrawList )
// profile(#procedure)
error : AllocatorError
v_offset := cast(u32) dst.vertices.num
v_offset := cast(u32) len( dst.vertices )
// for index : u32 = 0; index < cast(u32) src.vertices.num; index += 1 {
// error = append( & dst.vertices, src.vertices.data[index] )
// assert( error == .None )
// }
error = append( & dst.vertices, src.vertices )
num_appended : int
num_appended, error = append_elems( & dst.vertices, ..src.vertices[:] )
assert( error == .None )
i_offset := cast(u32) dst.indices.num
for index : u32 = 0; index < cast(u32) src.indices.num; index += 1 {
error = append( & dst.indices, src.indices.data[index] + v_offset )
i_offset := cast(u32) len(dst.indices)
for index : u32 = 0; index < cast(u32) len(src.indices); index += 1 {
ignored : int
ignored, error = append( & dst.indices, src.indices[index] + v_offset )
assert( error == .None )
}
for index : u32 = 0; index < cast(u32) src.calls.num; index += 1 {
src_call := src.calls.data[ index ]
for index : u32 = 0; index < cast(u32) len(src.calls); index += 1 {
src_call := src.calls[ index ]
src_call.start_index += i_offset
src_call.end_index += i_offset
append( & dst.calls, src_call )
@ -529,14 +531,12 @@ optimize_draw_list :: proc( draw_list : ^DrawList, call_offset : u64 )
// profile(#procedure)
assert( draw_list != nil )
calls := array_to_slice(draw_list.calls)
write_index : u64 = call_offset
for index : u64 = 1 + call_offset; index < u64(draw_list.calls.num); index += 1
for index : u64 = 1 + call_offset; index < cast(u64) len(draw_list.calls); index += 1
{
assert( write_index <= index )
draw_0 := & draw_list.calls.data[ write_index ]
draw_1 := & draw_list.calls.data[ index ]
draw_0 := & draw_list.calls[ write_index ]
draw_1 := & draw_list.calls[ index ]
merge : b32 = true
if draw_0.pass != draw_1.pass do merge = false
@ -557,11 +557,11 @@ optimize_draw_list :: proc( draw_list : ^DrawList, call_offset : u64 )
// logf("can't merge %v : %v %v", draw_0.pass, write_index, index )
write_index += 1
if write_index != index {
draw_2 := & draw_list.calls.data[ write_index ]
draw_2 := & draw_list.calls[ write_index ]
draw_2^ = draw_1^
}
}
}
resize( & draw_list.calls, u64(write_index + 1) )
resize( & draw_list.calls, write_index + 1 )
}

View File

@ -89,7 +89,9 @@ append :: proc {
grime.array_append_slice,
grime.array_append_value,
// append_elem, append_elems, append_elem_string,
append_elem,
// append_elems,
// append_elem_string,
}
append_at :: proc {
@ -101,6 +103,8 @@ clear :: proc {
array_clear,
hmap_chained_clear,
hmap_zpl_clear,
clear_dynamic_array,
}
delete :: proc {
@ -134,6 +138,8 @@ remove_at :: proc {
resize :: proc {
array_resize,
resize_dynamic_array,
}
set :: proc {

View File

@ -3,13 +3,13 @@ package VEFontCache
import "core:math"
ShapedText :: struct {
glyphs : Array(Glyph),
positions : Array(Vec2),
glyphs : [dynamic]Glyph,
positions : [dynamic]Vec2,
end_cursor_pos : Vec2,
}
ShapedTextCache :: struct {
storage : Array(ShapedText),
storage : [dynamic]ShapedText,
state : LRU_Cache,
next_cache_id : i32,
}
@ -54,10 +54,10 @@ shape_text_cached :: proc( ctx : ^Context, font : FontID, text_utf8 : string ) -
LRU_put( state, hash, shape_cache_idx )
}
shape_text_uncached( ctx, font, & shape_cache.storage.data[ shape_cache_idx ], text_utf8 )
shape_text_uncached( ctx, font, & shape_cache.storage[ shape_cache_idx ], text_utf8 )
}
return & shape_cache.storage.data[ shape_cache_idx ]
return & shape_cache.storage[ shape_cache_idx ]
}
shape_text_uncached :: proc( ctx : ^Context, font : FontID, output : ^ShapedText, text_utf8 : string )
@ -69,8 +69,8 @@ shape_text_uncached :: proc( ctx : ^Context, font : FontID, output : ^ShapedText
use_full_text_shape := ctx.text_shape_adv
entry := & ctx.entries[ font ]
clear( output.glyphs )
clear( output.positions )
clear( & output.glyphs )
clear( & output.positions )
ascent, descent, line_gap := parser_get_font_vertical_metrics( & entry.parser_info )