Skip to content

Commit 2cd0c6b

Browse files
improved render thread communication
1 parent 824e006 commit 2cd0c6b

File tree

1 file changed

+55
-35
lines changed

1 file changed

+55
-35
lines changed

ZEngine/ZEngine/Engine.cpp

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,29 @@
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+
1317
namespace 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

Comments
 (0)