55#include < Logging/LoggerDefinition.h>
66#include < Managers/AssetManager.h>
77#include < Windows/GameWindow.h>
8+ #include < chrono>
89
910#ifdef __APPLE__
11+ #include < mach/mach.h>
1012#include < pthread/pthread.h>
1113#endif
1214
15+ using namespace std ::chrono_literals;
16+
1317namespace ZEngine
1418{
15- static const uint8_t k_mailbox_buffer_size = 4 ;
1619 static std::atomic_bool s_request_terminate = false ;
20+ static EngineContextPtr g_engine_ctx = nullptr ;
21+ static Applications::GameApplicationPtr g_app = nullptr ;
22+ static Applications::AppRenderPipelinePtr g_appRenderPipeline = nullptr ;
23+ static std::thread g_render_thread = {};
24+
25+ static const uint8_t k_mailbox_buffer_size = 3 ;
26+ static std::atomic_int g_write_idx = 0 ;
27+ static std::atomic_int g_pending_idx = -1 ;
1728 static std::mutex g_mailbox_mut;
18- static std::shared_mutex g_mutex = {};
19- static EngineContextPtr g_engine_ctx = nullptr ;
20- static Applications::GameApplicationPtr g_app = nullptr ;
21- static Applications::AppRenderPipelinePtr g_appRenderPipeline = nullptr ;
22- static std::thread g_render_thread = {};
23- static Applications::RenderPayload g_mailbox_payloads[k_mailbox_buffer_size] = {};
24- static std::atomic_int g_mailbox_ready_idx = -1 ;
2529 static std::condition_variable g_mailbox_ready_cv = {};
26-
27- static int g_write_idx = 0 ;
28- static int g_pending_idx = -1 ;
30+ static Applications::RenderPayload g_mailbox_payloads[k_mailbox_buffer_size] = {};
2931
3032 void Engine::Initialize (ZEngine::Core::Memory::ArenaAllocator* arena, Windows::WindowConfigurationPtr window_cfg_ptr, Applications::GameApplicationPtr app)
3133 {
@@ -50,17 +52,15 @@ namespace ZEngine
5052
5153 for (size_t i = 0 ; i < k_mailbox_buffer_size; ++i)
5254 {
53- g_mailbox_payloads[i].UIOverlay .IndexedCmds .resize (20 );
54- g_mailbox_payloads[i].UIOverlay .ScissorCmds .resize (20 );
55- g_mailbox_payloads[i].UIOverlay .TextureIds .resize (20 );
55+ g_mailbox_payloads[i].UIOverlay .IndexedCmds .resize (100 );
56+ g_mailbox_payloads[i].UIOverlay .ScissorCmds .resize (100 );
57+ g_mailbox_payloads[i].UIOverlay .TextureIds .resize (100 );
5658 }
5759 ZENGINE_CORE_INFO (" Engine initialized" )
5860 }
5961
6062 void Engine::Deinitialize ()
6163 {
62- std::unique_lock l (g_mutex);
63-
6464 if (g_engine_ctx->Window )
6565 {
6666 g_engine_ctx->Window ->Deinitialize ();
@@ -82,33 +82,39 @@ namespace ZEngine
8282
8383 bool Engine::OnEngineClosed (Event::EngineClosedEvent& event)
8484 {
85- s_request_terminate.store (true , std::memory_order_release);
85+ {
86+ std::lock_guard l (g_mailbox_mut);
87+ s_request_terminate.store (true , std::memory_order_release);
88+ g_mailbox_ready_cv.notify_all ();
89+ }
8690 return true ;
8791 }
8892
8993 void Engine::MainThreadRun ()
9094 {
91- static int writable_payload_idx = 0 ;
92-
93- while (auto window = g_engine_ctx->Window )
95+ while (!s_request_terminate.load (std::memory_order_acquire))
9496 {
95- if (s_request_terminate. load (std::memory_order_acquire) )
97+ if (!g_engine_ctx || !g_engine_ctx-> Window || !g_engine_ctx-> Device )
9698 {
9799 break ;
98100 }
99101
100- if (g_engine_ctx->Device ->SwapchainResizeRequested )
102+ auto device = g_engine_ctx->Device ;
103+
104+ if (device->SwapchainResizeRequested )
101105 {
102106 {
103107 std::unique_lock l (g_engine_ctx->Device ->SwapchainMutex );
104- g_engine_ctx-> Device ->ResizeSwapchain ();
105- g_engine_ctx-> Device ->SwapchainResizeHandled = true ;
106- g_engine_ctx-> Device ->SwapchainResizeRequested = false ;
108+ device ->ResizeSwapchain ();
109+ device ->SwapchainResizeHandled = true ;
110+ device ->SwapchainResizeRequested = false ;
107111 }
108- g_engine_ctx-> Device ->SwapchainCond .notify_all ();
112+ device ->SwapchainCond .notify_all ();
109113 }
110114
111- float dt = window->GetDeltaTime ();
115+ auto window = g_engine_ctx->Window ;
116+
117+ float dt = window->GetDeltaTime ();
112118
113119 window->PollEvent ();
114120
@@ -121,12 +127,18 @@ namespace ZEngine
121127
122128 {
123129 std::unique_lock l (g_mailbox_mut);
124- g_mailbox_ready_cv.wait (l, [&] { return g_pending_idx == -1 ; });
130+ g_mailbox_ready_cv.wait (l, [&] { return s_request_terminate.load (std::memory_order_acquire) || g_pending_idx.load (std::memory_order_acquire) == -1 ; });
131+
132+ if (s_request_terminate.load (std::memory_order_acquire))
133+ {
134+ break ;
135+ }
125136
126- int next_payload_idx = g_write_idx;
137+ int next_payload_idx = g_write_idx. load (std::memory_order_relaxed) ;
127138
128139 auto & r_payload = g_mailbox_payloads[next_payload_idx];
129140 r_payload.UIOverlay .DrawDataIndex = 0 ;
141+ r_payload.RenderUIOverlay = false ;
130142
131143 if (g_app->EnableRenderOverlay )
132144 {
@@ -140,8 +152,8 @@ namespace ZEngine
140152
141153 g_app->PrepareScene (r_payload);
142154
143- g_pending_idx = next_payload_idx;
144- g_write_idx = ( g_write_idx + 1 ) % k_mailbox_buffer_size;
155+ g_pending_idx. store ( next_payload_idx, std::memory_order_release) ;
156+ g_write_idx. store (( g_write_idx + 1 ) % k_mailbox_buffer_size, std::memory_order_relaxed) ;
145157 }
146158 g_mailbox_ready_cv.notify_one ();
147159 }
@@ -151,21 +163,29 @@ namespace ZEngine
151163 {
152164#ifdef __APPLE__
153165 pthread_setname_np (" RenderThread" );
166+ thread_port_t thread_port = pthread_mach_thread_np (pthread_self ());
167+ thread_time_constraint_policy_data_t policy;
168+ policy.period = 50000 ;
169+ policy.computation = 20000 ;
170+ policy.constraint = 40000 ;
171+ policy.preemptible = 1 ;
172+
173+ kern_return_t kr = thread_policy_set (thread_port, THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t ) &policy, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
154174#endif
155175 while (true )
156176 {
157177 int idx = -1 ;
158178 {
159179 std::unique_lock l (g_mailbox_mut);
160- g_mailbox_ready_cv.wait (l, [&] { return g_pending_idx != -1 ; });
180+ g_mailbox_ready_cv.wait (l, [&] { return s_request_terminate. load (std::memory_order_acquire) || g_pending_idx. load (std::memory_order_acquire) != -1 ; });
161181
162182 if (s_request_terminate.load (std::memory_order_acquire))
163183 {
164184 break ;
165185 }
166186
167- idx = g_pending_idx;
168- g_pending_idx = - 1 ;
187+ idx = g_pending_idx. load (std::memory_order_acquire) ;
188+ g_pending_idx. store (- 1 , std::memory_order_release) ;
169189 }
170190
171191 ZENGINE_VALIDATE_ASSERT (idx > -1 , " Invalid payload index" )
@@ -177,6 +197,7 @@ namespace ZEngine
177197 if (r_payload.ResizeRenderTarget )
178198 {
179199 pipeline->ResizeRenderTarget (r_payload.RenderTargetW , r_payload.RenderTargetH );
200+ r_payload.ResizeRenderTarget = false ;
180201 }
181202
182203 pipeline->BeginFrame ();
@@ -199,7 +220,6 @@ namespace ZEngine
199220
200221 if (s_request_terminate.load (std::memory_order_acquire))
201222 {
202- g_mailbox_ready_cv.notify_all ();
203223 Deinitialize ();
204224 }
205225 }
0 commit comments