From a8018f024bd6c4ed55edc18de65b3fd388f45bdf Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 28 Jun 2025 02:33:53 +0100 Subject: [PATCH] update linear allocator to stacks --- vg_audio.c | 32 +-- vg_audio.h | 8 +- vg_audio_dsp.c | 2 +- vg_build.h | 1 + vg_bvh.c | 20 +- vg_bvh.h | 4 +- vg_engine.c | 13 +- vg_engine.h | 2 + vg_framebuffer.c | 7 +- vg_framebuffer.h | 2 +- vg_io.c | 83 ++---- vg_io.h | 10 +- vg_kv.c | 3 + vg_kv.h | 20 ++ vg_lines.c | 119 ++++---- vg_lines.h | 4 +- vg_mem.c | 433 +++++++++-------------------- vg_mem.h | 132 ++++----- vg_mem_view.c | 560 ++++++++++++++++++++++---------------- vg_render.c | 8 +- vg_steam_auth.h | 85 ------ vg_steam_auth_server.h | 87 ++++++ vg_tex.c | 4 +- vg_ui/imgui.c | 13 +- vg_ui/imgui.h | 7 + vg_ui/imgui_impl_opengl.c | 32 ++- 26 files changed, 798 insertions(+), 893 deletions(-) create mode 100644 vg_kv.c create mode 100644 vg_kv.h create mode 100644 vg_steam_auth_server.h diff --git a/vg_audio.c b/vg_audio.c index 3113fc7..69000b0 100644 --- a/vg_audio.c +++ b/vg_audio.c @@ -68,10 +68,10 @@ static void vg_audio_assert_lock(void) /* clip loading from disk * ------------------------------------------------------------------------------- */ -void audio_clip_load( audio_clip *clip, void *lin_alloc ) +void audio_clip_load( audio_clip *clip, vg_stack_allocator *stack ) { - if( lin_alloc == NULL ) - lin_alloc = _vg_audio.data_allocator; + if( stack == NULL ) + stack = _vg_audio.permanent_stack; if( _vg_audio.always_keep_clips_compressed ) { @@ -98,7 +98,7 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc ) vg_error( "No path specified, embeded vorbis unsupported\n" ); vg_audio_lock(); - clip->any_data = vg_file_read( lin_alloc, clip->path, &clip->size ); + clip->any_data = vg_file_read( stack, clip->path, &clip->size, 0 ); vg_audio_unlock(); if( !clip->any_data ) @@ -125,7 +125,7 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc ) if( total_size > AUDIO_DECODE_SIZE ) vg_error( "Bird coding too long, and exceeds maximum decode size\n" ); - struct synth_bird *bird = vg_linear_alloc( lin_alloc, total_size ); + struct synth_bird *bird = vg_stack_allocate( stack, total_size, 8, NULL ); memcpy( &bird->settings, clip->any_data, clip->size ); clip->any_data = bird; @@ -136,19 +136,17 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc ) else { if( !clip->path ) - { vg_error( "No path specified, embeded mono unsupported\n" ); - } - vg_linear_clear( vg_mem.scratch ); + vg_stack_clear( &vg.scratch ); u32 fsize; stb_vorbis_alloc alloc = { - .alloc_buffer = vg_linear_alloc( vg_mem.scratch, AUDIO_DECODE_SIZE ), + .alloc_buffer = vg_stack_allocate( &vg.scratch, AUDIO_DECODE_SIZE, 8, NULL ), .alloc_buffer_length_in_bytes = AUDIO_DECODE_SIZE }; - void *filedata = vg_file_read( vg_mem.scratch, clip->path, &fsize ); + void *filedata = vg_file_read( &vg.scratch, clip->path, &fsize, 0 ); int err; stb_vorbis *decoder = stb_vorbis_open_memory( filedata, fsize, &err, &alloc ); @@ -166,7 +164,7 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc ) data_size = length_samples * sizeof(i16); vg_audio_lock(); - clip->any_data = vg_linear_alloc( lin_alloc, vg_align8(data_size) ); + clip->any_data = vg_stack_allocate( stack, data_size, 8, NULL ); clip->size = length_samples; vg_audio_unlock(); @@ -177,10 +175,10 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc ) } } -void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc ) +void audio_clip_loadn( audio_clip *arr, int count, vg_stack_allocator *stack ) { for( int i=0; idsp_enabled = _vg_audio.dsp_enabled_ui; diff --git a/vg_audio.h b/vg_audio.h index f47f450..3be329b 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -181,8 +181,8 @@ struct vg_audio SDL_AudioDeviceID sdl_output_device; vg_str device_choice; /* buffer is null? use default from OS */ - void *data_allocator; /* allocator for practically static sound data */ - void *decoding_buffer; /* place where raw samples get decoded into */ + vg_stack_allocator *permanent_stack; + void *decoding_buffer; SDL_mutex *mutex; u32 samples_written_last_audio_frame; @@ -221,8 +221,8 @@ void vg_audio_device_init(void); void vg_audio_init(void); void vg_audio_free(void); -void audio_clip_load( audio_clip *clip, void *lin_alloc ); -void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc ); +void audio_clip_load( audio_clip *clip, vg_stack_allocator *stack ); +void audio_clip_loadn( audio_clip *arr, int count, vg_stack_allocator *stack ); void vg_audio_lock(void); void vg_audio_unlock(void); diff --git a/vg_audio_dsp.c b/vg_audio_dsp.c index 4a3536e..7d6bd1a 100644 --- a/vg_audio_dsp.c +++ b/vg_audio_dsp.c @@ -133,7 +133,7 @@ static struct dsp_schroeder __diffusion_chain[8]; void vg_dsp_init( void ) { vg_rand_seed( &vg_dsp.rand, 461 ); - vg_dsp.buffer = vg_linear_alloc( vg_mem.rtmemory, 1024*1024*1 ); + vg_dsp.buffer = vg_stack_allocate( &vg.rtmem, VG_MB(1), 8, "Audio DSP Buffer" ); /* temporary global design */ dsp_init_lpf( &__lpf_mud_free, 125.0f ); diff --git a/vg_build.h b/vg_build.h index 4026690..c34f393 100644 --- a/vg_build.h +++ b/vg_build.h @@ -282,6 +282,7 @@ vg_compiler_run( struct vg_project *project, vg_strcat( &cmd, " -Wall -ferror-limit=10\\\n" " -Wno-unused-function -Wno-unused-variable\\\n" " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n" + " -Wunused-result\\\n" ); if( env->compiler != k_compiler_clang ) diff --git a/vg_bvh.c b/vg_bvh.c index b33b031..05edae7 100644 --- a/vg_bvh.c +++ b/vg_bvh.c @@ -91,23 +91,21 @@ void bh_rebuild( bh_tree *bh, u32 item_count ) bh_subdivide( bh, 0 ); } -bh_tree *bh_create( void *lin_alloc, bh_system *system, - void *user, u32 item_count, u32 max_per_leaf ) +bh_tree *bh_create( vg_stack_allocator *stack, bh_system *system, void *user, u32 item_count, u32 max_per_leaf ) { u32 alloc_count = VG_MAX( 1, item_count ); u32 totsize = sizeof(bh_tree) + sizeof(bh_node)*(alloc_count*2-1); - bh_tree *bh = lin_alloc? vg_linear_alloc( lin_alloc, vg_align8(totsize) ): - malloc( totsize ); + bh_tree *bh = stack? vg_stack_allocate( stack, totsize, 8, "BVH Tree" ): vg_malloc( totsize ); bh->system = system; bh->user = user; bh->max_per_leaf = max_per_leaf; bh_rebuild( bh, item_count ); - if( lin_alloc ){ - totsize = vg_align8(sizeof(bh_tree) + sizeof(bh_node) * bh->node_count); - bh = vg_linear_resize( lin_alloc, bh, totsize ); - } + totsize = sizeof(bh_tree) + sizeof(bh_node) * bh->node_count; + + if( stack ) vg_stack_resize_last( stack, totsize ); + else bh = vg_realloc( bh, totsize ); vg_success( "BVH done, size: %u/%u\n", bh->node_count, (alloc_count*2-1) ); return bh; @@ -121,8 +119,10 @@ void bh_debug_leaf( bh_tree *bh, bh_node *node ) { vg_line_boxf( node->bbx, 0xff00ff00 ); - if( bh->system->item_debug ){ - for( u32 i=0; icount; i++ ){ + if( bh->system->item_debug ) + { + for( u32 i=0; icount; i++ ) + { u32 idx = node->start+i; bh->system->item_debug( bh->user, idx ); } diff --git a/vg_bvh.h b/vg_bvh.h index 1adb3d8..3592bc6 100644 --- a/vg_bvh.h +++ b/vg_bvh.h @@ -78,8 +78,8 @@ struct bh_system{ void bh_update_bounds( bh_tree *bh, u32 inode ); void bh_subdivide( bh_tree *bh, u32 inode ); void bh_rebuild( bh_tree *bh, u32 item_count ); -bh_tree *bh_create( void *lin_alloc, bh_system *system, - void *user, u32 item_count, u32 max_per_leaf ); + +bh_tree *bh_create( vg_stack_allocator *stack, bh_system *system, void *user, u32 item_count, u32 max_per_leaf ); void bh_debug_leaf( bh_tree *bh, bh_node *node ); diff --git a/vg_engine.c b/vg_engine.c index db310fc..2b17501 100644 --- a/vg_engine.c +++ b/vg_engine.c @@ -514,7 +514,7 @@ static void _vg_init_window( const char *window_name ) char *exe_basepath = SDL_GetBasePath(); u32 len = vg_align8( strlen(exe_basepath)+1 ); - char *dest = vg_linear_alloc( vg_mem.rtmemory, len ); + char *dest = vg_stack_allocate( &vg.rtmem, len, 1, "Exe basepath" ); strcpy( dest, exe_basepath ); SDL_free( exe_basepath ); vg.base_path = dest; @@ -660,12 +660,6 @@ static void _vg_terminate(void) exit(0); } -static int cmd_log_memory( int argc, const char *argv[] ) -{ - vg_mem_log( vg_mem.rtmemory, 0, "rtmemory" ); - return 0; -} - static int _vg_loader_thread( void *pfn ) { SDL_TLSSet( vg.thread_purpose, &_thread_purpose_loader, NULL ); @@ -715,9 +709,6 @@ void vg_init( int argc, const char *argv[], const char *window_name ) if( (arg = vg_long_opt_arg( "samples", "Rendering samples per pixel" )) ) vg.samples = VG_MAX( 0, VG_MIN( 8, atoi( arg ) ) ); - if( vg_long_opt( "use-libc-malloc", "Use standard libc allocator" ) ) - vg_mem.use_libc_malloc = 1; - if( vg_long_opt( "high-performance", "Turn graphics to lowest quality" ) ) vg.quality_profile = k_quality_profile_low; @@ -740,7 +731,6 @@ void vg_run(void) exit(0); /* Systems init */ - vg_alloc_quota(); vg_console_init(); vg_magi_init(); @@ -755,7 +745,6 @@ void vg_run(void) vg_console_load_autos(); vg_console_reg_cmd( "vg_settings", cmd_vg_settings_toggle, NULL ); - vg_console_reg_cmd( "vg_rtmemory", cmd_log_memory, NULL ); _vg_init_window( vg.window_name ); SDL_SetRelativeMouseMode(1); diff --git a/vg_engine.h b/vg_engine.h index 2cc8b6d..b44f441 100644 --- a/vg_engine.h +++ b/vg_engine.h @@ -68,6 +68,8 @@ enum engine_status struct vg_engine { + vg_stack_allocator rtmem, scratch; + /* Engine sync */ SDL_Window *window; SDL_GLContext gl_context; diff --git a/vg_framebuffer.c b/vg_framebuffer.c index 95776b7..95f94bb 100644 --- a/vg_framebuffer.c +++ b/vg_framebuffer.c @@ -226,9 +226,9 @@ static void vg_framebuffer_allocate_texture( vg_framebuffer *fb, } } -vg_framebuffer *vg_framebuffer_allocate( void *alloc, u32 attachment_count, bool track ) +vg_framebuffer *vg_framebuffer_allocate( vg_stack_allocator *stack, u32 attachment_count, bool track ) { - vg_framebuffer *fb = vg_linear_alloc( alloc, sizeof(vg_framebuffer) ); + vg_framebuffer *fb = VG_STACK_ALLOCATE_STRUCT( stack, vg_framebuffer ); if( track ) { @@ -242,9 +242,8 @@ vg_framebuffer *vg_framebuffer_allocate( void *alloc, u32 attachment_count, bool } } - fb->attachments = vg_linear_alloc( alloc, sizeof(vg_framebuffer_attachment) * attachment_count ); + fb->attachments = vg_stack_allocate( stack, sizeof(vg_framebuffer_attachment) * attachment_count, 8, NULL ); fb->attachment_count = attachment_count; - return fb; } diff --git a/vg_framebuffer.h b/vg_framebuffer.h index 788c011..98bd7ed 100644 --- a/vg_framebuffer.h +++ b/vg_framebuffer.h @@ -87,7 +87,7 @@ void vg_framebuffer_bind_texture( vg_framebuffer *fb, int attachment, int slot ) * Allocation of a framebuffer memory. Optionally, track this framebuffer in * debugging systems. */ -vg_framebuffer *vg_framebuffer_allocate( void *alloc, u32 attachment_count, bool track ); +vg_framebuffer *vg_framebuffer_allocate( vg_stack_allocator *stack, u32 attachment_count, bool track ); /* * Allocate graphics memory and initialize diff --git a/vg_io.c b/vg_io.c index dbb51e9..a293958 100644 --- a/vg_io.c +++ b/vg_io.c @@ -187,34 +187,35 @@ void vg_file_error_info( FILE *fp ) } } -#define VG_FILE_IO_CHUNK_SIZE 1024*256 +#define VG_FILE_IO_CHUNK_SIZE VG_KB(256) /* read entire binary file */ -void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) +void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool text ) { FILE *f = fopen( path, "rb" ); if( f ) { - void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ): NULL; + if( !stack ) + { + stack = alloca( sizeof(vg_stack_allocator) ); + vg_stack_init( stack, NULL, VG_FILE_IO_CHUNK_SIZE, "Stretchy file buffer" ); + vg_stack_set_flags( stack, VG_STACK_ALLOCATOR_DOUBLE_IF_FULL ); + } + + u8 *buffer = vg_stack_allocate( stack, 0, 8, "File data" ); u64 current = 0; /* read in chunks */ for( u32 i=0; 1; i++ ) { - if( lin_alloc ) - buffer = vg_linear_extend( lin_alloc,buffer,VG_FILE_IO_CHUNK_SIZE ); - else - buffer = realloc( buffer, current + VG_FILE_IO_CHUNK_SIZE ); - + vg_stack_extend_last( stack, VG_FILE_IO_CHUNK_SIZE ); u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f ); current += l; if( l != VG_FILE_IO_CHUNK_SIZE ) { if( feof( f ) ) - { break; - } else { if( ferror( f ) ) @@ -235,75 +236,47 @@ void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) } } - if( lin_alloc ) - buffer = vg_linear_resize( lin_alloc, buffer, vg_align8(current) ); - else - buffer = realloc( buffer, vg_align8(current) ); + if( text ) + { + vg_stack_extend_last( stack, 1 ); + buffer[ current ++ ] = '\0'; + } + vg_stack_resize_last( stack, current ); fclose( f ); *size = (u32)current; return buffer; } - else{ + else + { vg_error( "vg_disk_open_read: %s (file: %s)\n", strerror(errno), path ); return NULL; } } -/* read entire file and append a null on the end */ -char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz ) -{ - u32 size; - char *str = vg_file_read( lin_alloc, path, &size ); - - if( !str ) - return NULL; - - /* include null terminator */ - if( lin_alloc ) - str = vg_linear_extend( lin_alloc, str, 1 ); - else - str = realloc( str, size+1 ); - - str[ size ] = '\0'; - *sz = size+1; - - return str; -} - - -int vg_asset_write( const char *path, void *data, i64 size ) +bool vg_asset_write( const char *path, void *data, i64 size ) { FILE *f = fopen( path, "wb" ); - if( f ){ + if( f ) + { fwrite( data, size, 1, f ); fclose( f ); return 1; } - else{ + else return 0; - } -} - -/* TODO: error handling if read fails */ -int vg_file_copy( const char *src, const char *dst, void *lin_alloc ) -{ - vg_info( "vg_file_copy( %s -> %s )\n", src, dst ); - u32 size; - void *data = vg_file_read( lin_alloc, src, &size ); - return vg_asset_write( dst, data, size ); } const char *vg_path_filename( const char *path ) { const char *base = path; - - for( int i=0; i<1024; i++ ){ - if( path[i] == '\0' ) break; - if( path[i] == '/' ){ + for( int i=0; i<1024; i++ ) + { + if( path[i] == '\0' ) + break; + if( path[i] == '/' ) base = path+i+1; - } } return base; diff --git a/vg_io.h b/vg_io.h index 4f549b8..6a84aaf 100644 --- a/vg_io.h +++ b/vg_io.h @@ -54,13 +54,9 @@ bool vg_make_directory( const char *path ); * File I/O */ -/* read entire binary file */ -void *vg_file_read( void *lin_alloc, const char *path, u32 *size ); +/* read entire binary file, if text is 1, appends a nul to the end of the buffer */ +void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool text ); -/* read entire file and append a null on the end */ -char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz ); - -int vg_asset_write( const char *path, void *data, i64 size ); -int vg_file_copy( const char *src, const char *dst, void *lin_alloc ); +bool vg_asset_write( const char *path, void *data, i64 size ); const char *vg_path_filename( const char *path ); void vg_file_error_info( FILE *fp ); diff --git a/vg_kv.c b/vg_kv.c new file mode 100644 index 0000000..39f7831 --- /dev/null +++ b/vg_kv.c @@ -0,0 +1,3 @@ +#include "vg_kv.h" + + diff --git a/vg_kv.h b/vg_kv.h new file mode 100644 index 0000000..ee11558 --- /dev/null +++ b/vg_kv.h @@ -0,0 +1,20 @@ +#pragma once +#include "vg_platform.h" + +struct vg_kv +{ + u32 key_info; /* 20 bit hash, 10 bit key length, 2 bit type */ + u32 key_offset; /* into the raw text buffer */ + u32 brother_offset;/* 24 bits, relative jump past all descendents to the next key */ + + union + { + struct + { + u16 offset_from_key, length; + } + value; + + u32 children; /* 24 bits */ + }; +}; diff --git a/vg_lines.c b/vg_lines.c index 364bd1a..40eff0c 100644 --- a/vg_lines.c +++ b/vg_lines.c @@ -45,7 +45,7 @@ static struct vg_shader _shader_lines = { } }; -#define VG_LINES_BUFFER_SIZE 50000 * sizeof( struct vg_lines_vert ) +#define VG_LINES_MAX_VERTS 50000 static void async_vg_lines_init( void *_ ) { @@ -55,8 +55,7 @@ static void async_vg_lines_init( void *_ ) glGenBuffers( 1, &vg_lines.vbo ); glBindVertexArray( vg_lines.vao ); glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo ); - - glBufferData( GL_ARRAY_BUFFER, VG_LINES_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW ); + glBufferData( GL_ARRAY_BUFFER, VG_LINES_MAX_VERTS*sizeof(struct vg_lines_vert), NULL, GL_DYNAMIC_DRAW ); glBindVertexArray( vg_lines.vao ); /* Pointers */ @@ -84,8 +83,9 @@ static void async_vg_lines_init( void *_ ) void vg_lines_init(void) { THREAD_1; + vg_lines.vertex_buffer = vg_stack_allocate( &vg.rtmem, VG_LINES_MAX_VERTS*sizeof(struct vg_lines_vert), + 8, "Debugging Lines" ); - vg_lines.vertex_buffer = vg_create_linear_allocator( vg_mem.rtmemory, VG_LINES_BUFFER_SIZE, VG_MEMORY_REALTIME); vg_async_call( &vg.main_tasks, async_vg_lines_init, NULL ); vg_console_reg_var( "vg_lines", &vg_lines.render, k_var_dtype_i32, VG_VAR_CHEAT ); vg_shader_register( &_shader_lines ); @@ -94,51 +94,54 @@ void vg_lines_init(void) void vg_lines_drawall( void ) { glUseProgram( _shader_lines.id ); - - glUniformMatrix4fv( glGetUniformLocation( _shader_lines.id, "uPv" ), - 1, GL_FALSE, (float *)vg.pv ); + glUniformMatrix4fv( glGetUniformLocation( _shader_lines.id, "uPv" ), 1, GL_FALSE, (f32 *)vg.pv ); glBindVertexArray( vg_lines.vao ); glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo ); - - u32 bufusage = vg_linear_get_cur(vg_lines.vertex_buffer); - glBufferSubData( GL_ARRAY_BUFFER, 0, bufusage, vg_lines.vertex_buffer ); + glBufferSubData( GL_ARRAY_BUFFER, 0, vg_lines.vertex_count*sizeof(struct vg_lines_vert), vg_lines.vertex_buffer ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBlendEquation( GL_FUNC_ADD ); if( vg_lines.render ) - glDrawArrays( GL_LINES, 0, bufusage / sizeof(struct vg_lines_vert) ); + glDrawArrays( GL_LINES, 0, vg_lines.vertex_count ); glDisable( GL_BLEND ); - vg_linear_clear( vg_lines.vertex_buffer ); + vg_lines.vertex_count = 0; } void vg_line2( line_co from, line_co to, u32 fc, u32 tc ) { - if( !vg_lines.enabled ) return; + if( !vg_lines.enabled ) + return; - u32 size = 2 * sizeof(struct vg_lines_vert); - struct vg_lines_vert *v = vg_linear_alloc( vg_lines.vertex_buffer, size ); + if( vg_lines.vertex_count < VG_LINES_MAX_VERTS ) + { + struct vg_lines_vert *v = &vg_lines.vertex_buffer[ vg_lines.vertex_count ]; - v3_copy( from, v[0].co ); - v3_copy( to, v[1].co ); + v3_copy( from, v[0].co ); + v3_copy( to, v[1].co ); - v[0].colour = fc; - v[1].colour = tc; + v[0].colour = fc; + v[1].colour = tc; + + vg_lines.vertex_count += 2; + } } void vg_line( line_co from, line_co to, u32 colour ) { - if( !vg_lines.enabled ) return; + if( !vg_lines.enabled ) + return; vg_line2( from, to, colour, colour ); } -void vg_line_arrow( line_co co, line_co dir, float size, u32 colour ) +void vg_line_arrow( line_co co, line_co dir, f32 size, u32 colour ) { - if( !vg_lines.enabled ) return; + if( !vg_lines.enabled ) + return; v3f p1, tx, ty, p2, p3; v3_muladds( co, dir, size, p1 ); @@ -155,26 +158,27 @@ void vg_line_arrow( line_co co, line_co dir, float size, u32 colour ) void vg_line_box_verts( boxf box, v3f verts[8] ) { - if( !vg_lines.enabled ) return; + if( !vg_lines.enabled ) + return; - for( u32 i=0; i<8; i++ ){ - for( u32 j=0; j<3; j++ ){ + for( u32 i=0; i<8; i++ ) + for( u32 j=0; j<3; j++ ) verts[i][j] = i&(0x1< #include -struct vg_global_mem vg_mem; +void *vg_malloc( u64 size ) +{ + void *buf = malloc( size ); + if( !buf ) + vg_fatal_error( "Out of memory (OS)\n" ); + return buf; +} + +void vg_free( void *buf ) +{ + free( buf ); +} + +void *vg_realloc( void *buf, u64 size ) +{ + buf = realloc( buf, size ); + if( !buf ) + vg_fatal_error( "Out of memory (OS)\n" ); + return buf; +} + +void vg_zero_mem( void *buffer, u32 length ) +{ + u8 *u8s = buffer; + for( u32 i=0; i> 4; @@ -27,320 +54,162 @@ u32 vg_align4( u32 s ) return m << 2; } -/* Returns allocator structure from data pointer */ -vg_linear_allocator *vg_linear_header( void *data ) +void vg_stack_init( vg_stack_allocator *stack, void *buffer, u32 capacity, const char *debug_name ) { - vg_linear_allocator *ptr = data; - ptr --; + VG_ASSERT( sizeof( vg_allocation_meta ) == 24 ); + VG_ASSERT( sizeof( vg_stack_allocator ) == 24 ); - return ptr; + vg_zero_mem( stack, sizeof(vg_stack_allocator) ); + stack->data = buffer? buffer: vg_malloc( capacity ); + stack->capacity = capacity; + stack->flags = buffer? 0: VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC; } -/* allocate something from a linear allocator */ -__attribute__((warn_unused_result)) -void *_vg_linear_alloc( void *buffer, u32 size, const char *constr_name ) +vg_stack_allocator *vg_stack_make_substack( vg_stack_allocator *parent, u32 capacity, const char *debug_name ) { - if( size % 8 ) - size = vg_align8( size ); - - if( ((u64)buffer) % 8 ) - vg_fatal_error( "Tried allocating to an unaligned buffer (%p)", buffer ); + void *block = vg_stack_allocate( parent, sizeof(vg_stack_allocator) + capacity, 8, debug_name ); + vg_stack_set_flags_last( parent, VG_ALLOCATION_FLAG_IS_STACK ); - vg_linear_allocator *alloc = vg_linear_header( buffer ); - - if( (alloc->cur + size) > alloc->size ) - vg_fatal_error( "linear allocator overflow (%u + %u > %u)\n", - alloc->cur, size, alloc->size ); + vg_stack_allocator *stack = block; + vg_stack_init( stack, block + sizeof(vg_stack_allocator), capacity, debug_name ); + return stack; +} - if( alloc->flags & VG_MEMORY_SYSTEM ) +static void vg_stack_growmaybe( vg_stack_allocator *stack, u32 new_usage ) +{ + if( new_usage > stack->capacity ) { - if( (alloc->allocation_count + 1) > VG_MAX_ALLOCATIONS ) + if( stack->flags & VG_STACK_ALLOCATOR_DOUBLE_IF_FULL ) { - vg_fatal_condition(); - vg_info( "Linear allocators marked as 'SYSTEMS', have a hard limit of " - "%u allocations.\n\n" - "The limit was exceeded by the following request:\n", - VG_MAX_ALLOCATIONS ); - vg_info( " Name: %s\n", constr_name ); - vg_info( " Size: %u bytes\n", size ); - vg_fatal_exit(); - } - } - - void *data; + u32 cap = stack->capacity * 2; + if( new_usage > cap ) + cap = new_usage; - if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ) - { - data = malloc( size ); - - vg_allocation_meta *meta = &alloc->alloc_table[ alloc->allocation_count ]; - meta->type = k_allocation_type_block; - meta->data = data; - meta->size = size; - meta->name = constr_name; + stack->data = vg_realloc( stack->data, cap ); + stack->capacity = cap; + } + else + { + vg_fatal_error( "Stack allocator overflow (capacity: %u, used: %u, new_usage: %u)\n", + stack->capacity, stack->used, new_usage ); + } } - else - data = buffer + alloc->cur; - - u8 *bytes = data; - for( u32 i=0; iallocation_count ++; - alloc->last_alloc = data; - alloc->last_alloc_size = size; - alloc->cur += size; - - if( ((u64)data) % 8 ) - vg_fatal_error( "Resultant allocation was unaligned, most likely memory " - "corruption or programmer error\n" ); - return data; } -/* resize latest block of memory from linear */ -__attribute__((warn_unused_result)) -void *vg_linear_resize( void *buffer, void *data, u32 newsize ) +void *vg_stack_allocate( vg_stack_allocator *stack, u32 size, u32 alignment, const char *debug_name ) { - vg_linear_allocator *alloc = vg_linear_header( buffer ); - - if( newsize % 8 ) - newsize = vg_align8( newsize ); - - if( alloc->last_alloc != data ) - vg_fatal_error( "Tried to resize allocation in linear allocator which " - "has allocated other things after this block.\n" ); - - if( (alloc->cur - alloc->last_alloc_size + newsize) > alloc->size ) - vg_fatal_error( "Tried to resize allocation to new size which would " - "overflow the allocator\n" ); + VG_ASSERT( (alignment >= 1) && (alignment <= 8) ); + VG_ASSERT( ~stack->used & (0x1<<31) ); + VG_ASSERT( ~size & (0x1<<31) ); - alloc->cur -= alloc->last_alloc_size; - alloc->cur += newsize; - alloc->last_alloc_size = newsize; - - if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ) + u32 block_size = size; + if( stack->flags & VG_STACK_ALLOCATOR_METADATA ) { - data = realloc( data, newsize ); - if( !data ) - vg_fatal_error( "We are libc mode, and realloc failed" ); - - alloc->alloc_table[ alloc->allocation_count-1 ].data = data; - alloc->alloc_table[ alloc->allocation_count-1 ].size = newsize; - alloc->last_alloc = data; - return data; + block_size += sizeof( vg_allocation_meta ); + alignment = 8; } - else return data; -} -void vg_libc_del_recursive( void *buffer ) -{ - vg_linear_allocator *alloc = vg_linear_header( buffer ); - for( u32 i=0; iallocation_count; i ++ ) - { - vg_allocation_meta *meta = &alloc->alloc_table[i]; - if( meta->type == k_allocation_type_linear ) - vg_libc_del_recursive( meta->data ); - else - free( meta->data ); - } + u32 previous_base_offset = stack->used - stack->last_allocation_totalsize; + stack->last_allocation_totalsize = block_size; - free( alloc->alloc_table ); - free( alloc ); -} + u32 new_usage = stack->used + block_size + alignment; + vg_stack_growmaybe( stack, new_usage ); -/* its possible to delete just the last item */ -void vg_linear_del( void *buffer, void *data ) -{ - vg_linear_allocator *alloc = vg_linear_header( buffer ); + while( stack->used & (alignment-1) ) + stack->used ++; - if( alloc->last_alloc != data ) - vg_fatal_error( "This block has been fixed and cannot be deleted.\n" - "Last alloc: %p, this: %p\n", alloc->last_alloc, data ); + void *block = (void *)stack->data + stack->used; + stack->used += block_size; - if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ) + if( stack->flags & VG_STACK_ALLOCATOR_METADATA ) { - vg_allocation_meta *meta = &alloc->alloc_table[alloc->allocation_count-1]; - if( meta->type == k_allocation_type_linear ) - vg_libc_del_recursive( meta->data ); - else - free( data ); - } + vg_allocation_meta *meta = block; + memset( block, 0, sizeof(vg_allocation_meta) ); + meta->name = debug_name; + meta->size = size; + meta->previous_offset = previous_base_offset; + meta->flags = 0; - alloc->allocation_count --; - alloc->cur -= alloc->last_alloc_size; - alloc->last_alloc = NULL; - alloc->last_alloc_size = 0; + return (void *)meta->data; + } + else return block; } -void vg_allocator_free( void *allocator ) +void vg_stack_clear( vg_stack_allocator *stack ) { - if( vg_mem.use_libc_malloc ) - vg_libc_del_recursive( allocator ); - else - free( vg_linear_header( allocator ) ); + stack->used = 0; + stack->last_allocation_totalsize = 0; } -/* extend latest block of memory from linear */ -__attribute__((warn_unused_result)) -void *_vg_linear_extend( void *buffer, void *data, u32 extra, - const char *constr_name ) +void vg_stack_free( vg_stack_allocator *stack ) { - if( !data ) - return _vg_linear_alloc( buffer, vg_align8(extra), constr_name ); - - vg_linear_allocator *alloc = vg_linear_header( buffer ); - - if( alloc->last_alloc != data ) - vg_fatal_error( "This block has been fixed!" ); - - u32 new_size = alloc->last_alloc_size + extra; - return vg_linear_resize( buffer, data, vg_align8(new_size) ); + if( stack->flags & VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC ) + vg_free( stack->data ); + vg_zero_mem( stack, sizeof(vg_stack_allocator) ); } -/* get the current usage of allocator */ -u32 vg_linear_get_cur( void *buffer ) +void vg_stack_set_flags( vg_stack_allocator *stack, u16 append_flags ) { - vg_linear_allocator *alloc = vg_linear_header( buffer ); - return alloc->cur; -} + if( append_flags & VG_STACK_ALLOCATOR_DOUBLE_IF_FULL ) + if( !(stack->flags & VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC) ) + vg_fatal_error( "Cannot append DOUBLE_IF_FULL to stack allocator, since buffer wasn't from malloc.\n" ); -/* get the capacity of allocator. */ -u32 vg_linear_get_capacity( void *buffer ) -{ - vg_linear_allocator *alloc = vg_linear_header( buffer ); - return alloc->size; -} + if( append_flags & VG_STACK_ALLOCATOR_METADATA ) + if( stack->used ) + vg_fatal_error( "Cannot append METADATA to stack allocator after allocating something.\n" ); -/* get the remaining size of the allocator */ -u32 vg_linear_remaining( void *buffer ) -{ - vg_linear_allocator *alloc = vg_linear_header( buffer ); - return alloc->size - alloc->cur; + stack->flags |= append_flags; } -/* yeet all memory from linear allocator */ -void vg_linear_clear( void *buffer ) +void vg_stack_set_flags_last( vg_stack_allocator *stack, u16 append_flags ) { - vg_linear_allocator *alloc = vg_linear_header( buffer ); - - /* libc mode we recursively free any allocations made */ - if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){ - for( u32 i=0; iallocation_count; i++ ){ - vg_allocation_meta *meta = &alloc->alloc_table[i]; - - if( meta->type == k_allocation_type_block ){ - free( meta->data ); - } - else{ - vg_linear_clear( meta->data ); - vg_linear_allocator *sub = vg_linear_header( meta->data ); - - free( sub->alloc_table ); - free( sub ); - } - } - } + if( !(stack->flags & VG_STACK_ALLOCATOR_METADATA) ) + vg_fatal_error( "Stack allocator does not have the METADATA flag set.\n" ); - alloc->last_alloc = NULL; - alloc->last_alloc_size = 0; - alloc->allocation_count = 0; - alloc->cur = 0; + vg_allocation_meta *meta = (void *)stack->data + (stack->used - stack->last_allocation_totalsize); + meta->flags |= append_flags; } -/* allocate a FIXED SIZE linear allocator - * - * FIXME: there was a bug in vg's code that caused a race condition between - * two system allocations. make this IMPOSSIBLE by requiring a lock - * on the allocater to be passed between threads. - * - * luckily that bug only exists when using development tools, but still! - * - * this should then only be checked and turned on in debugging. - * - */ -void *_vg_create_linear_allocator( void *lin_alloc, u32 size, u16 flags, const char *constr_name) +void vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ) { - VG_ASSERT( sizeof( vg_linear_allocator ) == 32 ); + u32 base_offset = stack->used - stack->last_allocation_totalsize, + block_size = new_size; - vg_linear_allocator *header; - u32 block_size = size + sizeof(vg_linear_allocator); - - /* Creating it inside an existing one */ - if( lin_alloc ) + if( stack->flags & VG_STACK_ALLOCATOR_METADATA ) { - vg_linear_allocator *alloc = vg_linear_header( lin_alloc ); - - if( alloc->cur + block_size > alloc->size ) - vg_fatal_error( "Out of memory (%u + %u > %u)\n", alloc->cur, block_size, alloc->size ); - - if( alloc->allocation_count + 1 > VG_MAX_ALLOCATIONS ) - vg_fatal_error( "Exceeded max allocations in linear allocator (%u)\n", VG_MAX_ALLOCATIONS ); - - if( (flags && VG_MEMORY_SYSTEM) && (alloc->flags & VG_MEMORY_REALTIME) ) - vg_fatal_error( "Cannot declare realtime allocator inside systems allocator"); - - if( vg_mem.use_libc_malloc ){ - vg_allocation_meta *meta = - &alloc->alloc_table[ alloc->allocation_count ]; - - if( flags & VG_MEMORY_REALTIME ) - header = malloc( block_size ); - else - header = malloc( sizeof(vg_linear_allocator) ); - - meta->data = header+1; - meta->type = k_allocation_type_linear; - meta->size = size; - meta->name = constr_name; - } - else header = lin_alloc + alloc->cur; - - alloc->cur += block_size; - alloc->last_alloc = header; - alloc->last_alloc_size = block_size; - alloc->allocation_count ++; - } - else{ - if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) ) - header = malloc( sizeof(vg_linear_allocator) ); - else - header = malloc( block_size ); + vg_allocation_meta *meta = (void *)stack->data + base_offset; + meta->size = new_size; + block_size += sizeof( vg_allocation_meta ); } - header->allocation_count = 0; - header->cur = 0; - header->last_alloc = NULL; - header->last_alloc_size = 0; - header->size = size; - header->flags = flags; - - if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) ) - { - u32 table_size = sizeof(vg_allocation_meta)*VG_MAX_ALLOCATIONS; - header->alloc_table = malloc( table_size ); - } - else header->alloc_table = NULL; - - return header+1; + u32 new_usage = base_offset + block_size; + vg_stack_growmaybe( stack, new_usage ); + stack->used = new_usage; + stack->last_allocation_totalsize = block_size; } -/* request all the memory we need in advance */ -void vg_set_mem_quota( u32 size ) +void vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ) { - vg_mem.quota = size; + u32 current_size = stack->last_allocation_totalsize; + if( stack->flags & VG_STACK_ALLOCATOR_METADATA ) + current_size -= sizeof(vg_allocation_meta); + vg_stack_resize_last( stack, current_size + extra_bytes ); } -void vg_alloc_quota(void) +void *vg_stack_pop_last( vg_stack_allocator *stack ) { - u32 size_scratch = 10*1024*1024; - u32 size = VG_MAX( vg_mem.quota, size_scratch ); - - vg_mem.rtmemory = _vg_create_linear_allocator( NULL, size, VG_MEMORY_SYSTEM, - "VG Root" ); - vg_mem.scratch = _vg_create_linear_allocator( vg_mem.rtmemory, - size_scratch, - VG_MEMORY_SYSTEM, - "Scratch buffer" ); + if( !(stack->flags & VG_STACK_ALLOCATOR_METADATA) ) + vg_fatal_error( "Stack allocator does not have the METADATA flag set.\n" ); + + if( !stack->last_allocation_totalsize ) + return NULL; + + u32 base_offset = stack->used - stack->last_allocation_totalsize; + vg_allocation_meta *meta = (void *)stack->data + base_offset; + + stack->last_allocation_totalsize = base_offset - meta->previous_offset; + stack->used = base_offset; + return (void *)meta->data; } static void vg_mem_print_size( u32 bytes, char buf[32] ) @@ -352,41 +221,3 @@ static void vg_mem_print_size( u32 bytes, char buf[32] ) else snprintf( buf, 32, "%ub", bytes ); } - -void vg_mem_log( void *lin_alloc, int depth, const char *name ) -{ - if( vg_mem.use_libc_malloc ){ - vg_linear_allocator *alloc = vg_linear_header( lin_alloc ); - - u32 s = alloc->size; - f32 p = ((float)alloc->cur / (float)s) * 100.0f; - - for( int i=0; iflags & VG_MEMORY_SYSTEM ){ - for( u32 i=0; iallocation_count; i++ ){ - vg_allocation_meta *meta = &alloc->alloc_table[i]; - - if( meta->type == k_allocation_type_block ){ - for( int i=0; isize, asize ); - printf( "B(%s): %s\n", meta->name, asize ); - } - else{ - vg_mem_log( meta->data, depth +1, meta->name ); - } - } - } - else{ - for( int i=0; i (UNTRACKED)\n" ); - } - } - else{ - vg_error( "allocations are not tracked (turn on libc mode)\n" ); - } -} diff --git a/vg_mem.h b/vg_mem.h index b5b0366..9c91111 100644 --- a/vg_mem.h +++ b/vg_mem.h @@ -1,103 +1,77 @@ #pragma once +#include "vg_platform.h" +#include -#define VG_MAX_ALLOCATIONS 256 +#define VG_KB( X ) (X*1024) +#define VG_MB( X ) (X*1024*1024) +#define VG_GB( X ) (X*1024*1024*1024) -typedef struct vg_linear_allocator vg_linear_allocator; -typedef struct vg_allocation_meta vg_allocation_meta; +void *vg_malloc( u64 size ); +void *vg_realloc( void *buf, u64 size ); +void vg_free( void *buf ); +void vg_zero_mem( void *buffer, u32 length ); -struct vg_global_mem -{ - void *rtmemory, - *scratch; +typedef struct vg_stack_allocator vg_stack_allocator; +typedef struct vg_allocation_meta vg_allocation_meta; - int use_libc_malloc; - u32 quota; -} -extern vg_mem; +#define VG_ALLOCATION_FLAG_IS_STACK 0x1 +/* 24 bytes + size */ struct vg_allocation_meta { const char *name; - void *data; + u32 size; - enum allocation_type{ - k_allocation_type_block = 0, - k_allocation_type_linear = 1 - } - type; + u32 previous_offset; + u16 flags; + u16 unused0; + u32 unused1; + + u64 data[]; }; -#define VG_MEMORY_SYSTEM 0x1 /* systems memory, slow and low counts */ -#define VG_MEMORY_REALTIME 0x2 /* per-frame. no max allocs, only size. fast */ +/* configuration flags */ +#define VG_STACK_ALLOCATOR_METADATA 0x1 +#define VG_STACK_ALLOCATOR_DOUBLE_IF_FULL 0x2 -/* - * Stored just behind the array. 32 bytes. - */ -#pragma pack(push,1) -struct vg_linear_allocator +/* system flags */ +#define VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC 0x4 + +/* 24 bytes */ +struct vg_stack_allocator { - u32 size; - u32 cur; - u16 allocation_count; + u32 capacity; /* bytes */ + u32 used; + u32 last_allocation_totalsize; u16 flags; - u32 last_alloc_size; - void *last_alloc; - vg_allocation_meta *alloc_table; + u16 unused0; + + void *data; }; -#pragma pack(pop) +/* NOT USED IN THIS FILE */ u32 vg_align16( u32 s ); u32 vg_align8( u32 s ); u32 vg_align4( u32 s ); -/* allocate something from a linear allocator */ -__attribute__((warn_unused_result)) -void *_vg_linear_alloc( void *buffer, u32 size, const char *constr_name ); - -/* resize latest block of memory from linear */ -__attribute__((warn_unused_result)) -void *vg_linear_resize( void *buffer, void *data, u32 newsize ); - -/* its possible to delete just the last item */ -void vg_linear_del( void *buffer, void *data ); - -/* extend latest block of memory from linear */ -__attribute__((warn_unused_result)) -void *_vg_linear_extend( void *buffer, void *data, u32 extra, - const char *constr_name ); - -/* get the current usage of allocator */ -u32 vg_linear_get_cur( void *buffer ); - -/* get the capacity of allocator. */ -u32 vg_linear_get_capacity( void *buffer ); - -/* get the remaining size of the allocator */ -u32 vg_linear_remaining( void *buffer ); - -/* yeet all memory from linear allocator */ -void vg_linear_clear( void *buffer ); - -/* request all the memory we need in advance */ -void vg_set_mem_quota( u32 size ); - -/* essentially init() */ -void vg_alloc_quota(void); - -/* print out tree of current memory used. only works with libc mode */ -void vg_mem_log( void *lin_alloc, int depth, const char *name ); +/* If parent_stack is NULL, it will malloc a new stack of size + * If parent_stack is not NULL, it will allocate the new stack inside of this one. This allows it to be seen in the + * metadata as a tree structure. + */ +void vg_stack_init( vg_stack_allocator *stack, void *buffer, u32 capacity, const char *debug_name ); +void *vg_stack_allocate( vg_stack_allocator *stack, u32 size, u32 alignment, const char *debug_name ); +void vg_stack_clear( vg_stack_allocator *stack ); +void vg_stack_free( vg_stack_allocator *stack ); +void vg_stack_set_flags( vg_stack_allocator *stack, u16 append_flags ); +vg_stack_allocator *vg_stack_make_substack( vg_stack_allocator *parent, u32 capacity, const char *debug_name ); -#define VG_MEM_MCSTR(S) VG_MEM_MCSTR2(S) -#define VG_MEM_MCSTR2(S) #S +#define VG_STACK_ALLOCATE_STRUCT( STACK, STRUCT ) vg_stack_allocate( STACK, sizeof(STRUCT), alignof(STRUCT), NULL ) -#define vg_linear_alloc(...) \ - _vg_linear_alloc( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) -#define vg_linear_extend(...) \ - _vg_linear_extend( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) -#define vg_create_linear_allocator(...) \ - _vg_create_linear_allocator( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) +void vg_stack_resize_last( vg_stack_allocator *stack, u32 new_size ); +void vg_stack_extend_last( vg_stack_allocator *stack, u32 extra_bytes ); -void *_vg_create_linear_allocator( void *lin_alloc, u32 size, - u16 flags, const char *constr_name); -vg_linear_allocator *vg_linear_header( void *data ); -void vg_allocator_free( void *allocator ); +/* + * The following are availible if allocator has the flag METADATA set + */ +void vg_stack_set_flags_last( vg_stack_allocator *stack, u16 append_flags ); +void *vg_stack_pop_last( vg_stack_allocator *stack ); diff --git a/vg_mem_view.c b/vg_mem_view.c index c36913e..03c82f6 100644 --- a/vg_mem_view.c +++ b/vg_mem_view.c @@ -1,9 +1,36 @@ #include "vg_ui/imgui.h" -int vg_mem_view = 0; +struct mem_view_data +{ + void *base_buffer; + u32 route[8]; + u32 route_depth; + + bool vis_dirty; + u32 vis_offset; + v4f vis_colour; + f32 vis_inv_max; + GLuint vis_tex; + u32 vis_i, vis_size; + + struct mem_view_info + { + const char *display_name; + u32 buffer_offset, buffer_size; /* offset + size into route[0]->data */ -void squarey_layout( ui_rect rect, f32 *areas, u32 area_count, - void (*cb)( u32, ui_rect, void* ), void *cb_user ) + bool is_stack; + u32 stack_used_bytes, + stack_children_start, stack_children_count; /* offset + count into this array (infos), children are sorted + by capacity / size */ + } + infos[ 4096 ]; + u32 info_count; + f32 sizes[ 4096 ]; + + f32 vis_data[256*256]; +}; + +void squarey_layout( ui_rect rect, f32 *areas, u32 area_count, void (*cb)( u32, ui_rect, void* ), void *cb_user ) { f32 area_total = 0.0f; for( u32 i=0; iindices[idx]; - vg_allocation_meta *meta = &inf->alloc->alloc_table[idx]; + struct mem_view_info *root_info = &context->mv->infos[ context->root_id ], + *this_info = &context->mv->infos[ root_info->stack_children_start + idx ]; u32 colour; - if( inf->root_colour ) colour = inf->root_colour; - else colour = ~0xff000000&((idx+5)*0x45d9f3b); + if( context->root_colour ) colour = context->root_colour; + else colour = ~0xff000000&((idx+5)*0x45d9f3b); - if( meta->type == k_allocation_type_block ) + if( this_info->is_stack ) { - ui_fill( inf->ui_ctx, tmp, 0x80000000 | colour ); - ui_outline( inf->ui_ctx, tmp, -1, 0xff000000 | colour, 0 ); + struct vg_mem_draw_blocks_context next_level = *context; + next_level.depth ++; + next_level.root_colour = colour; + next_level.root_id = root_info->stack_children_start + idx; + + ui_rect subrect; + rect_copy( rect, subrect ); + vg_mem_view_stack( &next_level, subrect ); } else - vg_mem_view_ui( inf->ui_ctx, tmp, meta->data, meta->name, colour, NULL ); + { + ui_fill( context->ui_ctx, tmp, 0x80000000 | colour ); + ui_outline( context->ui_ctx, tmp, -1, 0xff000000 | colour, 0 ); + } - if( inf->result ) + if( context->depth == 0 ) { - if( ui_inside_rect( rect, inf->ui_ctx->mouse ) ) + if( ui_inside_rect( rect, context->ui_ctx->mouse ) ) { - inf->result->target = meta; - inf->result->colour = colour; - rect_copy( rect, inf->result->target_rect ); + context->highlight_colour = colour; + context->highlight_id = root_info->stack_children_start + idx; + rect_copy( rect, context->highlight_rect ); } } } -vg_linear_allocator *_CB_values; -int _CB_vg_mem_sort( const void *a, const void *b ) +static void vg_mem_view_stack( struct vg_mem_draw_blocks_context *context, ui_rect rect ) { - i32 ia = *((const i32 *)a), ib = *((const i32 *)b); - f32 fa = _CB_values->alloc_table[ ia ].size, - fb = _CB_values->alloc_table[ ib ].size; - return (fa < fb) - (fa > fb); -} + struct mem_view_info *info = &context->mv->infos[ context->root_id ]; + VG_ASSERT( info->is_stack ); -static void vg_mem_view_ui( ui_context *ctx, ui_rect rect, - void *lin_alloc, const char *name, u32 root_colour, - struct vg_mem_view_result *result ) -{ - f32 sizes[ VG_MAX_ALLOCATIONS ]; - i32 indices[ VG_MAX_ALLOCATIONS ]; - - if( vg_mem.use_libc_malloc ) + if( info->stack_used_bytes ) { - vg_linear_allocator *alloc = vg_linear_header( lin_alloc ); - struct vg_mem_draw_inf inf = + /* draw unused stack space as dark black */ + if( info->stack_used_bytes < info->buffer_size ) { - .ui_ctx = ctx, - .alloc = alloc, - .indices = indices, - .result = result, - .root_colour = root_colour - }; + u32 short_side = rect[3] < rect[2]? 1: 0; + f32 p = 1.0f-((f32)info->stack_used_bytes / (f32)info->buffer_size); + ui_px h = (f32)rect[2+short_side^0x1] * p*p; + ui_rect out_box = {rect[0], rect[1]}; + out_box[ 2+short_side^0x1 ] = h; + out_box[ 2+short_side ] = rect[ 2+short_side ]; - if( alloc->allocation_count ) - { - if( alloc->cur < alloc->size ) - { - u32 short_side = rect[3] < rect[2]? 1: 0; - f32 p = 1.0f-((f32)alloc->cur / (f32)alloc->size); - ui_px h = (f32)rect[2+short_side^0x1] * p*p; - ui_rect out_box = {rect[0], rect[1]}; - out_box[ 2+short_side^0x1 ] = h; - out_box[ 2+short_side ] = rect[ 2+short_side ]; - - ui_fill( ctx, out_box, 0x80000000 ); - - char asize[32]; - vg_mem_print_size( alloc->size-alloc->cur, asize ); - ui_text( ctx, out_box, asize, 1, k_ui_align_middle_center, 0 ); + ui_fill( context->ui_ctx, out_box, 0x80000000 ); - rect[ short_side^0x1 ] += h; - rect[ 2+short_side^0x1 ] -= h; - } - - if( alloc->flags & VG_MEMORY_SYSTEM ) - { - for( i32 i=0; iallocation_count; i ++ ) - indices[i] = i; + char asize[32]; + vg_mem_print_size( info->buffer_size - info->stack_used_bytes, asize ); + ui_text( context->ui_ctx, out_box, asize, 1, k_ui_align_middle_center, 0 ); - u32 count = alloc->allocation_count; - _CB_values = alloc; - qsort( indices, count, sizeof(i32), _CB_vg_mem_sort ); - - for( u32 i=0; iallocation_count; i++ ) - { - i32 indice = indices[i]; - - vg_allocation_meta *meta = &alloc->alloc_table[indice]; - sizes[i] = sqrtf(meta->size); - } - - squarey_layout( rect, sizes, count, vg_mem_draw_cb, &inf ); - } - else - { - //printf( " (UNTRACKED)\n" ); - } + rect[ short_side^0x1 ] += h; + rect[ 2+short_side^0x1 ] -= h; } - else + + if( info->stack_children_count ) { - ui_fill( ctx, rect, 0x80101010 ); - //ui_text( ctx, rect, name, 1, k_ui_align_left, 0 ); + squarey_layout( rect, &context->mv->sizes[ info->stack_children_start ], info->stack_children_count, + vg_mem_draw_block_cb, context ); } + else + ui_fill( context->ui_ctx, rect, 0x80101010 ); } else - { - //vg_error( "allocations are not tracked (turn on libc mode)\n" ); - } + ui_fill( context->ui_ctx, rect, 0x80000000 ); } -struct mem_view_data -{ - void *main_buffer[8], - *inspecting; - v4f inspect_colour; - - const char *walk[8]; - - u32 depth; - - f32 vis_data[256*256]; - GLuint tex; -}; - -static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, - struct vg_magi_panel *magi ) +static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi ) { struct mem_view_data *mv = magi->data; - struct vg_mem_view_result result = { .target=NULL }; ui_rect left; ui_split( rect, k_ui_axis_v, 256+16, 2, left, rect ); @@ -237,118 +205,120 @@ static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, /* Tree back-tracker */ { - ui_rect bib = { left[0],left[1],left[2],24 }; - u32 new_depth = mv->depth; - for( u32 i=0; idepth+1; i ++ ) + ui_rect box = { left[0],left[1],left[2],24 }; + u32 new_depth = mv->route_depth; + for( u32 i=0; iroute_depth+1; i ++ ) { - if( i != mv->depth ) + struct mem_view_info *info = &mv->infos[ mv->route[i] ]; + if( i != mv->route_depth ) { - if( ui_button_text( ctx, bib, mv->walk[ i ], 1 ) == 1 ) + if( ui_button_text( ctx, box, info->display_name, 1 ) == 1 ) { new_depth = i; } } else { - ui_fill( ctx, bib, ui_colour( ctx, k_ui_bg ) ); - ui_text( ctx, bib, mv->walk[i], 1, k_ui_align_middle_center, 0 ); + ui_fill( ctx, box, ui_colour( ctx, k_ui_bg ) ); + ui_text( ctx, box, info->display_name, 1, k_ui_align_middle_center, 0 ); } - bib[0] += 8; - bib[2] -= 8; - bib[1] += 24; + box[0] += 8; + box[2] -= 8; + box[1] += 24; } - mv->depth = new_depth; - ui_px v = (mv->depth+1)*24; + mv->route_depth = new_depth; + ui_px v = (mv->route_depth+1)*24; left[1] += v; left[3] -= v; } - if( vg_mem.use_libc_malloc == 0 ) + struct vg_mem_draw_blocks_context context = { - ui_text( ctx, rect, "Run with --use-libc-malloc to view memory", - 1, k_ui_align_middle_center, 0 ); - return; - } - - vg_mem_view_ui( ctx, rect, mv->main_buffer[ mv->depth ], "", 0, &result ); - - if( result.target ) + .ui_ctx = ctx, + .mv = mv, + .root_colour = 0, + .root_id = mv->route[ mv->route_depth ], + .highlight_id = 0xffffffff, + .depth = 0 + }; + vg_mem_view_stack( &context, rect ); + + if( context.highlight_id != 0xffffffff ) { - ui_outline( ctx, result.target_rect, 1, ui_colour( ctx,k_ui_bg+7 ), 0 ); - ui_info( ctx, left, result.target->name ); + struct mem_view_info *highlight_info = &mv->infos[ context.highlight_id ]; + + ui_outline( ctx, context.highlight_rect, 1, ui_colour( ctx,k_ui_bg+7 ), 0 ); + ui_info( ctx, left, highlight_info->display_name ); char buf[32]; - vg_mem_print_size( result.target->size, buf ); + vg_mem_print_size( highlight_info->buffer_size, buf ); ui_info( ctx, left, buf ); - if( mv->inspecting != result.target->data ) + if( mv->vis_offset != highlight_info->buffer_offset ) { - if( result.target->type == k_allocation_type_block ) - { - for( u32 i=0; i<256*256; i++ ) mv->vis_data[i] = 0.0f; - f32 max_freq = 0.0f; - - const u8 *src = result.target->data; - for( u32 i=0; isize-1; i ++ ) - { - u8 x = src[i], y = src[i+1]; - u32 offset = y*256 + x; - - mv->vis_data[ offset ] += 1.0f; - max_freq = vg_maxf( mv->vis_data[ offset ], max_freq ); - } - - f32 median = 0.0f; - for( u32 i=0; i<256*256; i++ ) median += mv->vis_data[i]; - median /= 256.0f*256.0f; - - f32 inv_max = 1.0f/logf(1.0f+median*2.0f); - for( u32 i=0; i<256*256; i++ ) - { - f32 v = logf(mv->vis_data[i]) * inv_max; - mv->vis_data[i] = v; - } + mv->vis_offset = highlight_info->buffer_offset; + mv->vis_i = 0; + mv->vis_size = highlight_info->buffer_size; + mv->vis_dirty = 1; + mv->vis_inv_max = 1.0f; + + f32 nrm = 2.6f / 255.0f; + mv->vis_colour[0] = (f32)((context.highlight_colour ) & 0xff) * nrm; + mv->vis_colour[1] = (f32)((context.highlight_colour>>8 ) & 0xff) * nrm; + mv->vis_colour[2] = (f32)((context.highlight_colour>>16) & 0xff) * nrm; + mv->vis_colour[3] = 1.0f; + + for( u32 i=0; i<256*256; i++ ) + mv->vis_data[i] = 0.0f; + } - glBindTexture( GL_TEXTURE_2D, mv->tex ); - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 256, - GL_RED, GL_FLOAT, mv->vis_data ); + if( mv->vis_i+1 < mv->vis_size ) + { + const u8 *src = mv->base_buffer + mv->vis_offset; + for( u32 it=0; itvis_i+1 < mv->vis_size); it ++ ) + { + u8 x = src[mv->vis_i], y = src[mv->vis_i+1]; + u32 coord = y*256 + x; + mv->vis_data[ coord ] += 1.0f; + mv->vis_i ++; } - mv->inspecting = result.target->data; + f32 median = (f32)mv->vis_i; + mv->vis_inv_max = 1.0f/logf(1.0f+median*2.0f); + mv->vis_dirty = 1; + } - f32 nrm = 1.6f / 255.0f; - mv->inspect_colour[0] = (f32)((result.colour ) & 0xff) * nrm; - mv->inspect_colour[1] = (f32)((result.colour>>8 ) & 0xff) * nrm; - mv->inspect_colour[2] = (f32)((result.colour>>16) & 0xff) * nrm; - mv->inspect_colour[3] = 1.0f; + if( mv->vis_dirty ) + { + glBindTexture( GL_TEXTURE_2D, mv->vis_tex ); + glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RED, GL_FLOAT, mv->vis_data ); } - if( result.target->type == k_allocation_type_block ) - ui_info( ctx, left, "Leaf" ); - else + if( highlight_info->is_stack ) ui_info( ctx, left, "Linear Allocator (expand)" ); + else + ui_info( ctx, left, "Leaf" ); - if( result.target->type == k_allocation_type_block ) - { - ui_rect freq_box = { left[0]+8, left[1], 256,256 }; - - ui_flush( ctx, k_ui_shader_colour, NULL ); - ui_fill_rect( ctx, freq_box, 0xffffffff, (ui_px[4]){ 0,256,256,0 } ); - struct ui_batch_shader_data_image inf = { .resource = &mv->tex }; - v4_copy( mv->inspect_colour, vg_ui.colour ); - ui_flush( ctx, k_ui_shader_grad, &inf ); - v4_copy( (v4f){1,1,1,1}, vg_ui.colour ); - } + ui_rect freq_box = { left[0]+8, left[1], 256,256 }; - if( result.target->type == k_allocation_type_linear ) + ui_flush( ctx, k_ui_shader_colour, NULL ); + ui_fill_rect( ctx, freq_box, 0xffffffff, (ui_px[4]){ 0,256,256,0 } ); + struct ui_batch_shader_data_image_gradient inf = { + .resource = &mv->vis_tex, + .log = 1, + .scale = mv->vis_inv_max + }; + v4_copy( mv->vis_colour, vg_ui.colour ); + ui_flush( ctx, k_ui_shader_grad, &inf ); + v4_copy( (v4f){1,1,1,1}, vg_ui.colour ); + + if( highlight_info->is_stack ) { if( ui_click_down( ctx, UI_MOUSE_LEFT ) ) { - mv->main_buffer[ mv->depth+1 ] = result.target->data; - mv->walk[ mv->depth+1 ] = result.target->name; - mv->inspecting = NULL; - mv->depth ++; + mv->route_depth ++; + mv->route[ mv->route_depth ] = context.highlight_id; } } } @@ -357,59 +327,185 @@ static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, static void cb_mem_view_close( struct vg_magi_panel *me ) { struct mem_view_data *mv = me->data; - glDeleteTextures( 1, &mv->tex ); - free( me->data ); + glDeleteTextures( 1, &mv->vis_tex ); + vg_free( me->data ); } static struct { const char *name; - void **buffer; + vg_stack_allocator *stack; } _vg_mem_named_buffers[] = { - { "rtmemory", &vg_mem.rtmemory }, - { "scratch", &vg_mem.scratch } + { "rtmem", &vg.rtmem }, }; +int _CB_vg_mem_infosort( const void *a, const void *b ) +{ + const struct mem_view_info *info_a = a, + *info_b = b; + return (i32)(info_a->buffer_size < info_b->buffer_size) - (i32)(info_a->buffer_size > info_b->buffer_size); +} + static int cmd_vg_mem_view( int argc, const char *argv[] ) { - if( argc == 1 ) + if( argc != 1 ) { - for( u32 i=0; i\n" ); + return 0; + } + + for( u32 i=0; ititle = "Memory outliner"; + + struct mem_view_data *mv = vg_malloc(sizeof(struct mem_view_data)); + mv->route[0] = 0; + mv->route_depth = 0; + mv->vis_offset = 0xffffffff; + mv->info_count = 1; + + /* cache all allocations in full tree */ + struct route_frame { - ui_px w = 512+16, - h = 512; - struct vg_magi_panel *magi = _vg_magi_open( w,h, VG_MAGI_ALL ); - magi->title = "Memory outliner"; - - struct mem_view_data *mv = malloc(sizeof(struct mem_view_data)); - mv->main_buffer[0] = *_vg_mem_named_buffers[i].buffer; - mv->walk[0] = _vg_mem_named_buffers[i].name; - mv->depth = 0; - mv->inspecting = NULL; - - glGenTextures( 1, &mv->tex ); - glBindTexture( GL_TEXTURE_2D, mv->tex ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 256,256, 0, - GL_RED, GL_FLOAT, NULL ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - - magi->data = mv; - magi->ui_cb = cb_vg_mem_view; - magi->close_cb = cb_mem_view_close; - return 1; + bool init; + vg_stack_allocator *stack; + struct mem_view_info *info; + u32 buffer_base_offset; + + u32 descend_i; } - } + route[8]; + u32 route_depth = 0; + + route[0].init = 0; + route[0].stack = _vg_mem_named_buffers[i].stack; + route[0].info = &mv->infos[ 0 ]; + route[0].buffer_base_offset = 0; + route[0].descend_i = 0; + + mv->infos[0].display_name = _vg_mem_named_buffers[i].name; + mv->infos[0].buffer_offset = 0; + mv->infos[0].buffer_size = _vg_mem_named_buffers[i].stack->capacity; + mv->infos[0].is_stack = 1; + mv->infos[0].stack_used_bytes = _vg_mem_named_buffers[i].stack->used; + mv->sizes[0] = sqrtf(mv->infos[0].buffer_size); + + mv->base_buffer = _vg_mem_named_buffers[i].stack->data; + + l0:{ + struct route_frame *frame = &route[ route_depth ]; + + if( !frame->init ) + { + frame->init = 1; + frame->info->stack_children_start = mv->info_count; + frame->info->stack_children_count = 0; + + /* create array of all immediate child allocations */ + u32 offset = frame->stack->used - frame->stack->last_allocation_totalsize; + + if( (frame->stack->used == 0) || !(frame->stack->flags & VG_STACK_ALLOCATOR_METADATA) ) + goto l1; + + l2:{ + vg_allocation_meta *meta = frame->stack->data + offset; + + if( mv->info_count == VG_ARRAY_LEN(mv->infos) ) + { + vg_error( "Reached maximum allocation infos! (%u)\n", mv->info_count ); + goto e1; + } + + struct mem_view_info *info = &mv->infos[ mv->info_count ]; + info->display_name = meta->name; + info->buffer_offset = frame->buffer_base_offset + offset + sizeof(vg_allocation_meta); + info->buffer_size = meta->size; + + mv->info_count ++; + frame->info->stack_children_count ++; + + if( meta->flags & VG_ALLOCATION_FLAG_IS_STACK ) + { + info->is_stack = 1; + vg_stack_allocator *substack = mv->base_buffer + info->buffer_offset; + + info->stack_used_bytes = substack->used; + info->stack_children_start = 0; /* deferred to !frame->init */ + info->stack_children_count = 0; + } + else + info->is_stack = 0; + + if( offset ) + { + offset = meta->previous_offset; + goto l2; + } + } + } + + l1: if( frame->descend_i < frame->info->stack_children_count ) + { + struct mem_view_info *info = &mv->infos[ frame->info->stack_children_start + frame->descend_i ]; + frame->descend_i ++; + + if( info->is_stack ) + { + route_depth ++; + + struct route_frame *next_frame = &route[ route_depth ]; + next_frame->init = 0; + next_frame->stack = mv->base_buffer + info->buffer_offset; + next_frame->info = info; + next_frame->buffer_base_offset = info->buffer_offset + sizeof(vg_stack_allocator); + next_frame->descend_i = 0; + + goto l0; + } + else goto l1; + } + else + { + /* Sort children by size, calculate sqrt f32 sizes, and step down */ + qsort( &mv->infos[ frame->info->stack_children_start ], frame->info->stack_children_count, + sizeof(struct mem_view_info), _CB_vg_mem_infosort ); + + for( u32 i=0; iinfo->stack_children_count; i ++ ) + { + u32 index = frame->info->stack_children_start + i; + struct mem_view_info *info = &mv->infos[ index ]; + mv->sizes[ index ] = sqrtf(info->buffer_size); + } + + if( route_depth ) + { + route_depth --; + goto l0; + } + } + } + + vg_success( "Cached %u allocations.\n", mv->info_count ); + + e1: glGenTextures( 1, &mv->vis_tex ); + glBindTexture( GL_TEXTURE_2D, mv->vis_tex ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 256,256, 0, GL_RED, GL_FLOAT, NULL ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - vg_error( "No named buffer '%s'\n", argv[0] ); + magi->data = mv; + magi->ui_cb = cb_vg_mem_view; + magi->close_cb = cb_mem_view_close; + return 1; + } } - else - vg_error( "Usage: vg_mem_view \n" ); + vg_error( "No named buffer '%s'\n", argv[0] ); return 0; } diff --git a/vg_render.c b/vg_render.c index 7c63978..eadd59f 100644 --- a/vg_render.c +++ b/vg_render.c @@ -78,13 +78,11 @@ void vg_render_init(void) #ifdef VG_3D vg_console_reg_var( "blur_strength", &_vg_postprocess.blur_strength, k_var_dtype_f32, 0 ); vg_console_reg_var( "blur_effect", &_vg_postprocess.blur_effect, k_var_dtype_i32, VG_VAR_PERSISTENT ); - - void *alloc = vg_mem.rtmemory; /* * Main framebuffer */ - _vg_render.fb_main = vg_framebuffer_allocate( alloc, 3, 1 ); + _vg_render.fb_main = vg_framebuffer_allocate( &vg.rtmem, 3, 1 ); _vg_render.fb_main->display_name = "main"; _vg_render.fb_main->resolution_div = 1; _vg_render.fb_main->attachments[0] = (vg_framebuffer_attachment) @@ -119,7 +117,7 @@ void vg_render_init(void) /* * Water reflection */ - _vg_render.fb_water_reflection = vg_framebuffer_allocate( alloc, 2, 1 ); + _vg_render.fb_water_reflection = vg_framebuffer_allocate( &vg.rtmem, 2, 1 ); _vg_render.fb_water_reflection->display_name = "water_reflection"; _vg_render.fb_water_reflection->resolution_div = 2; _vg_render.fb_water_reflection->attachments[0] = (vg_framebuffer_attachment) @@ -142,7 +140,7 @@ void vg_render_init(void) * Thid rendered view from the perspective of the camera, but just * captures stuff thats under the water */ - _vg_render.fb_water_beneath = vg_framebuffer_allocate( alloc, 2, 1 ); + _vg_render.fb_water_beneath = vg_framebuffer_allocate( &vg.rtmem, 2, 1 ); _vg_render.fb_water_beneath->display_name = "water_beneath"; _vg_render.fb_water_beneath->resolution_div = 2; _vg_render.fb_water_beneath->attachments[0] = (vg_framebuffer_attachment) diff --git a/vg_steam_auth.h b/vg_steam_auth.h index f0cd8cc..ca97b0f 100644 --- a/vg_steam_auth.h +++ b/vg_steam_auth.h @@ -56,88 +56,3 @@ steamapi_bool SteamAPI_ISteamUser_GetEncryptedAppTicket( int cbMaxTicket, u32 *pcbTicket ); u64_steamid SteamAPI_ISteamUser_GetSteamID( ISteamUser *self ); - - -/* - * Application symetric-key ticket method (Server) - */ - -enum { k_nSteamEncryptedAppTicketSymmetricKeyLen = 32 }; - -steamapi_bool SteamEncryptedAppTicket_BDecryptTicket( u8 *rgubTicketEncrypted, - u32 cubTicketEncrypted, u8 *rgubTicketDecrypted, - u32 *pcubTicketDecrypted, - u8 rgubKey[k_nSteamEncryptedAppTicketSymmetricKeyLen], - int cubKey ); - -steamapi_bool SteamEncryptedAppTicket_BIsTicketForApp( u8 *rgubTicketDecrypted, - u32 cubTicketDecrypted, AppId_t nAppID ); - -RTime32 SteamEncryptedAppTicket_GetTicketIssueTime( u8 *rgubTicketDecrypted, - u32 cubTicketDecrypted ); - -void SteamEncryptedAppTicket_GetTicketSteamID( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, CSteamID *psteamID ); - -AppId_t SteamEncryptedAppTicket_GetTicketAppID( u8 *rgubTicketDecrypted, - u32 cubTicketDecrypted ); - -steamapi_bool SteamEncryptedAppTicket_BUserOwnsAppInTicket( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, AppId_t nAppID ); - -steamapi_bool SteamEncryptedAppTicket_BUserIsVacBanned( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted ); - -steamapi_bool SteamEncryptedAppTicket_BGetAppDefinedValue( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, u32 *pValue ); - -u8 *SteamEncryptedAppTicket_GetUserVariableData( u8 *rgubTicketDecrypted, - u32 cubTicketDecrypted, u32 *pcubUserData ); - -steamapi_bool SteamEncryptedAppTicket_BIsTicketSigned( u8 *rgubTicketDecrypted, - u32 cubTicketDecrypted, u8 *pubRSAKey, u32 cubRSAKey ); - -steamapi_bool SteamEncryptedAppTicket_BIsLicenseBorrowed( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted ); - -steamapi_bool SteamEncryptedAppTicket_BIsLicenseTemporary( - u8 *rgubTicketDecrypted, u32 cubTicketDecrypted ); - -static inline u8 vg_char_base16( char c ) -{ - if( c >= '0' && c <= '9' ) - return c-'0'; - if( c >= 'a' && c <= 'f' ) - return (c-'a') + 10; - - return 0; -} - -static inline int vg_load_steam_symetric_key( const char *path, u8 *buf ) -{ - vg_linear_clear( vg_mem.scratch ); - u32 size; - char *src = vg_file_read( vg_mem.scratch, path, &size ); - - if( src ) - { - if( size < k_nSteamEncryptedAppTicketSymmetricKeyLen ) - { - vg_error( "Application key was invalid size\n" ); - return 0; - } - - for( int i=0; i= '0' && c <= '9' ) + return c-'0'; + if( c >= 'a' && c <= 'f' ) + return (c-'a') + 10; + + return 0; +} + +static inline int vg_load_steam_symetric_key( const char *path, u8 *buf ) +{ + vg_stack_allocator stack; + vg_stack_init( &stack, NULL, VG_KB(256), NULL ); + + u32 size; + char *src = vg_file_read( &stack, path, &size, 0 ); + + if( src ) + { + if( size < k_nSteamEncryptedAppTicketSymmetricKeyLen ) + { + vg_error( "Application key was invalid size\n" ); + return 0; + } + + for( int i=0; imap[ glyph ]; @@ -443,6 +442,9 @@ u32 ui_ntext( ui_context *ctx, ui_rect rect, const char *str, u32 len, ui_px scale, enum ui_align align, u32 colour ) { + if( str == NULL ) + str = "NULL"; + ui_px glow_text = 0; ui_rect text_cursor; @@ -597,9 +599,7 @@ u32 ui_ntext( ui_context *ctx, return printed_chars; } -u32 ui_text( ui_context *ctx, - ui_rect rect, const char *str, ui_px scale, - enum ui_align align, u32 colour ) +u32 ui_text( ui_context *ctx, ui_rect rect, const char *str, ui_px scale, enum ui_align align, u32 colour ) { return ui_ntext( ctx, rect, str, 1024, scale, align, colour ); } @@ -2035,8 +2035,7 @@ void ui_dev_colourview( ui_context *ctx ) if( names[i] ) { - ui_text( ctx, swatch, names[i], 1, - k_ui_align_middle_left, ui_colourcont(ctx,i)); + ui_text( ctx, swatch, names[i], 1, k_ui_align_middle_left, ui_colourcont(ctx,i)); } } } diff --git a/vg_ui/imgui.h b/vg_ui/imgui.h index 25f360c..8ce4782 100644 --- a/vg_ui/imgui.h +++ b/vg_ui/imgui.h @@ -235,6 +235,13 @@ struct ui_batch_shader_data_image void *resource; }; +struct ui_batch_shader_data_image_gradient +{ + void *resource; + bool log; + f32 scale; +}; + struct ui_batch { ui_vert *vert_buf; /* base vertex array + [vert_offset] */ diff --git a/vg_ui/imgui_impl_opengl.c b/vg_ui/imgui_impl_opengl.c index 0810ec7..8f7b1bb 100644 --- a/vg_ui/imgui_impl_opengl.c +++ b/vg_ui/imgui_impl_opengl.c @@ -197,6 +197,9 @@ static struct vg_shader _shader_ui_image_grad = { .static_src = "uniform sampler2D uTexImage;" "uniform vec4 uColour;" + "uniform int uLog;" + "uniform float uScale;" + "out vec4 FragColor;" "in vec2 aTexCoords;" @@ -206,7 +209,12 @@ static struct vg_shader _shader_ui_image_grad = { "void main()" "{" "vec4 colour = texture( uTexImage, aTexCoords );" - "FragColor = vec4(vec3(colour.r)*uColour.rgb,1.0);" + "float v = colour.r;" + "if( uLog == 1 ){" + "v = log(v);" + "}" + "v *= uScale;" + "FragColor = vec4(vec3(v)*uColour.rgb,1.0);" "}" } }; @@ -321,15 +329,14 @@ void ui_impl_render_batch( ui_context *ctx, ui_batch *batch, else if( shader == k_ui_shader_grad ) { glUseProgram( _shader_ui_image_grad.id ); - glUniformMatrix3fv( - glGetUniformLocation( _shader_ui_image_grad.id, "uPv" ), 1, - GL_FALSE, (float *)vg_ui.pv ); - glUniform1i( - glGetUniformLocation(_shader_ui_image_grad.id,"uTexImage"), 0 ); - glUniform4fv( glGetUniformLocation( _shader_ui_image.id, "uColour" ), 1, - vg_ui.colour ); + glUniformMatrix3fv( glGetUniformLocation( _shader_ui_image_grad.id, "uPv" ), 1, GL_FALSE, (float *)vg_ui.pv ); + glUniform1i( glGetUniformLocation(_shader_ui_image_grad.id,"uTexImage"), 0 ); + glUniform4fv( glGetUniformLocation( _shader_ui_image.id, "uColour" ), 1, vg_ui.colour ); + + struct ui_batch_shader_data_image_gradient *inf = shader_data; + glUniform1i( glGetUniformLocation(_shader_ui_image_grad.id,"uLog"), inf->log ); + glUniform1f( glGetUniformLocation(_shader_ui_image_grad.id,"uScale"), inf->scale ); - struct ui_batch_shader_data_image *inf = shader_data; GLuint *image = inf->resource; glActiveTexture( GL_TEXTURE0 ); @@ -339,8 +346,7 @@ void ui_impl_render_batch( ui_context *ctx, ui_batch *batch, { struct ui_batch_shader_data_hsv *inf = shader_data; glUseProgram( _shader_ui_hsv.id ); - glUniformMatrix3fv( glGetUniformLocation( _shader_ui_hsv.id, "uPv" ), 1, - GL_FALSE, (float *)vg_ui.pv ); + glUniformMatrix3fv( glGetUniformLocation( _shader_ui_hsv.id, "uPv" ), 1, GL_FALSE, (float *)vg_ui.pv ); glUniform1f( glGetUniformLocation(_shader_ui_hsv.id,"uHue"), inf->hue ); } else @@ -527,8 +533,8 @@ void vg_ui_init(void) total = sheet->w*sheet->h, data = 0; - vg_linear_clear( vg_mem.scratch ); - u8 *image = vg_linear_alloc( vg_mem.scratch, total ); + vg_stack_clear( &vg.scratch ); + u8 *image = vg_stack_allocate( &vg.scratch, total, 8, NULL ); while( pixels < total ) { -- 2.25.1