Fixed a long-standing issue with the chained hashmap (finally)
This commit is contained in:
parent
c405c47e6c
commit
a560222d5d
@ -4,6 +4,8 @@ package VEFontCache
|
||||
The choice was made to keep the LRU cache implementation as close to the original as possible.
|
||||
*/
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
PoolListIter :: i32
|
||||
PoolListValue :: u64
|
||||
|
||||
@ -20,9 +22,10 @@ PoolList :: struct {
|
||||
back : PoolListIter,
|
||||
size : u32,
|
||||
capacity : u32,
|
||||
dbg_name : string,
|
||||
}
|
||||
|
||||
pool_list_init :: proc( pool : ^PoolList, capacity : u32 )
|
||||
pool_list_init :: proc( pool : ^PoolList, capacity : u32, dbg_name : string = "" )
|
||||
{
|
||||
error : AllocatorError
|
||||
pool.items, error = make( Array( PoolListItem ), u64(capacity) )
|
||||
@ -35,6 +38,7 @@ pool_list_init :: proc( pool : ^PoolList, capacity : u32 )
|
||||
|
||||
pool.capacity = capacity
|
||||
|
||||
pool.dbg_name = dbg_name
|
||||
using pool
|
||||
|
||||
for id in 0 ..< capacity {
|
||||
@ -72,6 +76,9 @@ pool_list_push_front :: proc( pool : ^PoolList, value : PoolListValue )
|
||||
items.data[ id ].prev = -1
|
||||
items.data[ id ].next = front
|
||||
items.data[ 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 back == -1 do back = id
|
||||
@ -98,6 +105,9 @@ pool_list_erase :: proc( pool : ^PoolList, iter : PoolListIter )
|
||||
|
||||
iter_node.prev = -1
|
||||
iter_node.next = -1
|
||||
// if pool.dbg_name != "" {
|
||||
// logf("pool_list: erased %v, at id %v", iter_node.value, iter)
|
||||
// }
|
||||
iter_node.value = 0
|
||||
append( & free_list, iter )
|
||||
|
||||
@ -115,34 +125,35 @@ pool_list_peek_back :: proc ( pool : ^PoolList ) -> PoolListValue {
|
||||
}
|
||||
|
||||
pool_list_pop_back :: proc( pool : ^PoolList ) -> PoolListValue {
|
||||
using pool
|
||||
if size <= 0 do return 0
|
||||
assert( back != -1 )
|
||||
if pool.size <= 0 do return 0
|
||||
assert( pool.back != -1 )
|
||||
|
||||
value := items.data[ back ].value
|
||||
pool_list_erase( pool, back )
|
||||
value := pool.items.data[ pool.back ].value
|
||||
pool_list_erase( pool, pool.back )
|
||||
return value
|
||||
}
|
||||
|
||||
LRU_Link :: struct {
|
||||
pad_top : u64,
|
||||
value : i32,
|
||||
ptr : PoolListIter,
|
||||
pad_bottom : u64,
|
||||
}
|
||||
|
||||
LRU_Cache :: struct {
|
||||
capacity : u32,
|
||||
num : u32,
|
||||
table : HMapZPL(LRU_Link),
|
||||
table : HMapChained(LRU_Link),
|
||||
key_queue : PoolList,
|
||||
}
|
||||
|
||||
LRU_init :: proc( cache : ^LRU_Cache, capacity : u32 ) {
|
||||
LRU_init :: proc( cache : ^LRU_Cache, capacity : u32, dbg_name : string = "" ) {
|
||||
error : AllocatorError
|
||||
cache.capacity = capacity
|
||||
cache.table, error = hmap_zpl_init( HMapZPL(LRU_Link), u64( hmap_closest_prime( uint(capacity))) )
|
||||
cache.table, error = make( HMapChained(LRU_Link), hmap_closest_prime( uint(capacity)) )
|
||||
assert( error == .None, "VEFontCache.LRU_init : Failed to allocate cache's table")
|
||||
|
||||
pool_list_init( & cache.key_queue, capacity )
|
||||
pool_list_init( & cache.key_queue, capacity, dbg_name = dbg_name )
|
||||
}
|
||||
|
||||
LRU_free :: proc( cache : ^LRU_Cache )
|
||||
@ -152,7 +163,7 @@ LRU_free :: proc( cache : ^LRU_Cache )
|
||||
|
||||
LRU_reload :: proc( cache : ^LRU_Cache, allocator : Allocator )
|
||||
{
|
||||
hmap_zpl_reload( & cache.table, allocator )
|
||||
hmap_chained_reload( cache.table, allocator )
|
||||
pool_list_reload( & cache.key_queue, allocator )
|
||||
}
|
||||
|
||||
@ -162,9 +173,13 @@ LRU_hash_key :: #force_inline proc( key : u64 ) -> ( hash : u64 ) {
|
||||
return
|
||||
}
|
||||
|
||||
LRU_find :: proc( cache : ^LRU_Cache, key : u64 ) -> ^LRU_Link {
|
||||
LRU_find :: proc( cache : ^LRU_Cache, key : u64, must_find := false ) -> ^LRU_Link {
|
||||
hash := LRU_hash_key( key )
|
||||
link := get( & cache.table, hash )
|
||||
link := get( cache.table, hash )
|
||||
// if link == nil && must_find {
|
||||
// runtime.debug_trap()
|
||||
// link = get( cache.table, hash )
|
||||
// }
|
||||
return link
|
||||
}
|
||||
|
||||
@ -186,8 +201,8 @@ LRU_get_next_evicted :: proc( cache : ^LRU_Cache ) -> u64
|
||||
return 0xFFFFFFFFFFFFFFFF
|
||||
}
|
||||
|
||||
LRU_peek :: proc( cache : ^LRU_Cache, key : u64 ) -> i32 {
|
||||
iter := LRU_find( cache, key )
|
||||
LRU_peek :: proc( cache : ^LRU_Cache, key : u64, must_find := false ) -> i32 {
|
||||
iter := LRU_find( cache, key, must_find )
|
||||
if iter == nil {
|
||||
return -1
|
||||
}
|
||||
@ -197,7 +212,7 @@ LRU_peek :: proc( cache : ^LRU_Cache, key : u64 ) -> i32 {
|
||||
LRU_put :: proc( cache : ^LRU_Cache, key : u64, value : i32 ) -> u64
|
||||
{
|
||||
hash_key := LRU_hash_key( key )
|
||||
iter := get( & cache.table, hash_key )
|
||||
iter := get( cache.table, hash_key )
|
||||
if iter != nil {
|
||||
LRU_refresh( cache, key )
|
||||
iter.value = value
|
||||
@ -209,14 +224,19 @@ LRU_put :: proc( cache : ^LRU_Cache, key : u64, value : i32 ) -> u64
|
||||
evict = pool_list_pop_back( & cache.key_queue )
|
||||
|
||||
evict_hash := LRU_hash_key( evict )
|
||||
hmap_zpl_remove( & cache.table, evict_hash )
|
||||
// if cache.table.dbg_name != "" {
|
||||
// logf("%v: Evicted %v with hash: %v", cache.table.dbg_name, evict, evict_hash)
|
||||
// }
|
||||
hmap_chained_remove( cache.table, evict_hash )
|
||||
cache.num -= 1
|
||||
}
|
||||
|
||||
pool_list_push_front( & cache.key_queue, key )
|
||||
// if cache.table.dbg_name != "" {
|
||||
// logf("%v: Pushed %v with hash: %v", cache.table.dbg_name, key, hash_key )
|
||||
// }
|
||||
|
||||
// set( cache.table, hash_key, LRU_Link {
|
||||
set( & cache.table, hash_key, LRU_Link {
|
||||
set( cache.table, hash_key, LRU_Link {
|
||||
value = value,
|
||||
ptr = cache.key_queue.front
|
||||
})
|
||||
@ -227,6 +247,9 @@ LRU_put :: proc( cache : ^LRU_Cache, key : u64, value : i32 ) -> u64
|
||||
|
||||
LRU_refresh :: proc( cache : ^LRU_Cache, key : u64 ) {
|
||||
link := LRU_find( cache, key )
|
||||
// if cache.table.dbg_name != "" {
|
||||
// logf("%v: Refreshed %v", cache.table.dbg_name, key)
|
||||
// }
|
||||
pool_list_erase( & cache.key_queue, link.ptr )
|
||||
pool_list_push_front( & cache.key_queue, key )
|
||||
link.ptr = cache.key_queue.front
|
||||
|
@ -15,6 +15,7 @@ Changes:
|
||||
*/
|
||||
package VEFontCache
|
||||
|
||||
import "base:runtime"
|
||||
import "core:math"
|
||||
import "core:mem"
|
||||
|
||||
@ -625,7 +626,7 @@ cache_glyph_to_atlas :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph
|
||||
next_evict_codepoint := LRU_get_next_evicted( & region.state )
|
||||
assert( next_evict_codepoint != 0xFFFFFFFFFFFFFFFF )
|
||||
|
||||
atlas_index = LRU_peek( & region.state, next_evict_codepoint )
|
||||
atlas_index = LRU_peek( & region.state, next_evict_codepoint, must_find = true )
|
||||
assert( atlas_index != -1 )
|
||||
|
||||
evicted := LRU_put( & region.state, lru_code, atlas_index )
|
||||
@ -763,16 +764,17 @@ shape_text_cached :: proc( ctx : ^Context, font : FontID, text_utf8 : string ) -
|
||||
if shape_cache_idx == -1
|
||||
{
|
||||
if shape_cache.next_cache_id < i32(state.capacity) {
|
||||
shape_cache_idx = shape_cache.next_cache_id
|
||||
LRU_put( state, hash, shape_cache_idx )
|
||||
shape_cache_idx = shape_cache.next_cache_id
|
||||
shape_cache.next_cache_id += 1
|
||||
evicted := LRU_put( state, hash, shape_cache_idx )
|
||||
assert( evicted == hash )
|
||||
}
|
||||
else
|
||||
{
|
||||
next_evict_idx := LRU_get_next_evicted( state )
|
||||
assert( next_evict_idx != 0xFFFFFFFFFFFFFFFF )
|
||||
|
||||
shape_cache_idx = LRU_peek( state, next_evict_idx )
|
||||
shape_cache_idx = LRU_peek( state, next_evict_idx, must_find = true )
|
||||
assert( shape_cache_idx != - 1 )
|
||||
|
||||
LRU_put( state, hash, shape_cache_idx )
|
||||
|
@ -8,6 +8,8 @@ import "core:mem"
|
||||
|
||||
Kilobyte :: mem.Kilobyte
|
||||
|
||||
slice_ptr :: mem.slice_ptr
|
||||
|
||||
Arena :: mem.Arena
|
||||
|
||||
arena_allocator :: mem.arena_allocator
|
||||
@ -46,6 +48,7 @@ hmap_chained_destroy :: grime.hmap_chained_destroy
|
||||
hmap_chained_init :: grime.hmap_chained_init
|
||||
hmap_chained_get :: grime.hmap_chained_get
|
||||
hmap_chained_remove :: grime.hmap_chained_remove
|
||||
hmap_chained_reload :: grime.hmap_chained_reload
|
||||
hmap_chained_set :: grime.hmap_chained_set
|
||||
hmap_closest_prime :: grime.hmap_closest_prime
|
||||
|
||||
|
@ -13,8 +13,8 @@ and direct pointers are kept across the codebase instead of a key to the slot.
|
||||
*/
|
||||
package grime
|
||||
|
||||
import "core:mem"
|
||||
import "base:runtime"
|
||||
import "core:mem"
|
||||
|
||||
HTable_Minimum_Capacity :: 4 * Kilobyte
|
||||
|
||||
@ -26,6 +26,7 @@ HMapChainedSlot :: struct( $Type : typeid ) {
|
||||
}
|
||||
|
||||
HMapChainedHeader :: struct( $ Type : typeid ) {
|
||||
tracker : MemoryTracker,
|
||||
pool : Pool,
|
||||
lookup : [] ^HMapChainedSlot(Type),
|
||||
dbg_name : string,
|
||||
@ -62,7 +63,7 @@ hmap_chained_init :: proc( $HMapChainedType : typeid/HMapChained($Type), lookup_
|
||||
) -> (table : HMapChained(Type), error : AllocatorError)
|
||||
{
|
||||
header_size := size_of(HMapChainedHeader(Type))
|
||||
size := header_size + int(lookup_capacity) * size_of( ^HMapChainedSlot(Type)) + size_of(int)
|
||||
size := header_size + int(lookup_capacity) * size_of( ^HMapChainedSlot(Type))
|
||||
|
||||
raw_mem : rawptr
|
||||
raw_mem, error = alloc( size, allocator = allocator )
|
||||
@ -79,9 +80,14 @@ hmap_chained_init :: proc( $HMapChainedType : typeid/HMapChained($Type), lookup_
|
||||
dbg_name = str_intern(str_fmt("%v: pool", dbg_name)).str,
|
||||
enable_mem_tracking = enable_mem_tracking,
|
||||
)
|
||||
data := transmute([^] ^HMapChainedSlot(Type)) (transmute( [^]HMapChainedHeader(Type)) table.header)[1:]
|
||||
data := transmute(^^HMapChainedSlot(Type)) memory_after_header(table.header)
|
||||
table.lookup = slice_ptr( data, int(lookup_capacity) )
|
||||
table.dbg_name = dbg_name
|
||||
|
||||
if Track_Memory && enable_mem_tracking {
|
||||
memtracker_init( & table.tracker, allocator, Kilobyte * 16, dbg_name )
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -115,9 +121,6 @@ hmap_chained_get :: proc( using self : HMapChained($Type), key : u64) -> ^Type
|
||||
{
|
||||
// profile(#procedure)
|
||||
hash_index := hmap_chained_lookup_id(self, key)
|
||||
// if hash_index == 565 {
|
||||
// runtime.debug_trap()
|
||||
// }
|
||||
surface_slot := lookup[hash_index]
|
||||
|
||||
if surface_slot == nil {
|
||||
@ -128,9 +131,13 @@ hmap_chained_get :: proc( using self : HMapChained($Type), key : u64) -> ^Type
|
||||
return & surface_slot.value
|
||||
}
|
||||
|
||||
for slot := surface_slot.next; slot != nil; slot = slot.next {
|
||||
for slot := surface_slot.next; slot != nil; slot = slot.next
|
||||
{
|
||||
if slot.occupied && slot.key == key {
|
||||
return & surface_slot.value
|
||||
if self.dbg_name != "" && self.tracker.entries.header != nil {
|
||||
logf( "%v: Retrieved %v in lookup[%v] which shows key as %v", self.dbg_name, key, hash_index, slot.key )
|
||||
}
|
||||
return & slot.value
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,14 +146,15 @@ hmap_chained_get :: proc( using self : HMapChained($Type), key : u64) -> ^Type
|
||||
|
||||
hmap_chained_reload :: proc( self : HMapChained($Type), allocator : Allocator )
|
||||
{
|
||||
pool_reload(self.pool, allocator)
|
||||
// pool_reload(self.pool, allocator)
|
||||
}
|
||||
|
||||
// Returns true if an slot was actually found and marked as vacant
|
||||
// Entries already found to be vacant will not return true
|
||||
hmap_chained_remove :: proc( self : HMapChained($Type), key : u64 ) -> b32
|
||||
{
|
||||
surface_slot := self.lookup[hmap_chained_lookup_id(self, key)]
|
||||
hash_index := hmap_chained_lookup_id(self, key)
|
||||
surface_slot := self.lookup[hash_index]
|
||||
|
||||
if surface_slot == nil {
|
||||
return false
|
||||
@ -154,13 +162,24 @@ hmap_chained_remove :: proc( self : HMapChained($Type), key : u64 ) -> b32
|
||||
|
||||
if surface_slot.occupied && surface_slot.key == key {
|
||||
surface_slot.occupied = false
|
||||
surface_slot.value = {}
|
||||
surface_slot.key = {}
|
||||
if self.dbg_name != "" && self.tracker.entries.header != nil {
|
||||
logf( "%v: Removed %v in lookup[%v]", self.dbg_name, key, hash_index )
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
for slot := surface_slot.next; slot != nil; slot = slot.next
|
||||
nest_id : i32 = 1
|
||||
for slot := surface_slot.next; slot != nil; slot = slot.next
|
||||
{
|
||||
if slot.occupied && slot.key == key {
|
||||
slot.occupied = false
|
||||
slot.value = {}
|
||||
slot.key = {}
|
||||
if self.dbg_name != "" && self.tracker.entries.header != nil {
|
||||
logf( "%v: Removed %v in lookup[%v] nest_id: %v", self.dbg_name, key, hash_index, nest_id )
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -176,62 +195,69 @@ hmap_chained_set :: proc( self : HMapChained($Type), key : u64, value : Type ) -
|
||||
using self
|
||||
hash_index := hmap_chained_lookup_id(self, key)
|
||||
surface_slot := lookup[hash_index]
|
||||
set_slot :: #force_inline proc( using self : HMapChained(Type),
|
||||
slot : ^HMapChainedSlot(Type),
|
||||
key : u64,
|
||||
value : Type
|
||||
) -> (^ Type, AllocatorError )
|
||||
{
|
||||
error := AllocatorError.None
|
||||
if slot.next == nil {
|
||||
block : []byte
|
||||
block, error = pool_grab(pool, false)
|
||||
next := transmute( ^HMapChainedSlot(Type)) & block[0]
|
||||
next^ = {}
|
||||
slot.next = next
|
||||
next.prev = slot
|
||||
}
|
||||
slot.key = key
|
||||
slot.value = value
|
||||
slot.occupied = true
|
||||
return & slot.value, error
|
||||
}
|
||||
|
||||
if surface_slot == nil {
|
||||
block, error := pool_grab(pool, false)
|
||||
surface_slot := transmute( ^HMapChainedSlot(Type)) & block[0]
|
||||
slot_size := size_of(HMapChainedSlot(Type))
|
||||
if surface_slot == nil
|
||||
{
|
||||
block, error := pool_grab(pool, false)
|
||||
surface_slot := transmute( ^HMapChainedSlot(Type)) raw_data(block)
|
||||
surface_slot^ = {}
|
||||
|
||||
surface_slot.key = key
|
||||
surface_slot.value = value
|
||||
surface_slot.occupied = true
|
||||
if error != AllocatorError.None {
|
||||
ensure(error != AllocatorError.None, "Allocation failure for chained slot in hash table")
|
||||
return nil, error
|
||||
}
|
||||
|
||||
lookup[hash_index] = surface_slot
|
||||
|
||||
block, error = pool_grab(pool, false)
|
||||
next := transmute( ^HMapChainedSlot(Type)) & block[0]
|
||||
next^ = {}
|
||||
surface_slot.next = next
|
||||
next.prev = surface_slot
|
||||
if Track_Memory && tracker.entries.header != nil {
|
||||
memtracker_register_auto_name_slice( & self.tracker, block)
|
||||
}
|
||||
return & surface_slot.value, error
|
||||
}
|
||||
|
||||
if ! surface_slot.occupied
|
||||
{
|
||||
result, error := set_slot( self, surface_slot, key, value)
|
||||
return result, error
|
||||
surface_slot.key = key
|
||||
surface_slot.value = value
|
||||
surface_slot.occupied = true
|
||||
if dbg_name != "" && tracker.entries.header != nil {
|
||||
logf( "%v: Set %v in lookup[%v]", self.dbg_name, key, hash_index )
|
||||
}
|
||||
|
||||
return & surface_slot.value, .None
|
||||
}
|
||||
|
||||
slot : ^HMapChainedSlot(Type) = surface_slot.next
|
||||
for ; slot != nil; slot = slot.next
|
||||
slot : ^HMapChainedSlot(Type) = surface_slot
|
||||
nest_id : i32 = 1
|
||||
for ;; slot = slot.next
|
||||
{
|
||||
if !slot.occupied
|
||||
error : AllocatorError
|
||||
if slot.next == nil
|
||||
{
|
||||
result, error := set_slot( self, slot, key, value)
|
||||
return result, error
|
||||
block : []byte
|
||||
block, error = pool_grab(pool, false)
|
||||
next := transmute( ^HMapChainedSlot(Type)) raw_data(block)
|
||||
|
||||
slot.next = next
|
||||
slot.next^ = {}
|
||||
slot.next.prev = slot
|
||||
if Track_Memory && tracker.entries.header != nil {
|
||||
memtracker_register_auto_name_slice( & self.tracker, block)
|
||||
}
|
||||
}
|
||||
|
||||
if ! slot.next.occupied
|
||||
{
|
||||
slot.next.key = key
|
||||
slot.next.value = value
|
||||
slot.next.occupied = true
|
||||
if dbg_name != "" && tracker.entries.header != nil {
|
||||
logf( "%v: Set %v in lookup[%v] nest_id: %v", self.dbg_name, key, hash_index, nest_id )
|
||||
}
|
||||
return & slot.next.value, .None
|
||||
}
|
||||
|
||||
nest_id += 1
|
||||
}
|
||||
ensure(false, "Somehow got to a null slot that wasn't preemptively allocated from a previus set")
|
||||
return nil, AllocatorError.None
|
||||
|
@ -276,7 +276,7 @@ varena_allocator_proc :: proc(
|
||||
data = new_region
|
||||
// log( str_fmt_tmp("varena resize (new): old: %p %v new: %p %v", old_memory, old_size, (& data[0]), size))
|
||||
|
||||
when Track_Memory {
|
||||
if Track_Memory && arena.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & arena.tracker, & data[0], & data[len(data) - 1] )
|
||||
}
|
||||
return
|
||||
|
@ -128,9 +128,9 @@ setup_memory :: proc( profiler : ^SpallProfiler ) -> ClientMemory
|
||||
sectr.Memory_Reserve_Persistent,
|
||||
sectr.Memory_Commit_Initial_Persistent,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = false,
|
||||
allow_any_resize = true,
|
||||
dbg_name = "persistent",
|
||||
enable_mem_tracking = true )
|
||||
enable_mem_tracking = false )
|
||||
verify( alloc_error == .None, "Failed to allocate persistent virtual arena for the sectr module")
|
||||
|
||||
frame, alloc_error = varena_init(
|
||||
|
@ -92,7 +92,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
// push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
|
||||
|
||||
alloc_error : AllocatorError
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator(), dbg_name = Persistent_Slab_DBG_Name, enable_mem_tracking = true )
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator(), dbg_name = Persistent_Slab_DBG_Name, enable_mem_tracking = false )
|
||||
verify( alloc_error == .None, "Failed to allocate the persistent slab" )
|
||||
|
||||
transient_slab, alloc_error = slab_init( & default_slab_policy, allocator = transient_allocator(), dbg_name = Transient_Slab_DBG_Name )
|
||||
@ -254,23 +254,23 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
if true
|
||||
{
|
||||
font_provider_startup()
|
||||
// path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" })
|
||||
// font_rec_mono_semicasual_reg = font_load( path_rec_mono_semicasual_reg, 24.0, "RecMonoSemiCasual_Regular" )
|
||||
path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" })
|
||||
font_rec_mono_semicasual_reg = font_load( path_rec_mono_semicasual_reg, 24.0, "RecMonoSemiCasual_Regular" )
|
||||
|
||||
// path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } )
|
||||
// font_squidgy_slimes = font_load( path_squidgy_slimes, 24.0, "Squidgy_Slime" )
|
||||
path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } )
|
||||
font_squidgy_slimes = font_load( path_squidgy_slimes, 24.0, "Squidgy_Slime" )
|
||||
|
||||
path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } )
|
||||
font_firacode = font_load( path_firacode, 24.0, "FiraCode" )
|
||||
|
||||
// path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } )
|
||||
// font_open_sans = font_load( path_open_sans, 24.0, "OpenSans" )
|
||||
path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } )
|
||||
font_open_sans = font_load( path_open_sans, 24.0, "OpenSans" )
|
||||
|
||||
// path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } )
|
||||
// font_noto_sans = font_load( path_noto_sans, 24.0, "NotoSans" )
|
||||
path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } )
|
||||
font_noto_sans = font_load( path_noto_sans, 24.0, "NotoSans" )
|
||||
|
||||
// path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } )
|
||||
// font_arial_unicode_ms = font_load( path_arial_unicode_ms, 24.0, "Arial_Unicode_MS" )
|
||||
path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } )
|
||||
font_arial_unicode_ms = font_load( path_arial_unicode_ms, 24.0, "Arial_Unicode_MS" )
|
||||
|
||||
default_font = font_firacode
|
||||
log( "Default font loaded" )
|
||||
|
@ -125,7 +125,7 @@ render_mode_screenspace :: proc()
|
||||
debug.debug_text_vis = true
|
||||
if debug.debug_text_vis
|
||||
{
|
||||
fps_msg := str_fmt( "FPS: %0.2f", fps_avg)
|
||||
fps_msg := str_fmt( "FPS: %d", frame)
|
||||
fps_msg_width := measure_text_size( fps_msg, default_font, 12.0, 0.0 ).x
|
||||
fps_msg_pos := screen_get_corners().top_right - { fps_msg_width, 0 } - { 5, 5 }
|
||||
debug_draw_text( fps_msg, fps_msg_pos, 38.0, color = Color_Red )
|
||||
@ -133,7 +133,7 @@ render_mode_screenspace :: proc()
|
||||
// debug_text( "Screen Width : %v", rl.GetScreenWidth () )
|
||||
// debug_text( "Screen Height: %v", rl.GetScreenHeight() )
|
||||
// debug_text( "frametime_target_ms : %f ms", frametime_target_ms )
|
||||
debug_text( "frametime : %f ms", frametime_delta_ms )
|
||||
debug_text( "frametime : %d ms", frame )
|
||||
// debug_text( "frametime_last_elapsed_ms : %f ms", frametime_elapsed_ms )
|
||||
if replay.mode == ReplayMode.Record {
|
||||
debug_text( "Recording Input")
|
||||
|
@ -70,10 +70,10 @@ font_provider_startup :: proc()
|
||||
provider_data := & state.font_provider_data; using provider_data
|
||||
|
||||
error : AllocatorError
|
||||
font_cache, error = make( HMapChained(FontDef), hmap_closest_prime(1 * Kilo), persistent_allocator() /*dbg_name = "font_cache"*/ )
|
||||
font_cache, error = make( HMapChained(FontDef), hmap_closest_prime(1 * Kilo), persistent_allocator(), dbg_name = "font_cache" )
|
||||
verify( error == AllocatorError.None, "Failed to allocate font_cache" )
|
||||
|
||||
ve.init( & provider_data.ve_font_cache, .STB_TrueType, allocator = persistent_slab_allocator() )
|
||||
ve.init( & provider_data.ve_font_cache, .STB_TrueType, allocator = persistent_allocator() )
|
||||
log("VEFontCached initialized")
|
||||
|
||||
ve.configure_snap( & provider_data.ve_font_cache, u32(state.app_window.extent.x * 2.0), u32(state.app_window.extent.y * 2.0) )
|
||||
@ -552,7 +552,7 @@ font_load :: proc(path_file : string,
|
||||
|
||||
for font_size : i32 = Font_Size_Interval; font_size <= Font_Largest_Px_Size; font_size += Font_Size_Interval
|
||||
{
|
||||
logf("Loading at size %v", font_size)
|
||||
// logf("Loading at size %v", font_size)
|
||||
id := (font_size / Font_Size_Interval) + (font_size % Font_Size_Interval)
|
||||
ve_id := & def.size_table[id - 1]
|
||||
ve_id^ = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, 14.0 )
|
||||
|
Loading…
Reference in New Issue
Block a user