VEFontCache: Should be using odin arrays and maps excluisvely now for the package
This commit is contained in:
parent
1533a14a1b
commit
6f034534f3
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 )
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user