From dbcb05d2d1eee11d53eec3fe22776dc5fe1ead87 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 12 Jan 2020 23:16:03 +0200 Subject: [PATCH] Fixed a performance issue regarding timers. Now we can start a single timer per step request. --- metal/4ed_metal_render.mm | 2 +- platform_mac/mac_4ed.mm | 58 ++++++++++++++++++++++++++----- platform_mac/mac_4ed_functions.mm | 13 ++++--- platform_mac/mac_4ed_renderer.h | 4 ++- platform_mac/mac_4ed_renderer.mm | 25 +++++-------- 5 files changed, 72 insertions(+), 30 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 6f8b1a20..9aab846a 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -290,7 +290,7 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Obtain the render pass descriptor from the renderer's view MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; if (render_pass_descriptor != nil){ - render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0.0f, 1.0f, 1.0f); + render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); // NOTE(yuval): Create the render command encoder id render_encoder diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 470c7365..047086de 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -195,6 +195,7 @@ struct Mac_Vars { mach_timebase_info_data_t timebase_info; b32 first; + b32 step_requested; void *base_ptr; u64 timer_start; @@ -459,15 +460,18 @@ mac_resize(NSWindow *window){ mac_resize(bounds.size.width, bounds.size.height); } +#if defined(FRED_INTERNAL) function inline void mac_profile(char *name, u64 begin, u64 end){ printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); } #define MacProfileScope(name) for (u64 i = 0, begin = system_now_time();\ -i < 1;\ -++i, mac_profile(name, begin, system_now_time())) - +i == 0;\ +i = 1, mac_profile(name, begin, system_now_time())) +#else +# define MacProfileScope(...) +#endif //////////////////////////////// @implementation FCoder_App_Delegate @@ -539,8 +543,10 @@ i < 1;\ } - (void)drawRect:(NSRect)bounds{ - MacProfileScope("Frame"){ - MacProfileScope("Acquire System Mutex"){ + u64 prev_timer_start; + + MacProfileScope("Draw Rect"){ + MacProfileScope("Acquire Frame Mutex"){ // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_acquire(mac_vars.global_frame_mutex); } @@ -606,14 +612,44 @@ i < 1;\ } } + // NOTE(yuval): Sleep a bit to cool off + MacProfileScope("Cool Down"){ + system_mutex_release(mac_vars.global_frame_mutex); + { + u64 timer_end = system_now_time(); + u64 end_target = (mac_vars.timer_start + frame_useconds); + + if (timer_end < end_target){ + if ((end_target - timer_end) > 1000){ + // NOTE(yuval): Sleep until the end target minus a millisecond (to allow the scheduler to wake the process in time) + system_sleep(end_target - timer_end - 1000); + } + + // NOTE(yuval): Iterate through the rest of the time that's left using a regular for loop to make sure that we hit the end target + u64 now = system_now_time(); + while (now < end_target){ + now = system_now_time(); + } + } + + prev_timer_start = mac_vars.timer_start; + mac_vars.timer_start = system_now_time(); + } + system_mutex_acquire(mac_vars.global_frame_mutex); + } + MacProfileScope("Cleanup"){ mac_vars.first = false; + mac_vars.step_requested = false; linalloc_clear(mac_vars.frame_arena); + // NOTE(yuval): Release the global frame mutex until the next drawRect call system_mutex_release(mac_vars.global_frame_mutex); } } + + mac_profile("Frame", prev_timer_start, mac_vars.timer_start); printf("\n"); } @@ -762,6 +798,7 @@ i < 1;\ } - (void)request_display{ + printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; @@ -829,7 +866,9 @@ i < 1;\ - (void)process_mouse_move_event:(NSEvent*)event{ NSPoint location = [event locationInWindow]; - Vec2_i32 new_m = V2i32(location.x, mac_vars.height - location.y); + NSPoint backing_location = [self convertPointToBacking:location]; + + Vec2_i32 new_m = V2i32(backing_location.x, mac_vars.height - backing_location.y); if (new_m != mac_vars.input_chunk.pers.mouse){ mac_vars.input_chunk.pers.mouse = new_m; } @@ -854,7 +893,7 @@ main(int arg_count, char **args){ pthread_mutex_init(&memory_tracker_mutex, 0); - // NOTE(yuval): Context Setup + // NOTE(yuval): Context setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, get_base_allocator_system(), @@ -1048,9 +1087,11 @@ main(int arg_count, char **args){ mac_resize(w, h); // - // TODO(yuval): Misc System Initializations + // NOTE(yuval): Misc System Initializations // + // TODO(yuval): Initialize clipboard buffer + mac_keycode_init(); // NOTE(yuval): Get the timebase info @@ -1072,6 +1113,7 @@ main(int arg_count, char **args){ // mac_vars.first = true; + mac_vars.step_requested = false; mac_vars.global_frame_mutex = system_mutex_make(); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index a39faae5..69275512 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,10 +406,15 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ - [NSTimer scheduledTimerWithTimeInterval:0.0 - target:mac_vars.view - selector:@selector(request_display) - userInfo:nil repeats:NO]; + printf("Signal Step!\n"); + if (!mac_vars.step_requested){ + [NSTimer scheduledTimerWithTimeInterval:0.0 + target:mac_vars.view + selector:@selector(request_display) + userInfo:nil repeats:NO]; + + mac_vars.step_requested = true; + } } function diff --git a/platform_mac/mac_4ed_renderer.h b/platform_mac/mac_4ed_renderer.h index 0d1d4caf..ecc11ff2 100644 --- a/platform_mac/mac_4ed_renderer.h +++ b/platform_mac/mac_4ed_renderer.h @@ -21,7 +21,9 @@ typedef mac_fill_texture_sig(mac_fill_texture_type); typedef i32 Mac_Renderer_Kind; enum{ MacRenderer_OpenGL, - MacRenderer_Metal + MacRenderer_Metal, + // + MacRenderer_COUNT }; struct Mac_Renderer{ diff --git a/platform_mac/mac_4ed_renderer.mm b/platform_mac/mac_4ed_renderer.mm index 5b4e4015..7ad171b6 100644 --- a/platform_mac/mac_4ed_renderer.mm +++ b/platform_mac/mac_4ed_renderer.mm @@ -4,25 +4,18 @@ #import "mac_4ed_opengl.mm" #import "mac_4ed_metal.mm" +// TODO(yuval): Replace this array with an array of the paths to the renderer dlls +global mac_load_renderer_type *mac_renderer_load_functions[MacRenderer_COUNT] = { + mac_load_opengl_renderer, + mac_load_metal_renderer +}; + function Mac_Renderer* mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *target){ - // TODO(yuval): Import renderer load function from a DLL instead of using a switch statement and a renderer kind. This would allow us to switch the renderer backend and implemented new backends with ease. + // TODO(yuval): Import renderer load function from a DLL instead of using an array of the load functions. This would allow us to switch the renderer backend and implemented new backends with ease. - Mac_Renderer *result = 0; - - switch (kind){ - case MacRenderer_OpenGL: - { - result = mac_load_opengl_renderer(window, target); - } break; - - case MacRenderer_Metal: - { - result = mac_load_metal_renderer(window, target); - } break; - - default: InvalidPath; - } + mac_load_renderer_type *load_renderer = mac_renderer_load_functions[kind]; + Mac_Renderer *result = load_renderer(window, target); if (!result){ mac_error_box("Unable to initialize the renderer!");