From 2f552b15aa9e0aa80488c00c2190e9a25b578f87 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Wed, 17 Jun 2020 17:34:54 +0200 Subject: refactoring --- src/assets.c | 30 +++++++++ src/assets.h | 5 ++ src/linux/platform.c | 16 +++++ src/memory.h | 176 +++++++++++++++++++++++++++++++++++++++++++++++-- src/windows/platform.c | 14 +++- 5 files changed, 233 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/assets.c b/src/assets.c index e693d7f..e2452fb 100644 --- a/src/assets.c +++ b/src/assets.c @@ -33,8 +33,38 @@ inline static bool is_big_endian() return !((*((uint8_t*)(&i))) == 0x67); } +void assets_stop_if_done() +{ + if (global_asset_collection.queue.queue.length == 0 && !global_asset_collection.done_loading_assets) + { + global_asset_collection.done_loading_assets = true; + +#ifdef MODE_TIMESTARTUP + abort(); +#endif + +#if defined(MODE_DEBUGMEM) && !defined(MODE_TEST) + printf("allocated at startup: %dkb\n", __total_allocated/1000); + printf("reallocated at startup: %dkb\n", __total_reallocated/1000); +#endif + +#if defined(MODE_DEVELOPER) && !defined(MODE_TEST) + printf("frames drawn with missing assets: %d\n", __frames_drawn_with_missing_assets); +#endif + } + +#ifdef MODE_DEVELOPER + if (global_asset_collection.queue.queue.length != 0 && !global_asset_collection.done_loading_assets) + { + __frames_drawn_with_missing_assets++; + } +#endif +} + bool assets_do_post_process() { + assets_stop_if_done(); + bool result = false; mutex_lock(&asset_mutex); diff --git a/src/assets.h b/src/assets.h index 983ff41..1b0a6e7 100644 --- a/src/assets.h +++ b/src/assets.h @@ -19,6 +19,11 @@ #define ASSET_QUEUE_COUNT 20 #endif +#ifdef MODE_DEVELOPER +s32 __frames_drawn_with_missing_assets = 0; +#endif + + typedef struct t_image { u8 *start_addr; u8 *end_addr; diff --git a/src/linux/platform.c b/src/linux/platform.c index d654cac..5b94d92 100644 --- a/src/linux/platform.c +++ b/src/linux/platform.c @@ -58,6 +58,7 @@ struct t_platform_window Atom _NET_WM_STATE; // shared window properties + bool icon_loaded; bool do_draw; backbuffer backbuffer; s32 width; @@ -676,6 +677,15 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m bool has_max_size = max_w || max_h; platform_window window; + window.width = width; + window.height = height; + window.min_width = min_w; + window.min_height = min_h; + window.max_width = max_w; + window.max_height = max_h; + window.backbuffer.buffer = 0; + window.gl_context = 0; + window.icon_loaded = false; window.has_focus = true; window.curr_cursor_type = CURSOR_DEFAULT; window.next_cursor_type = CURSOR_DEFAULT; @@ -1587,6 +1597,12 @@ inline void platform_run_command(char *command) void platform_set_icon(platform_window *window, image *img) { + if (!img->loaded) return; + if (!window->icon_loaded) + window->icon_loaded = true; + else + return; + s32 w = img->width; s32 h = img->height; diff --git a/src/memory.h b/src/memory.h index 1457f21..0ebd070 100644 --- a/src/memory.h +++ b/src/memory.h @@ -7,14 +7,180 @@ #ifndef INCLUDE_MEMORY #define INCLUDE_MEMORY -#ifdef MODE_DEVELOPER +#ifdef MODE_DEBUGMEM +#include +#include + +#define MEM_ENTRY_BUFFER_SIZE 50000 + +typedef struct t_mem_entry +{ + bool valid; + void *p; + s32 size; + char *stacktrace; +} __mem_entry; + +static __mem_entry *mem_entries; + static s32 __total_allocated = 0; static s32 __total_reallocated = 0; -#define mem_alloc(size) malloc(size); __total_allocated+=size -#define mem_free(p) free(p) -#define mem_realloc(p, size) realloc(p, size); __total_reallocated+=size -#define memory_print_leaks() {} +static void* __custom_alloc(s32 size) +{ + if (mem_entries == 0) { + mem_entries = malloc(sizeof(__mem_entry)*MEM_ENTRY_BUFFER_SIZE); + memset(mem_entries, 0, MEM_ENTRY_BUFFER_SIZE); + } + + void* newp = malloc(size); + + bool found = false; + for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++) + { + if (!mem_entries[i].valid) + { +#ifdef OS_WIN + HANDLE process = GetCurrentProcess(); + HANDLE thread = GetCurrentThread(); + + CONTEXT context; + memset(&context, 0, sizeof(CONTEXT)); + context.ContextFlags = CONTEXT_FULL; + RtlCaptureContext(&context); + + SymInitialize(process, NULL, TRUE); + + DWORD image; + STACKFRAME64 stackframe; + ZeroMemory(&stackframe, sizeof(STACKFRAME64)); + +#ifdef _M_IX86 + image = IMAGE_FILE_MACHINE_I386; + stackframe.AddrPC.Offset = context.Eip; + stackframe.AddrPC.Mode = AddrModeFlat; + stackframe.AddrFrame.Offset = context.Ebp; + stackframe.AddrFrame.Mode = AddrModeFlat; + stackframe.AddrStack.Offset = context.Esp; + stackframe.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + image = IMAGE_FILE_MACHINE_AMD64; + stackframe.AddrPC.Offset = context.Rip; + stackframe.AddrPC.Mode = AddrModeFlat; + stackframe.AddrFrame.Offset = context.Rsp; + stackframe.AddrFrame.Mode = AddrModeFlat; + stackframe.AddrStack.Offset = context.Rsp; + stackframe.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + image = IMAGE_FILE_MACHINE_IA64; + stackframe.AddrPC.Offset = context.StIIP; + stackframe.AddrPC.Mode = AddrModeFlat; + stackframe.AddrFrame.Offset = context.IntSp; + stackframe.AddrFrame.Mode = AddrModeFlat; + stackframe.AddrBStore.Offset = context.RsBSP; + stackframe.AddrBStore.Mode = AddrModeFlat; + stackframe.AddrStack.Offset = context.IntSp; + stackframe.AddrStack.Mode = AddrModeFlat; +#endif + + mem_entries[i].stacktrace = malloc(4000); + mem_entries[i].stacktrace[0] = 0; + + for (size_t x = 0; i < 25; x++) { + + BOOL result = StackWalk64( + image, process, thread, + &stackframe, &context, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL); + + if (!result) { break; } + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + + DWORD64 displacement = 0; + if (SymFromAddr(process, stackframe.AddrPC.Offset, &displacement, symbol)) { + char tmp[100]; + snprintf(tmp, 100, "[%I64i] %s\n", x, symbol->Name); + strncat(mem_entries[i].stacktrace, tmp, 4000-1); + } else { + char tmp[100]; + snprintf(tmp, 100, "[%I64i] ???\n", x); + strncat(mem_entries[i].stacktrace, tmp, 4000-1); + } + + } + + SymCleanup(process); + +#endif + + mem_entries[i].valid = true; + mem_entries[i].p = newp; + mem_entries[i].size = size; + found = true; + break; + } + } + + if (!found) assert(0 && "memory entry buffer too small"); + + __total_allocated+=size; + return newp; +} + +static void* __custom_realloc(void *p, s32 size) +{ + for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++) + { + if (mem_entries[i].valid && mem_entries[i].p == p) + { + __total_allocated-=mem_entries[i].size; + __total_allocated+=size; + mem_entries[i].size = size; + break; + } + } + + __total_reallocated+=size; + return realloc(p, size); +} + +static void __custom_free(void *p) +{ + for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++) + { + if (mem_entries[i].valid && mem_entries[i].p == p) + { + __total_allocated-=mem_entries[i].size; + mem_entries[i].valid = false; + break; + } + } + + free(p); +} + +static void __custom_print_leaks() +{ + printf("\n\n********LEAK LIST********\n"); + for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++) + { + if (mem_entries[i].valid) + { + printf("%p: %d\n", mem_entries[i].p, mem_entries[i].size); + printf("%s\n", mem_entries[i].stacktrace); + } + } + getch(); +} + +#define mem_alloc(size) __custom_alloc(size) +#define mem_free(p) __custom_free(p) +#define mem_realloc(p, size) __custom_realloc(p, size); +#define memory_print_leaks() __custom_print_leaks() #else diff --git a/src/windows/platform.c b/src/windows/platform.c index a58a152..adbc053 100644 --- a/src/windows/platform.c +++ b/src/windows/platform.c @@ -27,6 +27,7 @@ struct t_platform_window s32 max_height; // shared window properties + bool icon_loaded; bool do_draw; backbuffer backbuffer; s32 width; @@ -673,6 +674,7 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m window.backbuffer.buffer = 0; window.do_draw = true; window.gl_context = 0; + window.icon_loaded = false; current_window_to_handle = &window; @@ -741,15 +743,15 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m platform_setup_backbuffer(&window); debug_print_elapsed(startup_stamp, "backbuffer"); + platform_setup_renderer(); + debug_print_elapsed(startup_stamp, "renderer"); + ShowWindow(window.window_handle, cmd_show); if (flags & FLAGS_HIDDEN) ShowWindow(window.window_handle, SW_HIDE); else ShowWindow(window.window_handle, SW_SHOW); - platform_setup_renderer(); - debug_print_elapsed(startup_stamp, "renderer"); - window.is_open = true; TRACKMOUSEEVENT track; @@ -1320,6 +1322,12 @@ void platform_init(int argc, char **argv) void platform_set_icon(platform_window *window, image *img) { + if (!img->loaded) return; + if (!window->icon_loaded) + window->icon_loaded = true; + else + return; + // NOTE only works with bmps currently; remove #if 0 to enable png again.. // we should probably change png color alignment so png and bmp data is the same in memory BYTE *bmp; -- cgit v1.2.3-70-g09d2