Skip to content

Commit 1589433

Browse files
committed
Apply additional fixes to servers' threading
1 parent 6f0760b commit 1589433

10 files changed

+142
-141
lines changed

core/templates/command_queue_mt.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ class CommandQueueMT {
388388
} while (sync_head != sync_head_goal); // Can't use lower-than because of wraparound.
389389
}
390390

391+
void _no_op() {}
392+
391393
public:
392394
void lock();
393395
void unlock();
@@ -409,18 +411,25 @@ class CommandQueueMT {
409411
_flush();
410412
}
411413
}
414+
412415
void flush_all() {
413416
_flush();
414417
}
415418

419+
void sync() {
420+
push_and_sync(this, &CommandQueueMT::_no_op);
421+
}
422+
416423
void wait_and_flush() {
417424
ERR_FAIL_COND(pump_task_id == WorkerThreadPool::INVALID_TASK_ID);
418425
WorkerThreadPool::get_singleton()->wait_for_task_completion(pump_task_id);
419426
_flush();
420427
}
421428

422429
void set_pump_task_id(WorkerThreadPool::TaskID p_task_id) {
430+
lock();
423431
pump_task_id = p_task_id;
432+
unlock();
424433
}
425434

426435
CommandQueueMT();

drivers/gles3/rasterizer_gles3.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,13 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
395395
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
396396

397397
if (p_first) {
398-
Size2i win_size = DisplayServer::get_singleton()->window_get_size();
399398
if (p_screen_rect.position != Vector2() || p_screen_rect.size != rt->size) {
400399
// Viewport doesn't cover entire window so clear window to black before blitting.
401-
glViewport(0, 0, win_size.width, win_size.height);
400+
// Querying the actual window size from the DisplayServer would deadlock in separate render thread mode,
401+
// so let's set the biggest viewport the implementation supports, to be sure the window is fully covered.
402+
GLsizei max_vp[2] = {};
403+
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_vp);
404+
glViewport(0, 0, max_vp[0], max_vp[1]);
402405
glClearColor(0.0, 0.0, 0.0, 1.0);
403406
glClear(GL_COLOR_BUFFER_BIT);
404407
}

servers/physics_server_2d_wrap_mt.cpp

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,45 +32,37 @@
3232

3333
#include "core/os/os.h"
3434

35-
void PhysicsServer2DWrapMT::thread_exit() {
36-
exit = true;
35+
void PhysicsServer2DWrapMT::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
36+
server_thread = Thread::get_caller_id();
37+
server_task_id = p_pump_task_id;
3738
}
3839

39-
void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
40-
physics_server_2d->step(p_delta);
41-
step_sem.post();
40+
void PhysicsServer2DWrapMT::_thread_exit() {
41+
exit = true;
4242
}
4343

44-
void PhysicsServer2DWrapMT::thread_loop() {
45-
server_thread = Thread::get_caller_id();
46-
47-
physics_server_2d->init();
48-
49-
command_queue.set_pump_task_id(server_task_id);
44+
void PhysicsServer2DWrapMT::_thread_loop() {
5045
while (!exit) {
5146
WorkerThreadPool::get_singleton()->yield();
5247
command_queue.flush_all();
5348
}
54-
55-
command_queue.flush_all();
56-
57-
physics_server_2d->finish();
5849
}
5950

6051
/* EVENT QUEUING */
6152

6253
void PhysicsServer2DWrapMT::step(real_t p_step) {
6354
if (create_thread) {
64-
command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step);
55+
command_queue.push(physics_server_2d, &PhysicsServer2D::step, p_step);
6556
} else {
66-
command_queue.flush_all(); // Flush all pending from other threads.
6757
physics_server_2d->step(p_step);
6858
}
6959
}
7060

7161
void PhysicsServer2DWrapMT::sync() {
7262
if (create_thread) {
73-
step_sem.wait();
63+
command_queue.sync();
64+
} else {
65+
command_queue.flush_all(); // Flush all pending from other threads.
7466
}
7567
physics_server_2d->sync();
7668
}
@@ -85,21 +77,26 @@ void PhysicsServer2DWrapMT::end_sync() {
8577

8678
void PhysicsServer2DWrapMT::init() {
8779
if (create_thread) {
88-
exit = false;
89-
server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::thread_loop), true);
90-
step_sem.post();
80+
WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::_thread_loop), true);
81+
command_queue.set_pump_task_id(tid);
82+
command_queue.push(this, &PhysicsServer2DWrapMT::_assign_mt_ids, tid);
83+
command_queue.push_and_sync(physics_server_2d, &PhysicsServer2D::init);
84+
DEV_ASSERT(server_task_id == tid);
9185
} else {
86+
server_thread = Thread::MAIN_ID;
9287
physics_server_2d->init();
9388
}
9489
}
9590

9691
void PhysicsServer2DWrapMT::finish() {
9792
if (create_thread) {
98-
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
93+
command_queue.push(physics_server_2d, &PhysicsServer2D::finish);
94+
command_queue.push(this, &PhysicsServer2DWrapMT::_thread_exit);
9995
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
10096
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
10197
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
10298
}
99+
server_thread = Thread::MAIN_ID;
103100
} else {
104101
physics_server_2d->finish();
105102
}
@@ -108,9 +105,6 @@ void PhysicsServer2DWrapMT::finish() {
108105
PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) {
109106
physics_server_2d = p_contained;
110107
create_thread = p_create_thread;
111-
if (!create_thread) {
112-
server_thread = Thread::MAIN_ID;
113-
}
114108
}
115109

