misc changes
* draw_text_string_pos_extent_zoomed can now oversample text futher (if desired) * render_ui_via_box_tree has a rudimentary render pass layering optimization Add support for the slab allocator to accept arbitrary alignments (odin's map container needs it) Messing around with 64-byte alignment as the default for the allocator...
This commit is contained in:
parent
268ba29ec6
commit
1533a14a1b
@ -181,12 +181,12 @@ array_append_at_slice :: proc( using self : ^Array( $ Type ), items : []Type, id
|
||||
return AllocatorError.None
|
||||
}
|
||||
|
||||
array_back :: proc( self : Array($Type) ) -> Type {
|
||||
array_back :: #force_inline proc "contextless" ( self : Array($Type) ) -> Type {
|
||||
value := self.data[self.num - 1]
|
||||
return value
|
||||
}
|
||||
|
||||
array_push_back :: proc( using self : Array( $ Type)) -> b32 {
|
||||
array_push_back :: #force_inline proc "contextless" ( using self : Array( $ Type)) -> b32 {
|
||||
if num == capacity {
|
||||
return false
|
||||
}
|
||||
|
@ -3,16 +3,16 @@ package grime
|
||||
import "base:runtime"
|
||||
|
||||
reload_array :: proc( self : ^[dynamic]$Type, allocator : Allocator ) {
|
||||
raw := transmute(runtime.Raw_Dynamic_Array) self
|
||||
raw := transmute( ^runtime.Raw_Dynamic_Array) self
|
||||
raw.allocator = allocator
|
||||
}
|
||||
|
||||
reload_queue :: proc( self : ^Queue($Type), allocator : Allocator ) {
|
||||
raw_array := transmute(runtime.Raw_Dynamic_Array) self.data
|
||||
raw_array := transmute( ^runtime.Raw_Dynamic_Array) self.data
|
||||
raw_array.allocator = allocator
|
||||
}
|
||||
|
||||
reload_map :: proc( self : ^map [$KeyType] $EntryType, allocator : Allocator ) {
|
||||
raw := transmute(runtime.Raw_Map) self
|
||||
raw := transmute( ^runtime.Raw_Map) self
|
||||
raw.allocator = allocator
|
||||
}
|
||||
|
@ -87,6 +87,11 @@ memory_aign_forward :: #force_inline proc( address, alignment : uintptr) -> uint
|
||||
return aligned_address
|
||||
}
|
||||
|
||||
|
||||
// align_up :: proc(address: uintptr, alignment: uintptr) -> uintptr {
|
||||
// return (address + alignment - 1) & ~(alignment - 1)
|
||||
// }
|
||||
|
||||
//endregion Memory Math
|
||||
|
||||
swap :: #force_inline proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) { return b, a }
|
||||
|
@ -353,11 +353,12 @@ pool_validate_ownership :: proc( using self : Pool, block : [] byte ) -> b32
|
||||
{
|
||||
misalignment := (block_address - start) % uintptr(block_size)
|
||||
if misalignment != 0 {
|
||||
ensure(false, "pool_validate_ownership: This data is within this pool's buckets, however its not aligned to the start of a block")
|
||||
log(str_fmt("Block address: %p Misalignment: %p closest: %p",
|
||||
transmute(rawptr)block_address,
|
||||
transmute(rawptr)misalignment,
|
||||
rawptr(block_address - misalignment)))
|
||||
// TODO(Ed): We cannot use thsi to validate that the data is within the pool bucket as we can provide the user different alignments
|
||||
// ensure(false, "pool_validate_ownership: This data is within this pool's buckets, however its not aligned to the start of a block")
|
||||
// log(str_fmt("Block address: %p Misalignment: %p closest: %p",
|
||||
// transmute(rawptr)block_address,
|
||||
// transmute(rawptr)misalignment,
|
||||
// rawptr(block_address - misalignment)))
|
||||
}
|
||||
|
||||
within_bucket = true
|
||||
|
@ -17,13 +17,13 @@ set_profiler_module_context :: #force_inline proc "contextless" ( ctx : ^SpallPr
|
||||
|
||||
@(deferred_none = profile_end)
|
||||
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
// spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
// spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_end :: #force_inline proc "contextless" () {
|
||||
spall._buffer_end( & Module_Context.ctx, & Module_Context.buffer)
|
||||
// spall._buffer_end( & Module_Context.ctx, & Module_Context.buffer)
|
||||
}
|
||||
|
@ -129,19 +129,24 @@ slab_alloc :: proc( self : Slab,
|
||||
loc := #caller_location
|
||||
) -> ( data : []byte, alloc_error : AllocatorError )
|
||||
{
|
||||
|
||||
// profile(#procedure)
|
||||
pool : Pool
|
||||
id : u32 = 0
|
||||
for ; id < self.pools.idx; id += 1 {
|
||||
pool = self.pools.items[id]
|
||||
|
||||
if pool.block_size >= size && pool.alignment >= alignment {
|
||||
adjusted_alignment := clamp(alignment, pool.alignment, alignment)
|
||||
aligned_size := size + (adjusted_alignment - 1)
|
||||
if pool.block_size >= aligned_size {
|
||||
break
|
||||
}
|
||||
}
|
||||
verify( id < self.pools.idx, "There is not a size class in the slab's policy to satisfy the requested allocation", location = loc )
|
||||
verify( pool.header != nil, "Requested alloc not supported by the slab allocator", location = loc )
|
||||
|
||||
adjusted_alignment := clamp(alignment, pool.alignment, alignment)
|
||||
|
||||
block : []byte
|
||||
slab_validate_pools( self )
|
||||
block, alloc_error = pool_grab(pool)
|
||||
@ -153,7 +158,11 @@ slab_alloc :: proc( self : Slab,
|
||||
}
|
||||
// log( str_fmt_tmp("%v: Retrieved block: %p %d", self.dbg_name, raw_data(block), len(block) ))
|
||||
|
||||
data = byte_slice(raw_data(block), size)
|
||||
// Align the block
|
||||
block_start := uintptr(raw_data(block))
|
||||
aligned_start := memory_aign_forward(block_start, uintptr(adjusted_alignment))
|
||||
|
||||
data = byte_slice(transmute(rawptr) aligned_start, size)
|
||||
if zero_memory {
|
||||
slice.zero(data)
|
||||
}
|
||||
|
@ -39,14 +39,15 @@ Module_String_Cache : ^StringCache
|
||||
|
||||
str_cache_init :: proc( table_allocator, slabs_allocator : Allocator ) -> (cache : StringCache)
|
||||
{
|
||||
alignment := uint(mem.DEFAULT_ALIGNMENT)
|
||||
// alignment := uint(mem.DEFAULT_ALIGNMENT)
|
||||
alignment := uint(64)
|
||||
|
||||
policy : SlabPolicy
|
||||
policy_ptr := & policy
|
||||
push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 8, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 16, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 32, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 64, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 8, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 16, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 32, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 640 * Kilobyte, 64, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 128, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 256, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Kilobyte, 512, alignment })
|
||||
|
@ -154,11 +154,14 @@ AppConfig :: struct {
|
||||
|
||||
engine_refresh_hz : uint,
|
||||
|
||||
|
||||
timing_fps_moving_avg_alpha : f32,
|
||||
|
||||
ui_resize_border_width : f32,
|
||||
|
||||
color_theme : AppColorTheme,
|
||||
|
||||
font_size_canvas_scalar : f32,
|
||||
}
|
||||
|
||||
AppWindow :: struct {
|
||||
|
@ -68,7 +68,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
|
||||
// Setup Persistent Slabs & String Cache
|
||||
{
|
||||
alignment := uint(mem.DEFAULT_ALIGNMENT)
|
||||
// alignment := uint(mem.DEFAULT_ALIGNMENT)
|
||||
alignment := uint(64) // Doing the cache line
|
||||
|
||||
policy_ptr := & default_slab_policy
|
||||
push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 1 * Kilobyte, alignment })
|
||||
@ -150,6 +151,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
ui_resize_border_width = 5
|
||||
|
||||
color_theme = App_Thm_Dusk
|
||||
|
||||
font_size_canvas_scalar = 2.0
|
||||
}
|
||||
|
||||
Desired_OS_Scheduler_MS :: 1
|
||||
@ -325,8 +328,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
ui_startup( & workspace.ui, cache_allocator = persistent_slab_allocator() )
|
||||
}
|
||||
|
||||
debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (197).txt", allocator = persistent_slab_allocator())
|
||||
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (1022).txt", allocator = persistent_slab_allocator())
|
||||
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (197).txt", allocator = persistent_slab_allocator())
|
||||
debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (1022).txt", allocator = persistent_slab_allocator())
|
||||
|
||||
alloc_error : AllocatorError; success : bool
|
||||
debug.lorem_content, success = os.read_entire_file( debug.path_lorem, persistent_slab_allocator() )
|
||||
|
@ -182,16 +182,17 @@ render_mode_screenspace :: proc()
|
||||
screen_corners := screen_get_corners()
|
||||
|
||||
position := screen_corners.top_left
|
||||
position.x += 2
|
||||
position.y -= debug.draw_debug_text_y
|
||||
|
||||
content := str_fmt( format, ..args )
|
||||
text_size := measure_text_size( content, default_font, 14.0, 0.0 )
|
||||
debug_draw_text( content, position, 14.0 )
|
||||
debug.draw_debug_text_y += text_size.y + 4
|
||||
debug.draw_debug_text_y += text_size.y + 3
|
||||
}
|
||||
|
||||
profile("debug_text_vis")
|
||||
fps_size : f32 = 16.0
|
||||
fps_size : f32 = 14.0
|
||||
fps_msg := str_fmt( "FPS: %0.2f", fps_avg)
|
||||
fps_msg_size := measure_text_size( fps_msg, default_font, fps_size, 0.0 )
|
||||
fps_msg_pos := screen_get_corners().top_right - { fps_msg_size.x, fps_msg_size.y }
|
||||
@ -218,7 +219,7 @@ render_mode_screenspace :: proc()
|
||||
iter_obj := iterator( & mouse_events ); iter := & iter_obj
|
||||
for event := next( iter ); event != nil; event = next( iter )
|
||||
{
|
||||
if id >= 4 do break
|
||||
if id >= 2 do break
|
||||
id += 1
|
||||
|
||||
debug_text("Mouse Event: %v", event )
|
||||
@ -227,10 +228,10 @@ render_mode_screenspace :: proc()
|
||||
|
||||
if debug.mouse_vis {
|
||||
debug_text("Mouse scroll: %v", input.mouse.scroll )
|
||||
debug_text("Mouse Delta : %v", input.mouse.delta )
|
||||
debug_text("Mouse Position (Render) : %v", input.mouse.raw_pos )
|
||||
debug_text("Mouse Position (Screen) : %v", input.mouse.pos )
|
||||
debug_text("Mouse Position (Workspace View): %v", screen_to_ws_view_pos(input.mouse.pos) )
|
||||
debug_text("Mouse Delta : %0.2f", input.mouse.delta )
|
||||
debug_text("Mouse Position (Render) : %0.2f", input.mouse.raw_pos )
|
||||
debug_text("Mouse Position (Screen) : %0.2f", input.mouse.pos )
|
||||
debug_text("Mouse Position (Workspace View): %0.2f", screen_to_ws_view_pos(input.mouse.pos) )
|
||||
}
|
||||
|
||||
if true
|
||||
@ -269,6 +270,15 @@ render_mode_screenspace :: proc()
|
||||
}
|
||||
}
|
||||
|
||||
if true {
|
||||
state.config.font_size_canvas_scalar = 1.0
|
||||
zoom_adjust_size := 16 * state.project.workspace.cam.zoom
|
||||
over_sample := zoom_adjust_size < 12 ? 1.0 : f32(state.config.font_size_canvas_scalar)
|
||||
debug_text("font_size_canvas_scalar: %v", config.font_size_canvas_scalar)
|
||||
ve_id, resolved_size := font_provider_resolve_draw_id( default_font, zoom_adjust_size * over_sample )
|
||||
debug_text("font_size resolved: %v px", resolved_size)
|
||||
}
|
||||
|
||||
render_text_layer()
|
||||
}
|
||||
|
||||
@ -492,10 +502,18 @@ render_ui_via_box_tree :: proc( root : ^UI_Box, cam : ^Camera = nil )
|
||||
cam_zoom_ratio := cam != nil ? 1.0 / cam.zoom : 1.0
|
||||
circle_radius := cam != nil ? cam_zoom_ratio * 3 : 3
|
||||
|
||||
text_enqueued : b32 = false
|
||||
shape_enqueued : b32 = false
|
||||
|
||||
previous_layer : i32 = 0
|
||||
for box := root.first; box != nil; box = ui_box_tranverse_next_depth_based( box )
|
||||
{
|
||||
text_enqueued : b32 = false
|
||||
shape_enqueued : b32 = false
|
||||
if box.ancestors != previous_layer {
|
||||
if shape_enqueued do render_flush_gp()
|
||||
if text_enqueued do render_text_layer()
|
||||
shape_enqueued = false
|
||||
text_enqueued = false
|
||||
}
|
||||
|
||||
border_width := box.layout.border_width
|
||||
computed := box.computed
|
||||
@ -509,7 +527,7 @@ render_ui_via_box_tree :: proc( root : ^UI_Box, cam : ^Camera = nil )
|
||||
|
||||
GP_Render:
|
||||
{
|
||||
// profile("draw_shapes")
|
||||
profile("draw_shapes")
|
||||
if style.bg_color.a != 0
|
||||
{
|
||||
draw_rect( bounds, style.bg_color )
|
||||
@ -555,9 +573,11 @@ render_ui_via_box_tree :: proc( root : ^UI_Box, cam : ^Camera = nil )
|
||||
text_enqueued = true
|
||||
}
|
||||
|
||||
if shape_enqueued do render_flush_gp()
|
||||
if text_enqueued do render_text_layer()
|
||||
previous_layer = box.ancestors
|
||||
}
|
||||
|
||||
if shape_enqueued do render_flush_gp()
|
||||
if text_enqueued do render_text_layer()
|
||||
}
|
||||
|
||||
render_ui_via_box_list :: proc( render_list : []UI_RenderBoxInfo, cam : ^Camera = nil )
|
||||
@ -693,7 +713,7 @@ draw_text_string_pos_norm :: proc( content : string, id : FontID, size : f32, po
|
||||
// Draw text using a string and extent-based screen coordinates
|
||||
draw_text_string_pos_extent :: proc( content : string, id : FontID, size : f32, pos : Vec2, color := Color_White )
|
||||
{
|
||||
// profile(#procedure)
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
screen_size := app_window.extent * 2
|
||||
render_pos := screen_to_render_pos(pos)
|
||||
@ -703,9 +723,9 @@ draw_text_string_pos_extent :: proc( content : string, id : FontID, size : f32,
|
||||
|
||||
draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size : f32, pos : Vec2, cam : Camera, color := Color_White )
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
|
||||
// profile(#procedure)
|
||||
cam_offset := Vec2 {
|
||||
cam.position.x,
|
||||
cam.position.y,
|
||||
@ -719,10 +739,10 @@ draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size
|
||||
render_pos := ws_view_to_render_pos(pos)
|
||||
normalized_pos := render_pos * screen_scale
|
||||
|
||||
// Oversample font-size for any render under a camera
|
||||
over_sample : f32 = 2.0
|
||||
|
||||
zoom_adjust_size := size * cam.zoom
|
||||
|
||||
// Over-sample font-size for any render under a camera
|
||||
over_sample : f32 = zoom_adjust_size < 12 ? 1.0 : f32(state.config.font_size_canvas_scalar)
|
||||
zoom_adjust_size *= over_sample
|
||||
|
||||
ve_id, resolved_size := font_provider_resolve_draw_id( id, zoom_adjust_size )
|
||||
@ -737,7 +757,7 @@ draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size
|
||||
text_scale.y = clamp( text_scale.y, 0, screen_size.y )
|
||||
}
|
||||
|
||||
// Downsample back
|
||||
// Down-sample back
|
||||
text_scale /= over_sample
|
||||
|
||||
color_norm := normalize_rgba8(color)
|
||||
@ -749,6 +769,7 @@ draw_text_string_pos_extent_zoomed :: proc( content : string, id : FontID, size
|
||||
|
||||
render_flush_gp :: #force_inline proc()
|
||||
{
|
||||
profile(#procedure)
|
||||
gfx.begin_pass( gfx.Pass { action = get_state().render_data.pass_actions.empty_action, swapchain = sokol_glue.swapchain() })
|
||||
gp.flush()
|
||||
gfx.end_pass()
|
||||
|
@ -165,10 +165,10 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
}
|
||||
|
||||
config.cam_max_zoom = 10
|
||||
config.cam_min_zoom = 0.10
|
||||
config.cam_min_zoom = 0.05
|
||||
config.cam_zoom_sensitivity_digital = 0.05
|
||||
config.cam_zoom_sensitivity_smooth = 2.0
|
||||
config.cam_zoom_mode = .Digital
|
||||
config.cam_zoom_mode = .Smooth
|
||||
switch config.cam_zoom_mode
|
||||
{
|
||||
case .Smooth:
|
||||
@ -247,9 +247,9 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
config.ui_resize_border_width = 2.5
|
||||
// test_hover_n_click()
|
||||
// test_draggable()
|
||||
test_text_box()
|
||||
// test_text_box()
|
||||
// test_parenting( & default_layout, & frame_style_default )
|
||||
// test_whitespace_ast( & default_layout, & frame_style_default )
|
||||
test_whitespace_ast( & default_layout, & frame_style_default )
|
||||
}
|
||||
//endregion Workspace Imgui Tick
|
||||
|
||||
|
@ -8,7 +8,7 @@ import sokol_glue "thirdparty:sokol/glue"
|
||||
|
||||
|
||||
Font_Provider_Use_Freetype :: false
|
||||
Font_Largest_Px_Size :: 110
|
||||
Font_Largest_Px_Size :: 172
|
||||
Font_Size_Interval :: 2
|
||||
|
||||
Font_Default :: FontID { 0, "" }
|
||||
@ -119,14 +119,14 @@ font_provider_startup :: proc()
|
||||
screen_shader = sokol_gfx.make_shader(ve_draw_text_shader_desc(backend) )
|
||||
|
||||
draw_list_vbuf = sokol_gfx.make_buffer( BufferDesciption {
|
||||
size = size_of([4]f32) * Kilo * 512,
|
||||
size = size_of([4]f32) * Kilo * 1024,
|
||||
usage = BufferUsage.STREAM,
|
||||
type = BufferType.VERTEXBUFFER,
|
||||
})
|
||||
verify( sokol_gfx.query_buffer_state( draw_list_vbuf) < ResourceState.FAILED, "Failed to make draw_list_vbuf" )
|
||||
|
||||
draw_list_ibuf = sokol_gfx.make_buffer( BufferDesciption {
|
||||
size = size_of(u32) * Kilo * 256,
|
||||
size = size_of(u32) * Kilo * 512,
|
||||
usage = BufferUsage.STREAM,
|
||||
type = BufferType.INDEXBUFFER,
|
||||
})
|
||||
@ -563,7 +563,7 @@ font_load :: proc(path_file : string,
|
||||
def.path_file = path_file
|
||||
def.default_size = default_size
|
||||
|
||||
for font_size : i32 = Font_Size_Interval; font_size <= Font_Largest_Px_Size; font_size += Font_Size_Interval
|
||||
for font_size : i32 = clamp( Font_Size_Interval, 10, Font_Size_Interval ); font_size <= Font_Largest_Px_Size; font_size += Font_Size_Interval
|
||||
{
|
||||
// logf("Loading at size %v", font_size)
|
||||
id := (font_size / Font_Size_Interval) + (font_size % Font_Size_Interval)
|
||||
@ -585,7 +585,7 @@ font_provider_resolve_draw_id :: proc( id : FontID, size := Font_Use_Default_Siz
|
||||
def := hmap_chained_get( font_provider_data.font_cache, id.key )
|
||||
size := size == 0.0 ? f32(def.default_size) : size
|
||||
even_size := math.round(size * (1.0 / f32(Font_Size_Interval))) * f32(Font_Size_Interval)
|
||||
resolved_size = clamp( i32( even_size), 14, Font_Largest_Px_Size )
|
||||
resolved_size = clamp( i32( even_size), 12, Font_Largest_Px_Size )
|
||||
|
||||
id := (resolved_size / Font_Size_Interval) + (resolved_size % Font_Size_Interval)
|
||||
ve_id = def.size_table[ id - 1 ]
|
||||
|
@ -118,7 +118,7 @@ ui_prev_cached_box :: #force_inline proc( box : ^UI_Box ) -> ^UI_Box { return hm
|
||||
|
||||
// TODO(Ed): Rename to ui_box_tranverse_view_next
|
||||
// Traveral pritorizes immeidate children
|
||||
ui_box_tranverse_next_depth_based :: proc "contextless" ( box : ^ UI_Box, bypass_intersection_test := false ) -> (^ UI_Box)
|
||||
ui_box_tranverse_next_depth_based :: #force_inline proc "contextless" ( box : ^ UI_Box, bypass_intersection_test := false ) -> (^ UI_Box)
|
||||
{
|
||||
using state := get_state()
|
||||
// If current has children, do them first
|
||||
|
Loading…
Reference in New Issue
Block a user