diff --git a/src/app.c b/src/app.c index 827507e0..669c3400 100644 --- a/src/app.c +++ b/src/app.c @@ -279,16 +279,14 @@ void sys_app_entry(struct string args_str) #endif /* Startup systems */ - struct resource_startup_receipt resource_sr = resource_startup(); - gp_startup(); struct sock_startup_receipt sock_sr = sock_startup(); struct host_startup_receipt host_sr = host_startup(&sock_sr); struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup(); struct ttf_startup_receipt ttf_sr = ttf_startup(); - struct font_startup_receipt font_sr = font_startup(&asset_cache_sr, &ttf_sr, &resource_sr); - struct sprite_startup_receipt sprite_sr = sprite_startup(&resource_sr); + struct font_startup_receipt font_sr = font_startup(&asset_cache_sr, &ttf_sr); + struct sprite_startup_receipt sprite_sr = sprite_startup(); struct mixer_startup_receipt mixer_sr = mixer_startup(); - struct sound_startup_receipt sound_sr = sound_startup(&asset_cache_sr, &resource_sr); + struct sound_startup_receipt sound_sr = sound_startup(&asset_cache_sr); struct draw_startup_receipt draw_sr = draw_startup(&font_sr); struct sim_startup_receipt sim_sr = sim_startup(); struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr); diff --git a/src/app.h b/src/app.h index cd95a058..1f553dd3 100644 --- a/src/app.h +++ b/src/app.h @@ -1,14 +1,6 @@ #ifndef APP_H #define APP_H -enum app_dedicated_worker_id { - APP_DEDICATED_WORKER_ID_USER = 0, - APP_DEDICATED_WORKER_ID_SIM = 1, - APP_DEDICATED_WORKER_ID_AUDIO = 2, - - NUM_APP_DEDICATED_WORKERS -}; - struct string app_write_path_cat(struct arena *arena, struct string filename); void app_exit(void); diff --git a/src/font.c b/src/font.c index 36a8463f..d2b6ddd7 100644 --- a/src/font.c +++ b/src/font.c @@ -40,12 +40,10 @@ GLOBAL struct { * ========================== */ struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr, - struct ttf_startup_receipt *ttf_sr, - struct resource_startup_receipt *resource_sr) + struct ttf_startup_receipt *ttf_sr) { (UNUSED)asset_cache_sr; (UNUSED)ttf_sr; - (UNUSED)resource_sr; G.params.arena = arena_alloc(GIBI(64)); diff --git a/src/font.h b/src/font.h index 45933ecf..73e3b96b 100644 --- a/src/font.h +++ b/src/font.h @@ -6,7 +6,6 @@ struct asset; struct asset_cache_startup_receipt; struct ttf_startup_receipt; -struct resource_startup_receipt; struct font_glyph { f32 off_x; @@ -29,8 +28,7 @@ struct font { struct font_startup_receipt { i32 _; }; struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr, - struct ttf_startup_receipt *ttf_sr, - struct resource_startup_receipt *resource_sr); + struct ttf_startup_receipt *ttf_sr); struct asset *font_load_asset(struct string path, f32 point_size, b32 wait); struct font *font_load_async(struct string path, f32 point_size); diff --git a/src/sound.c b/src/sound.c index 3a9c024b..07021d04 100644 --- a/src/sound.c +++ b/src/sound.c @@ -33,11 +33,9 @@ GLOBAL struct { * Startup * ========================== */ -struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr, - struct resource_startup_receipt *resource_sr) +struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr) { (UNUSED)asset_cache_sr; - (UNUSED)resource_sr; G.params.arena = arena_alloc(GIBI(64)); diff --git a/src/sound.h b/src/sound.h index 41872b9a..ad00b820 100644 --- a/src/sound.h +++ b/src/sound.h @@ -6,7 +6,6 @@ struct asset; struct asset_cache_startup_receipt; -struct resource_startup_receipt; struct sound { u32 flags; @@ -14,8 +13,7 @@ struct sound { }; struct sound_startup_receipt { i32 _; }; -struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr, - struct resource_startup_receipt *resource_sr); +struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr); struct asset *sound_load_asset(struct string path, u32 flags, b32 wait); struct sound *sound_load_async(struct string path, u32 flags); diff --git a/src/sprite.c b/src/sprite.c index 6c5de8e6..0e9e832e 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -208,10 +208,8 @@ INTERNAL SYS_JOB_DEF(sprite_evictor_job, _); INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, info); #endif -struct sprite_startup_receipt sprite_startup(struct resource_startup_receipt *resource_sr) +struct sprite_startup_receipt sprite_startup(void) { - (UNUSED)resource_sr; - G.perm_arena = arena_alloc(MEBI(1)); { /* Init loading texture */ diff --git a/src/sprite.h b/src/sprite.h index 3f2946e1..a3a71964 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -3,7 +3,6 @@ #include "util.h" -struct resource_startup_receipt; struct sprite_sheet_span; struct sprite_sheet_slice_group; @@ -12,7 +11,7 @@ struct sprite_sheet_slice_group; * ========================== */ struct sprite_startup_receipt { i32 _; }; -struct sprite_startup_receipt sprite_startup(struct resource_startup_receipt *resource_sr); +struct sprite_startup_receipt sprite_startup(void); /* ========================== * * Tag diff --git a/src/sys.h b/src/sys.h index a3e0eba0..43de5908 100644 --- a/src/sys.h +++ b/src/sys.h @@ -434,16 +434,12 @@ struct sys_window_settings { i32 floating_height; }; -struct sys_window_event_job_sig { - struct sys_window *window; - struct sys_event event; -}; - struct sys_window_present_job_sig { struct sys_window *window; + struct sys_event_array events; }; -struct sys_window *sys_window_alloc(sys_job_func *event_job, sys_job_func *present_job); +struct sys_window *sys_window_alloc(sys_job_func *present_job); void sys_window_release(struct sys_window *sys_window); void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings); diff --git a/src/sys_win32.c b/src/sys_win32.c index ee7799f9..e8940f7c 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -9,6 +9,7 @@ #include "util.h" #include "uni.h" #include "gp.h" +#include "resource.h" #pragma warning(push, 0) # define UNICODE @@ -48,7 +49,6 @@ #define MAX_EXIT_FUNCS 1024 - /* Arbitrary threshold for determining when to fall back from a looped WakeByAddressSingle to WakeByAddressAll */ #define WAKE_ALL_THRESHOLD 8 @@ -105,7 +105,10 @@ struct win32_window { struct gp_swapchain *swapchain; - sys_job_func *event_job; + struct snc_mutex event_arena_swp_mutex; + i32 current_event_arena_index; + struct arena *event_arenas[2]; + sys_job_func *present_job; struct sys_thread *event_thread; @@ -887,7 +890,7 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg) void *job_sig = 0; struct snc_counter *job_counter = 0; { - __profnc("Pull job", RGB32_F(0.75, 0.75, 0)); + //__profnc("Pull job", RGB32_F(0.75, 0.75, 0)); for (u32 queue_index = 0; queue_index < countof(queues) && !job_func; ++queue_index) { struct job_queue *queue = queues[queue_index]; if (queue) { @@ -1121,7 +1124,7 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg) { shutdown = atomic_i32_fetch(&G.workers_shutdown.v); while (atomic_i64_fetch(&G.num_jobs_in_queue.v) <= 0 && !shutdown) { - __profnc("Wait for job", RGB32_F(0.75, 0.75, 0)); + //__profnc("Wait for job", RGB32_F(0.75, 0.75, 0)); snc_cv_wait(&G.workers_wake_cv, &wake_lock); shutdown = atomic_i32_fetch(&G.workers_shutdown.v); } @@ -2203,14 +2206,13 @@ INTERNAL void win32_window_wake(struct win32_window *window); INTERNAL void win32_window_process_event(struct win32_window *window, struct sys_event event) { - if (window->event_job) { - __prof; - struct snc_counter counter = ZI; - struct sys_window_event_job_sig sig = ZI; - sig.window = (struct sys_window *)window; - sig.event = event; - sys_run(1, window->event_job, &sig, SYS_PRIORITY_NORMAL, &counter); - snc_counter_wait(&counter); + __prof; + if (window->present_job) { + struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex); + { + *arena_push(window->event_arenas[window->current_event_arena_index], struct sys_event) = event; + } + snc_unlock(&lock); } } @@ -2350,16 +2352,31 @@ INTERNAL SYS_THREAD_DEF(window_present_thread_entry_point, arg) gp_swapchain_wait(window->swapchain); } { - struct snc_counter counter = ZI; - struct sys_window_present_job_sig sig = ZI; - sig.window = (struct sys_window *)window; - sys_run(1, window->present_job, &sig, SYS_PRIORITY_HIGH, &counter); - snc_counter_wait(&counter); + i32 event_arena_index = 0; + { + struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex); + event_arena_index = window->current_event_arena_index; + window->current_event_arena_index = 1 - window->current_event_arena_index; + snc_unlock(&lock); + } + struct arena *events_arena = window->event_arenas[event_arena_index]; + struct sys_event_array events = ZI; + events.count = events_arena->pos / sizeof(struct sys_event); + events.events = (struct sys_event *)arena_base(events_arena); + { + struct snc_counter counter = ZI; + struct sys_window_present_job_sig sig = ZI; + sig.window = (struct sys_window *)window; + sig.events = events; + sys_run(1, window->present_job, &sig, SYS_PRIORITY_HIGH, &counter); + snc_counter_wait(&counter); + } + arena_reset(events_arena); } } } -INTERNAL struct win32_window *win32_window_alloc(sys_job_func *event_job, sys_job_func *present_job) +INTERNAL struct win32_window *win32_window_alloc(sys_job_func *present_job) { struct win32_window *window = 0; { @@ -2373,10 +2390,17 @@ INTERNAL struct win32_window *win32_window_alloc(sys_job_func *event_job, sys_jo snc_unlock(&lock); } MEMZERO_STRUCT(window); - window->event_job = event_job; window->present_job = present_job; + if (present_job) { + window->event_arenas[0] = arena_alloc(GIBI(64)); + window->event_arenas[1] = arena_alloc(GIBI(64)); + } + /* Start window event thread */ + /* NOTE: This thread must finish building for the window to actually be + * created and receive a HWND, because on Windows a the event proc must run on + * the same thread that created the window. */ snc_counter_add(&window->ready_fence, 1); window->event_thread = sys_thread_alloc(&window_event_thread_entry_point, window, LIT("Window event thread"), PROF_THREAD_GROUP_WINDOW); snc_counter_wait(&window->ready_fence); @@ -2387,25 +2411,25 @@ INTERNAL struct win32_window *win32_window_alloc(sys_job_func *event_job, sys_jo window->present_thread = sys_thread_alloc(&window_present_thread_entry_point, window, LIT("Window present thread"), PROF_THREAD_GROUP_WINDOW); } - /* Release swapchain */ - gp_swapchain_release(window->swapchain); - return window; } INTERNAL void win32_window_release(struct win32_window *window) { - struct snc_lock lock = snc_lock_e(&G.windows_mutex); - - window->next_free = G.first_free_window; - G.first_free_window = window; - /* Stop window threads */ atomic_i32_fetch_set(&window->shutdown, 1); win32_window_wake(window); sys_thread_wait_release(window->present_thread); sys_thread_wait_release(window->event_thread); + /* Release swapchain */ + gp_swapchain_release(window->swapchain); + + struct snc_lock lock = snc_lock_e(&G.windows_mutex); + { + window->next_free = G.first_free_window; + G.first_free_window = window; + } snc_unlock(&lock); } @@ -2769,10 +2793,10 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, return result; } -struct sys_window *sys_window_alloc(sys_job_func *event_job, sys_job_func *present_job) +struct sys_window *sys_window_alloc(sys_job_func *present_job) { __prof; - return (struct sys_window *)win32_window_alloc(event_job, present_job); + return (struct sys_window *)win32_window_alloc(present_job); } void sys_window_release(struct sys_window *sys_window) @@ -3364,6 +3388,10 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, /* Start test thread */ struct sys_thread *test_thread = sys_thread_alloc(test_entry, 0, LIT("Test thread"), PROF_THREAD_GROUP_APP); + /* Startup systems */ + resource_startup(); + gp_startup(); + /* ========================== * * App thread setup * ========================== */ diff --git a/src/user.c b/src/user.c index 1e39b0a2..d9d0aaea 100644 --- a/src/user.c +++ b/src/user.c @@ -192,6 +192,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = { INTERNAL SYS_EXIT_FUNC(user_shutdown); INTERNAL LOG_EVENT_CALLBACK_FUNC_DEF(debug_console_log_callback, log); +INTERNAL SYS_JOB_DEF(user_update_job, _); INTERNAL SYS_JOB_DEF(local_sim_job , _); struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr, @@ -222,9 +223,6 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr, /* Initialize average dt to a reasonable value */ G.average_local_to_user_snapshot_publish_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND; - /* Sys events */ - G.sys_events_arena = arena_alloc(GIBI(64)); - /* User blend clients */ G.user_client_store = sim_client_store_alloc(); G.user_unblended_client = sim_client_alloc(G.user_client_store); @@ -248,7 +246,7 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr, sys_run(1, local_sim_job, 0, SYS_PRIORITY_HIGH, &G.shutdown_job_counters); sys_on_exit(&user_shutdown); - G.window = sys_window_alloc(user_event_job, user_present_job); + G.window = sys_window_alloc(user_update_job); return (struct user_startup_receipt) { 0 }; } @@ -263,36 +261,6 @@ INTERNAL SYS_EXIT_FUNC(user_shutdown) snc_counter_wait(&G.shutdown_job_counters); } -/* ========================== * - * Window -> user communication - * ========================== */ - -INTERNAL struct sys_event_array pop_sys_events(struct arena *arena) -{ - struct sys_event_array array = ZI; - struct snc_lock lock = snc_lock_e(&G.sys_events_mutex); - { - struct sys_event *src_events = (struct sys_event *)arena_base(G.sys_events_arena); - array.count = G.sys_events_arena->pos / sizeof(*src_events); - array.events = arena_push_array_no_zero(arena, struct sys_event, array.count); - MEMCPY(array.events, src_events, array.count * sizeof(*src_events)); - arena_reset(G.sys_events_arena); - } - snc_unlock(&lock); - return array; -} - -SYS_JOB_DEF(user_event_job, job) -{ - __prof; - struct sys_window_event_job_sig *sig = job.sig; - struct snc_lock lock = snc_lock_e(&G.sys_events_mutex); - { - *arena_push_no_zero(G.sys_events_arena, struct sys_event) = sig->event; - } - snc_unlock(&lock); -} - /* ========================== * * Debug draw * ========================== */ @@ -593,11 +561,12 @@ INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata) * Update * ========================== */ -SYS_JOB_DEF(user_present_job, job) +SYS_JOB_DEF(user_update_job, job) { __prof; struct sys_window_present_job_sig *sig = job.sig; struct sys_window *window = sig->window; + struct sys_event_array events = sig->events; struct arena_temp scratch = scratch_begin_no_conflict(); @@ -731,7 +700,6 @@ SYS_JOB_DEF(user_present_job, job) { __profn("Process sys events"); - struct sys_event_array events = pop_sys_events(scratch.arena); /* Reset bind pressed / released states */ for (u32 i = 0; i < countof(G.bind_states); ++i) { diff --git a/src/user.h b/src/user.h index 5819f730..c7e69432 100644 --- a/src/user.h +++ b/src/user.h @@ -70,7 +70,4 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr, struct sim_startup_receipt *sim_sr, struct string connect_address_str); -SYS_JOB_DEF(user_event_job, job); -SYS_JOB_DEF(user_present_job, job); - #endif