116110
PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {

servers/physics_server_2d_wrap_mt.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,14 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D {
5353

5454
mutable CommandQueueMT command_queue;
5555

56-
void thread_loop();
57-
5856
Thread::ID server_thread = Thread::UNASSIGNED_ID;
5957
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
6058
bool exit = false;
61-
Semaphore step_sem;
6259
bool create_thread = false;
6360

64-
void thread_step(real_t p_delta);
65-
66-
void thread_exit();
61+
void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id);
62+
void _thread_exit();
63+
void _thread_loop();
6764

6865
public:
6966
#define ServerName PhysicsServer2D

servers/physics_server_3d_wrap_mt.cpp

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,45 +32,37 @@
3232

3333
#include "core/os/os.h"
3434

35-
void PhysicsServer3DWrapMT::thread_exit() {
36-
exit = true;
35+
void PhysicsServer3DWrapMT::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
36+
server_thread = Thread::get_caller_id();
37+
server_task_id = p_pump_task_id;
3738
}
3839

39-
void PhysicsServer3DWrapMT::thread_step(real_t p_delta) {
40-
physics_server_3d->step(p_delta);
41-
step_sem.post();
40+
void PhysicsServer3DWrapMT::_thread_exit() {
41+
exit = true;
4242
}
4343

44-
void PhysicsServer3DWrapMT::thread_loop() {
45-
server_thread = Thread::get_caller_id();
46-
47-
physics_server_3d->init();
48-
49-
command_queue.set_pump_task_id(server_task_id);
44+
void PhysicsServer3DWrapMT::_thread_loop() {
5045
while (!exit) {
5146
WorkerThreadPool::get_singleton()->yield();
5247
command_queue.flush_all();
5348
}
54-
55-
command_queue.flush_all(); // flush all
56-
57-
physics_server_3d->finish();
5849
}
5950

6051
/* EVENT QUEUING */
6152

6253
void PhysicsServer3DWrapMT::step(real_t p_step) {
6354
if (create_thread) {
64-
command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step);
55+
command_queue.push(physics_server_3d, &PhysicsServer3D::step, p_step);
6556
} else {
66-
command_queue.flush_all(); // Flush all pending from other threads.
6757
physics_server_3d->step(p_step);
6858
}
6959
}
7060

7161
void PhysicsServer3DWrapMT::sync() {
7262
if (create_thread) {
73-
step_sem.wait();
63+
command_queue.sync();
64+
} else {
65+
command_queue.flush_all(); // Flush all pending from other threads.
7466
}
7567
physics_server_3d->sync();
7668
}
@@ -85,21 +77,26 @@ void PhysicsServer3DWrapMT::end_sync() {
8577

8678
void PhysicsServer3DWrapMT::init() {
8779
if (create_thread) {
88-
exit = false;
89-
server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::thread_loop), true);
90-
step_sem.post();
80+
WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::_thread_loop), true);
81+
command_queue.set_pump_task_id(tid);
82+
command_queue.push(this, &PhysicsServer3DWrapMT::_assign_mt_ids, tid);
83+
command_queue.push_and_sync(physics_server_3d, &PhysicsServer3D::init);
84+
DEV_ASSERT(server_task_id == tid);
9185
} else {
86+
server_thread = Thread::MAIN_ID;
9287
physics_server_3d->init();
9388
}
9489
}
9590

9691
void PhysicsServer3DWrapMT::finish() {
9792
if (create_thread) {
98-
command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit);
93+
command_queue.push(physics_server_3d, &PhysicsServer3D::finish);
94+
command_queue.push(this, &PhysicsServer3DWrapMT::_thread_exit);
9995
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
10096
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
10197
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
10298
}
99+
server_thread = Thread::MAIN_ID;
103100
} else {
104101
physics_server_3d->finish();
105102
}
@@ -108,9 +105,6 @@ void PhysicsServer3DWrapMT::finish() {
108105
PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) {
109106
physics_server_3d = p_contained;
110107
create_thread = p_create_thread;
111-
if (!create_thread) {
112-
server_thread = Thread::MAIN_ID;
113-
}
114108
}
115109

116110
PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {

servers/physics_server_3d_wrap_mt.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,15 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D {
5252

5353
mutable CommandQueueMT command_queue;
5454

55-
void thread_loop();
56-
5755
Thread::ID server_thread = Thread::UNASSIGNED_ID;
5856
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
5957
bool exit = false;
60-
Semaphore step_sem;
6158
bool create_thread = false;
6259

63-
void thread_step(real_t p_delta);
64-
65-
void thread_exit();
60+
void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id);
61+
void _thread_exit();
62+
void _thread_step(real_t p_delta);
63+
void _thread_loop();
6664

6765
public:
6866
#define ServerName PhysicsServer3D

servers/rendering/renderer_viewport.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
678678
#endif // _3D_DISABLED
679679

680680
if (Engine::get_singleton()->is_editor_hint()) {
681-
set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
681+
RSG::texture_storage->set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
682682
}
683683

684684
if (sorted_active_viewports_dirty) {
@@ -1521,10 +1521,6 @@ void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time,
15211521
}
15221522
}
15231523

1524-
void RendererViewport::set_default_clear_color(const Color &p_color) {
1525-
RSG::texture_storage->set_default_clear_color(p_color);
1526-
}
1527-
15281524
void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) {
15291525
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
15301526
ERR_FAIL_NULL(viewport);

servers/rendering/renderer_viewport.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ class RendererViewport {
303303

304304
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
305305

306-
void set_default_clear_color(const Color &p_color);
307306
void draw_viewports(bool p_swap_buffers);
308307

309308
bool free(RID p_rid);

0 commit comments

Comments
 (0)