diff options
| author | Aldrik Ramaekers <aldrik.ramaekers@protonmail.com> | 2020-06-17 17:34:54 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrik.ramaekers@protonmail.com> | 2020-06-17 17:34:54 +0200 |
| commit | 2f552b15aa9e0aa80488c00c2190e9a25b578f87 (patch) | |
| tree | 784db7ef5c91c1f5ff03d7be4aa749b1d25f01c1 | |
| parent | db24b566ba1be51255b98aafc34a117aaec65f39 (diff) | |
refactoring
| -rw-r--r-- | src/assets.c | 30 | ||||
| -rw-r--r-- | src/assets.h | 5 | ||||
| -rw-r--r-- | src/linux/platform.c | 16 | ||||
| -rw-r--r-- | src/memory.h | 176 | ||||
| -rw-r--r-- | src/windows/platform.c | 14 |
5 files changed, 233 insertions, 8 deletions
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 <stdio.h> +#include <dbghelp.h> + +#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;
|
