summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorRémi Verschelde <remi@verschelde.fr>2024-04-15 10:12:00 +0200
committerGitHub <noreply@github.com>2024-04-15 10:12:00 +0200
commitc951421c996467dcb7106a33774410a7b5258690 (patch)
tree10bf3ef87a62987b6303d7dca63adc809ebbb05b /servers
parenta44b0b6dc1ccd6dc364bb72c426e844d6c85744e (diff)
parent65686dedf9778e829287f63c7179a523d44fa085 (diff)
downloadredot-engine-c951421c996467dcb7106a33774410a7b5258690.tar.gz
Merge pull request #90268 from RandomShaper/wtp_servers
Use WorkerThreadPool for Server threads (enhanced)
Diffstat (limited to 'servers')
-rw-r--r--servers/display_server.cpp4
-rw-r--r--servers/display_server.h1
-rw-r--r--servers/physics_server_2d_wrap_mt.cpp55
-rw-r--r--servers/physics_server_2d_wrap_mt.h38
-rw-r--r--servers/physics_server_3d_wrap_mt.cpp49
-rw-r--r--servers/physics_server_3d_wrap_mt.h38
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp6
-rw-r--r--servers/rendering/rendering_server_default.cpp65
-rw-r--r--servers/rendering/rendering_server_default.h21
-rw-r--r--servers/rendering_server.cpp9
-rw-r--r--servers/server_wrap_mt_common.h45
11 files changed, 152 insertions, 179 deletions
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 9ceb6909fe..351c03c158 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -697,10 +697,6 @@ void DisplayServer::release_rendering_thread() {
WARN_PRINT("Rendering thread not supported by this display server.");
}
-void DisplayServer::make_rendering_thread() {
- WARN_PRINT("Rendering thread not supported by this display server.");
-}
-
void DisplayServer::swap_buffers() {
WARN_PRINT("Swap buffers not supported by this display server.");
}
diff --git a/servers/display_server.h b/servers/display_server.h
index f1a98c2c17..aab51644c0 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -559,7 +559,6 @@ public:
virtual void force_process_and_drop_events();
virtual void release_rendering_thread();
- virtual void make_rendering_thread();
virtual void swap_buffers();
virtual void set_native_icon(const String &p_filename);
diff --git a/servers/physics_server_2d_wrap_mt.cpp b/servers/physics_server_2d_wrap_mt.cpp
index a23bb5e701..4548bb91cb 100644
--- a/servers/physics_server_2d_wrap_mt.cpp
+++ b/servers/physics_server_2d_wrap_mt.cpp
@@ -33,7 +33,7 @@
#include "core/os/os.h"
void PhysicsServer2DWrapMT::thread_exit() {
- exit.set();
+ exit = true;
}
void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
@@ -41,25 +41,18 @@ void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
step_sem.post();
}
-void PhysicsServer2DWrapMT::_thread_callback(void *_instance) {
- PhysicsServer2DWrapMT *vsmt = reinterpret_cast<PhysicsServer2DWrapMT *>(_instance);
-
- vsmt->thread_loop();
-}
-
void PhysicsServer2DWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();
physics_server_2d->init();
- exit.clear();
- step_thread_up.set();
- while (!exit.is_set()) {
- // flush commands one by one, until exit is requested
- command_queue.wait_and_flush();
+ command_queue.set_pump_task_id(server_task_id);
+ while (!exit) {
+ WorkerThreadPool::get_singleton()->yield();
+ command_queue.flush_all();
}
- command_queue.flush_all(); // flush all
+ command_queue.flush_all();
physics_server_2d->finish();
}
@@ -70,18 +63,14 @@ void PhysicsServer2DWrapMT::step(real_t p_step) {
if (create_thread) {
command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step);
} else {
- command_queue.flush_all(); //flush all pending from other threads
+ command_queue.flush_all(); // Flush all pending from other threads.
physics_server_2d->step(p_step);
}
}
void PhysicsServer2DWrapMT::sync() {
if (create_thread) {
- if (first_frame) {
- first_frame = false;
- } else {
- step_sem.wait(); //must not wait if a step was not issued
- }
+ step_sem.wait();
}
physics_server_2d->sync();
}
@@ -96,40 +85,34 @@ void PhysicsServer2DWrapMT::end_sync() {
void PhysicsServer2DWrapMT::init() {
if (create_thread) {
- //OS::get_singleton()->release_rendering_thread();
- thread.start(_thread_callback, this);
- while (!step_thread_up.is_set()) {
- OS::get_singleton()->delay_usec(1000);
- }
+ exit = false;
+ server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::thread_loop), true);
+ step_sem.post();
} else {
physics_server_2d->init();
}
}
void PhysicsServer2DWrapMT::finish() {
- if (thread.is_started()) {
+ if (create_thread) {
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
- thread.wait_to_finish();
+ if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
+ server_task_id = WorkerThreadPool::INVALID_TASK_ID;
+ }
} else {
physics_server_2d->finish();
}
}
-PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) :
- command_queue(p_create_thread) {
+PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) {
physics_server_2d = p_contained;
create_thread = p_create_thread;
-
- if (!p_create_thread) {
- server_thread = Thread::get_caller_id();
- } else {
- server_thread = 0;
+ if (!create_thread) {
+ server_thread = Thread::MAIN_ID;
}
-
- main_thread = Thread::get_caller_id();
}
PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {
memdelete(physics_server_2d);
- //finish();
}
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index 3bebe5df85..5e2b3b4086 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -32,6 +32,7 @@
#define PHYSICS_SERVER_2D_WRAP_MT_H
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/safe_refcount.h"
@@ -43,30 +44,27 @@
#define SYNC_DEBUG
#endif
+#ifdef DEBUG_ENABLED
+#define MAIN_THREAD_SYNC_WARN WARN_PRINT("Call to " + String(__FUNCTION__) + " causing PhysicsServer2D synchronizations on every frame. This significantly affects performance.");
+#endif
+
class PhysicsServer2DWrapMT : public PhysicsServer2D {
- mutable PhysicsServer2D *physics_server_2d;
+ mutable PhysicsServer2D *physics_server_2d = nullptr;
mutable CommandQueueMT command_queue;
- static void _thread_callback(void *_instance);
void thread_loop();
- Thread::ID server_thread;
- Thread::ID main_thread;
- SafeFlag exit;
- Thread thread;
- SafeFlag step_thread_up;
+ Thread::ID server_thread = Thread::UNASSIGNED_ID;
+ WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
+ bool exit = false;
+ Semaphore step_sem;
bool create_thread = false;
- Semaphore step_sem;
void thread_step(real_t p_delta);
void thread_exit();
- bool first_frame = true;
-
- Mutex alloc_mutex;
-
public:
#define ServerName PhysicsServer2D
#define ServerNameWrapMT PhysicsServer2DWrapMT
@@ -94,7 +92,7 @@ public:
//these work well, but should be used from the main thread only
bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), false);
return physics_server_2d->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
}
@@ -109,18 +107,18 @@ public:
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), nullptr);
return physics_server_2d->space_get_direct_state(p_space);
}
FUNC2(space_set_debug_contacts, RID, int);
virtual Vector<Vector2> space_get_contacts(RID p_space) const override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>());
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), Vector<Vector2>());
return physics_server_2d->space_get_contacts(p_space);
}
virtual int space_get_contact_count(RID p_space) const override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), 0);
return physics_server_2d->space_get_contact_count(p_space);
}
@@ -261,13 +259,13 @@ public:
FUNC2(body_set_pickable, RID, bool);
bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), false);
return physics_server_2d->body_test_motion(p_body, p_parameters, r_result);
}
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), nullptr);
return physics_server_2d->body_get_direct_state(p_body);
}
@@ -338,4 +336,8 @@ public:
#endif
#undef SYNC_DEBUG
+#ifdef DEBUG_ENABLED
+#undef MAIN_THREAD_SYNC_WARN
+#endif
+
#endif // PHYSICS_SERVER_2D_WRAP_MT_H
diff --git a/servers/physics_server_3d_wrap_mt.cpp b/servers/physics_server_3d_wrap_mt.cpp
index feb17cad84..f8f60281a7 100644
--- a/servers/physics_server_3d_wrap_mt.cpp
+++ b/servers/physics_server_3d_wrap_mt.cpp
@@ -41,22 +41,15 @@ void PhysicsServer3DWrapMT::thread_step(real_t p_delta) {
step_sem.post();
}
-void PhysicsServer3DWrapMT::_thread_callback(void *_instance) {
- PhysicsServer3DWrapMT *vsmt = reinterpret_cast<PhysicsServer3DWrapMT *>(_instance);
-
- vsmt->thread_loop();
-}
-
void PhysicsServer3DWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();
physics_server_3d->init();
- exit = false;
- step_thread_up = true;
+ command_queue.set_pump_task_id(server_task_id);
while (!exit) {
- // flush commands one by one, until exit is requested
- command_queue.wait_and_flush();
+ WorkerThreadPool::get_singleton()->yield();
+ command_queue.flush_all();
}
command_queue.flush_all(); // flush all
@@ -70,18 +63,14 @@ void PhysicsServer3DWrapMT::step(real_t p_step) {
if (create_thread) {
command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step);
} else {
- command_queue.flush_all(); //flush all pending from other threads
+ command_queue.flush_all(); // Flush all pending from other threads.
physics_server_3d->step(p_step);
}
}
void PhysicsServer3DWrapMT::sync() {
if (create_thread) {
- if (first_frame) {
- first_frame = false;
- } else {
- step_sem.wait(); //must not wait if a step was not issued
- }
+ step_sem.wait();
}
physics_server_3d->sync();
}
@@ -96,40 +85,34 @@ void PhysicsServer3DWrapMT::end_sync() {
void PhysicsServer3DWrapMT::init() {
if (create_thread) {
- //OS::get_singleton()->release_rendering_thread();
- thread.start(_thread_callback, this);
- while (!step_thread_up) {
- OS::get_singleton()->delay_usec(1000);
- }
+ exit = false;
+ server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::thread_loop), true);
+ step_sem.post();
} else {
physics_server_3d->init();
}
}
void PhysicsServer3DWrapMT::finish() {
- if (thread.is_started()) {
+ if (create_thread) {
command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit);
- thread.wait_to_finish();
+ if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
+ server_task_id = WorkerThreadPool::INVALID_TASK_ID;
+ }
} else {
physics_server_3d->finish();
}
}
-PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) :
- command_queue(p_create_thread) {
+PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) {
physics_server_3d = p_contained;
create_thread = p_create_thread;
-
- if (!p_create_thread) {
- server_thread = Thread::get_caller_id();
- } else {
- server_thread = 0;
+ if (!create_thread) {
+ server_thread = Thread::MAIN_ID;
}
-
- main_thread = Thread::get_caller_id();
}
PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {
memdelete(physics_server_3d);
- //finish();
}
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index fc8930977d..22f3ee0e45 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -32,6 +32,7 @@
#define PHYSICS_SERVER_3D_WRAP_MT_H
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "servers/physics_server_3d.h"
@@ -42,30 +43,27 @@
#define SYNC_DEBUG
#endif
+#ifdef DEBUG_ENABLED
+#define MAIN_THREAD_SYNC_WARN WARN_PRINT("Call to " + String(__FUNCTION__) + " causing PhysicsServer3D synchronizations on every frame. This significantly affects performance.");
+#endif
+
class PhysicsServer3DWrapMT : public PhysicsServer3D {
- mutable PhysicsServer3D *physics_server_3d;
+ mutable PhysicsServer3D *physics_server_3d = nullptr;
mutable CommandQueueMT command_queue;
- static void _thread_callback(void *_instance);
void thread_loop();
- Thread::ID server_thread;
- Thread::ID main_thread;
- volatile bool exit = false;
- Thread thread;
- volatile bool step_thread_up = false;
+ Thread::ID server_thread = Thread::UNASSIGNED_ID;
+ WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
+ bool exit = false;
+ Semaphore step_sem;
bool create_thread = false;
- Semaphore step_sem;
void thread_step(real_t p_delta);
void thread_exit();
- bool first_frame = true;
-
- Mutex alloc_mutex;
-
public:
#define ServerName PhysicsServer3D
#define ServerNameWrapMT PhysicsServer3DWrapMT
@@ -98,7 +96,7 @@ public:
#if 0
//these work well, but should be used from the main thread only
bool shape_collide(RID p_shape_A, const Transform &p_xform_A, const Vector3 &p_motion_A, RID p_shape_B, const Transform &p_xform_B, const Vector3 &p_motion_B, Vector3 *r_results, int p_result_max, int &r_result_count) {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), false);
return physics_server_3d->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
}
#endif
@@ -113,18 +111,18 @@ public:
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), nullptr);
return physics_server_3d->space_get_direct_state(p_space);
}
FUNC2(space_set_debug_contacts, RID, int);
virtual Vector<Vector3> space_get_contacts(RID p_space) const override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector3>());
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), Vector<Vector3>());
return physics_server_3d->space_get_contacts(p_space);
}
virtual int space_get_contact_count(RID p_space) const override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), 0);
return physics_server_3d->space_get_contact_count(p_space);
}
@@ -260,13 +258,13 @@ public:
FUNC2(body_set_ray_pickable, RID, bool);
bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), false);
return physics_server_3d->body_test_motion(p_body, p_parameters, r_result);
}
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ ERR_FAIL_COND_V(!Thread::is_main_thread(), nullptr);
return physics_server_3d->body_get_direct_state(p_body);
}
@@ -411,4 +409,8 @@ public:
#endif
#undef SYNC_DEBUG
+#ifdef DEBUG_ENABLED
+#undef MAIN_THREAD_SYNC_WARN
+#endif
+
#endif // PHYSICS_SERVER_3D_WRAP_MT_H
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index c9c7c53d04..f7b28e7a1e 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -257,7 +257,6 @@ void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting)
}
bool ParticlesStorage::particles_get_emitting(RID p_particles) {
- ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer.");
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_NULL_V(particles, false);
@@ -608,10 +607,6 @@ void ParticlesStorage::particles_request_process(RID p_particles) {
}
AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) {
- if (RSG::threaded) {
- WARN_PRINT_ONCE("Calling this function with threaded rendering enabled stalls the renderer, use with care.");
- }
-
const Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_NULL_V(particles, AABB());
@@ -1642,7 +1637,6 @@ Dependency *ParticlesStorage::particles_get_dependency(RID p_particles) const {
}
bool ParticlesStorage::particles_is_inactive(RID p_particles) const {
- ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer.");
const Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_NULL_V(particles, false);
return !particles->emitting && particles->inactive;
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 5bf0ab0ba6..7e5ccee0e3 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -69,9 +69,6 @@ void RenderingServerDefault::request_frame_drawn_callback(const Callable &p_call
}
void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
- //needs to be done before changes is reset to 0, to not force the editor to redraw
- RS::get_singleton()->emit_signal(SNAME("frame_pre_draw"));
-
changes = 0;
RSG::rasterizer->begin_frame(frame_step);
@@ -220,16 +217,9 @@ void RenderingServerDefault::_finish() {
void RenderingServerDefault::init() {
if (create_thread) {
- print_verbose("RenderingServerWrapMT: Creating render thread");
+ print_verbose("RenderingServerWrapMT: Starting render thread");
DisplayServer::get_singleton()->release_rendering_thread();
- if (create_thread) {
- thread.start(_thread_callback, this);
- print_verbose("RenderingServerWrapMT: Starting render thread");
- }
- while (!draw_thread_up.is_set()) {
- OS::get_singleton()->delay_usec(1000);
- }
- print_verbose("RenderingServerWrapMT: Finished render thread");
+ server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &RenderingServerDefault::_thread_loop), true);
} else {
_init();
}
@@ -238,8 +228,9 @@ void RenderingServerDefault::init() {
void RenderingServerDefault::finish() {
if (create_thread) {
command_queue.push(this, &RenderingServerDefault::_thread_exit);
- if (thread.is_started()) {
- thread.wait_to_finish();
+ if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
+ server_task_id = WorkerThreadPool::INVALID_TASK_ID;
}
} else {
_finish();
@@ -337,38 +328,29 @@ Size2i RenderingServerDefault::get_maximum_viewport_size() const {
}
void RenderingServerDefault::_thread_exit() {
- exit.set();
+ exit = true;
}
void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) {
_draw(p_swap_buffers, frame_step);
}
-void RenderingServerDefault::_thread_flush() {
-}
-
-void RenderingServerDefault::_thread_callback(void *_instance) {
- RenderingServerDefault *vsmt = reinterpret_cast<RenderingServerDefault *>(_instance);
-
- vsmt->_thread_loop();
-}
-
void RenderingServerDefault::_thread_loop() {
server_thread = Thread::get_caller_id();
- DisplayServer::get_singleton()->make_rendering_thread();
-
+ DisplayServer::get_singleton()->gl_window_make_current(DisplayServer::MAIN_WINDOW_ID); // Move GL to this thread.
_init();
- draw_thread_up.set();
- while (!exit.is_set()) {
- // flush commands one by one, until exit is requested
- command_queue.wait_and_flush();
+ command_queue.set_pump_task_id(server_task_id);
+ while (!exit) {
+ WorkerThreadPool::get_singleton()->yield();
+ command_queue.flush_all();
}
- command_queue.flush_all(); // flush all
+ command_queue.flush_all();
_finish();
+ DisplayServer::get_singleton()->release_rendering_thread();
}
/* INTERPOLATION */
@@ -384,15 +366,15 @@ void RenderingServerDefault::set_physics_interpolation_enabled(bool p_enabled) {
/* EVENT QUEUING */
void RenderingServerDefault::sync() {
- if (create_thread) {
- command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush);
- } else {
- command_queue.flush_all(); //flush all pending from other threads
+ if (!create_thread) {
+ command_queue.flush_all(); // Flush all pending from other threads.
}
}
void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "Manually triggering the draw function from the RenderingServer can only be done on the main thread. Call this function from the main thread or use call_deferred().");
+ // Needs to be done before changes is reset to 0, to not force the editor to redraw.
+ RS::get_singleton()->emit_signal(SNAME("frame_pre_draw"));
if (create_thread) {
command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step);
} else {
@@ -404,21 +386,14 @@ void RenderingServerDefault::_call_on_render_thread(const Callable &p_callable)
p_callable.call();
}
-RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
- command_queue(p_create_thread) {
+RenderingServerDefault::RenderingServerDefault(bool p_create_thread) {
RenderingServer::init();
-#ifdef THREADS_ENABLED
create_thread = p_create_thread;
if (!create_thread) {
- server_thread = Thread::get_caller_id();
- } else {
- server_thread = 0;
+ server_thread = Thread::MAIN_ID;
}
-#else
- create_thread = false;
- server_thread = Thread::get_main_id();
-#endif
+
RSG::threaded = create_thread;
RSG::canvas = memnew(RendererCanvasCull);
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index c50472c0cd..f94323f198 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -31,6 +31,7 @@
#ifndef RENDERING_SERVER_DEFAULT_H
#define RENDERING_SERVER_DEFAULT_H
+#include "core/object/worker_thread_pool.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/hash_map.h"
@@ -75,22 +76,17 @@ class RenderingServerDefault : public RenderingServer {
mutable CommandQueueMT command_queue;
- static void _thread_callback(void *_instance);
void _thread_loop();
- Thread::ID server_thread = 0;
- SafeFlag exit;
- Thread thread;
- SafeFlag draw_thread_up;
- bool create_thread;
+ Thread::ID server_thread = Thread::UNASSIGNED_ID;
+ WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
+ bool exit = false;
+ bool create_thread = false;
void _thread_draw(bool p_swap_buffers, double frame_step);
- void _thread_flush();
void _thread_exit();
- Mutex alloc_mutex;
-
void _draw(bool p_swap_buffers, double frame_step);
void _init();
void _finish();
@@ -127,6 +123,10 @@ public:
#define SYNC_DEBUG
#endif
+#ifdef DEBUG_ENABLED
+#define MAIN_THREAD_SYNC_WARN WARN_PRINT("Call to " + String(__FUNCTION__) + " causing RenderingServer synchronizations on every frame. This significantly affects performance.");
+#endif
+
#include "servers/server_wrap_mt_common.h"
/* TEXTURE API */
@@ -1013,6 +1013,9 @@ public:
#undef ServerName
#undef WRITE_ACTION
#undef SYNC_DEBUG
+#ifdef DEBUG_ENABLED
+#undef MAIN_THREAD_SYNC_WARN
+#endif
virtual uint64_t get_rendering_info(RenderingInfo p_info) override;
virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 96d317ebd3..bbe6b1ad0d 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -83,25 +83,16 @@ static PackedInt64Array to_int_array(const Vector<ObjectID> &ids) {
}
PackedInt64Array RenderingServer::_instances_cull_aabb_bind(const AABB &p_aabb, RID p_scenario) const {
- if (RSG::threaded) {
- WARN_PRINT_ONCE("Using this function with a threaded renderer hurts performance, as it causes a server stall.");
- }
Vector<ObjectID> ids = instances_cull_aabb(p_aabb, p_scenario);
return to_int_array(ids);
}
PackedInt64Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
- if (RSG::threaded) {
- WARN_PRINT_ONCE("Using this function with a threaded renderer hurts performance, as it causes a server stall.");
- }
Vector<ObjectID> ids = instances_cull_ray(p_from, p_to, p_scenario);
return to_int_array(ids);
}
PackedInt64Array RenderingServer::_instances_cull_convex_bind(const TypedArray<Plane> &p_convex, RID p_scenario) const {
- if (RSG::threaded) {
- WARN_PRINT_ONCE("Using this function with a threaded renderer hurts performance, as it causes a server stall.");
- }
Vector<Plane> planes;
for (int i = 0; i < p_convex.size(); ++i) {
const Variant &v = p_convex[i];
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index 1a73c97fc7..40867490ca 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -31,12 +31,22 @@
#ifndef SERVER_WRAP_MT_COMMON_H
#define SERVER_WRAP_MT_COMMON_H
+#ifdef DEBIG_ENABLED
+#define MAIN_THREAD_SYNC_CHECK \
+ if (unlikely(Thread::is_main_thread() && Engine::get_singleton()->notify_frame_server_synced())) { \
+ MAIN_THREAD_SYNC_WARN \
+ }
+#else
+#define MAIN_THREAD_SYNC_CHECK
+#endif
+
#define FUNC0R(m_r, m_type) \
virtual m_r m_type() override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -68,6 +78,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -102,6 +113,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(); \
@@ -113,6 +125,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(); \
@@ -128,6 +141,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -141,6 +155,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -154,6 +169,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1); \
@@ -165,6 +181,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1); \
@@ -199,6 +216,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -212,6 +230,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -225,6 +244,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
@@ -236,6 +256,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
@@ -270,6 +291,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -283,6 +305,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -296,6 +319,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
@@ -307,6 +331,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
@@ -341,6 +366,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -354,6 +380,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -367,6 +394,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4); \
@@ -378,6 +406,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4); \
@@ -412,6 +441,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -425,6 +455,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -438,6 +469,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -449,6 +481,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -483,6 +516,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -496,6 +530,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -509,6 +544,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -520,6 +556,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -554,6 +591,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -567,6 +605,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -580,6 +619,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -591,6 +631,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -625,6 +666,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -638,6 +680,7 @@
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
return ret; \
} else { \
command_queue.flush_if_pending(); \
@@ -651,6 +694,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
@@ -662,6 +706,7 @@
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
SYNC_DEBUG \
+ MAIN_THREAD_SYNC_CHECK \
} else { \
command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \