From 30c92caf4d96f5793f3e233671b8e0fdae0c7459 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 12 May 2023 16:36:50 +0200 Subject: [PATCH] Use WorkerThreadPool for Server threads * Servers now use WorkerThreadPool for background computation. * This helps keep the number of threads used fixed at all times. * It also ensures everything works on HTML5 with threads. * And makes it easier to support disabling threads for also HTML5. The only downside of this is that GLES3 threads likely no longer work because every time the render thread is called, the thread context is different. This needs to be researched how to fix. Maybe if GLES3 is used, threaded rendering server should be disabled for the time being? --- core/config/engine.cpp | 15 + core/config/engine.h | 7 + drivers/gles3/rasterizer_gles3.cpp | 4 + drivers/gles3/rasterizer_gles3.h | 2 + main/main.cpp | 4 +- servers/physics_server_2d_wrap_mt.cpp | 67 +- servers/physics_server_2d_wrap_mt.h | 21 +- servers/physics_server_3d_wrap_mt.cpp | 67 +- servers/physics_server_3d_wrap_mt.h | 23 +- servers/rendering/renderer_compositor.h | 2 + .../rendering/rendering_server_default.cpp | 99 +-- servers/rendering/rendering_server_default.h | 25 +- servers/server_wrap_mt_common.h | 795 ++++++++++-------- 13 files changed, 598 insertions(+), 533 deletions(-) diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 24080c056a02..10754bba1eea 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -82,6 +82,16 @@ int Engine::get_audio_output_latency() const { return _audio_output_latency; } +void Engine::increment_frames_drawn() { + if (frame_server_synced) { + server_syncs++; + } else { + server_syncs = 0; + } + frame_server_synced = 0; + + frames_drawn++; +} uint64_t Engine::get_frames_drawn() { return frames_drawn; } @@ -351,6 +361,11 @@ Engine *Engine::get_singleton() { return singleton; } +bool Engine::notify_frame_server_synced() { + frame_server_synced = true; + return server_syncs > server_sync_frame_count_warning; +} + Engine::Engine() { singleton = this; } diff --git a/core/config/engine.h b/core/config/engine.h index b64309a9e838..ef2f456a5c4d 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -89,6 +89,10 @@ class Engine { String write_movie_path; String shader_cache_path; + static constexpr int server_sync_frame_count_warning = 5; + int server_syncs = 0; + bool frame_server_synced = false; + public: static Engine *get_singleton(); @@ -175,6 +179,9 @@ class Engine { bool is_generate_spirv_debug_info_enabled() const; int32_t get_gpu_index() const; + void increment_frames_drawn(); + bool notify_frame_server_synced(); + Engine(); virtual ~Engine() {} }; diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 6ab98a9473f9..d0e16115ce55 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -115,6 +115,10 @@ void RasterizerGLES3::end_viewport(bool p_swap_buffers) { } } +void RasterizerGLES3::context_move_to_current_thread() { + DisplayServer::get_singleton()->make_rendering_thread(); +} + void RasterizerGLES3::clear_depth(float p_depth) { #ifdef GL_API_ENABLED if (is_gles_over_gl()) { diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index d9f436a2ec4a..646ff7faa126 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -115,6 +115,8 @@ class RasterizerGLES3 : public RendererCompositor { _ALWAYS_INLINE_ double get_frame_delta_time() const { return delta; } _ALWAYS_INLINE_ double get_total_time() const { return time_total; } + virtual void context_move_to_current_thread(); + static RasterizerGLES3 *get_singleton() { return singleton; } RasterizerGLES3(); ~RasterizerGLES3(); diff --git a/main/main.cpp b/main/main.cpp index dbe186d63ab9..4cf102ac2189 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -3799,11 +3799,11 @@ bool Main::iteration() { if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) { if (RenderingServer::get_singleton()->has_changed()) { RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands - Engine::get_singleton()->frames_drawn++; + Engine::get_singleton()->increment_frames_drawn(); } } else { RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands - Engine::get_singleton()->frames_drawn++; + Engine::get_singleton()->increment_frames_drawn(); force_redraw_requested = false; } } diff --git a/servers/physics_server_2d_wrap_mt.cpp b/servers/physics_server_2d_wrap_mt.cpp index a23bb5e7019d..b892fdd8ffe8 100644 --- a/servers/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_server_2d_wrap_mt.cpp @@ -32,43 +32,28 @@ #include "core/os/os.h" -void PhysicsServer2DWrapMT::thread_exit() { - exit.set(); -} - void PhysicsServer2DWrapMT::thread_step(real_t p_delta) { + server_thread = Thread::get_caller_id(); + command_queue.flush_all(); physics_server_2d->step(p_delta); - step_sem.post(); -} - -void PhysicsServer2DWrapMT::_thread_callback(void *_instance) { - PhysicsServer2DWrapMT *vsmt = reinterpret_cast(_instance); - - vsmt->thread_loop(); + command_queue.flush_all(); // Flush pending commands before and after + server_thread = Thread::UNASSIGNED_ID; } -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(); +void PhysicsServer2DWrapMT::_main_thread_sync() { + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } - command_queue.flush_all(); // flush all - - physics_server_2d->finish(); + server_thread = Thread::MAIN_ID; } /* EVENT QUEUING */ void PhysicsServer2DWrapMT::step(real_t p_step) { if (create_thread) { - command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step); + task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::thread_step).bind(p_step), true); } else { command_queue.flush_all(); //flush all pending from other threads physics_server_2d->step(p_step); @@ -77,10 +62,9 @@ void PhysicsServer2DWrapMT::step(real_t 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 + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } } physics_server_2d->sync(); @@ -95,24 +79,15 @@ 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); - } - } else { - physics_server_2d->init(); - } + physics_server_2d->init(); } void PhysicsServer2DWrapMT::finish() { - if (thread.is_started()) { - command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit); - thread.wait_to_finish(); - } else { - physics_server_2d->finish(); + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } + physics_server_2d->finish(); } PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) : @@ -121,12 +96,12 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool create_thread = p_create_thread; if (!p_create_thread) { - server_thread = Thread::get_caller_id(); + server_thread = Thread::MAIN_ID; } else { - server_thread = 0; + server_thread = Thread::UNASSIGNED_ID; } - main_thread = Thread::get_caller_id(); + main_thread = Thread::MAIN_ID; } PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() { diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index 3bebe5df851c..16d19084887b 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,29 +44,38 @@ #define SYNC_DEBUG #endif +#ifdef DEBUG_ENABLED +#define MAIN_THREAD_SYNC \ + if (Engine::get_singleton()->notify_frame_server_synced()) { \ + WARN_PRINT("Call to " + String(__FUNCTION__) + " causing PhysicsServer2D synchronizations on every frame. This significantly affects performance."); \ + } \ + const_cast(this)->_main_thread_sync(); +#else +#define MAIN_THREAD_SYNC const_cast(this)->_main_thread_sync(); +#endif + class PhysicsServer2DWrapMT : public PhysicsServer2D { mutable PhysicsServer2D *physics_server_2d; 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; bool create_thread = false; + WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID; - Semaphore step_sem; void thread_step(real_t p_delta); void thread_exit(); + void _main_thread_sync(); + bool first_frame = true; Mutex alloc_mutex; + int pool_max_size = 0; public: #define ServerName PhysicsServer2D @@ -337,5 +347,6 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D { #undef DEBUG_SYNC #endif #undef SYNC_DEBUG +#undef MAIN_THREAD_SYNC #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 feb17cad8440..0d5b292e4592 100644 --- a/servers/physics_server_3d_wrap_mt.cpp +++ b/servers/physics_server_3d_wrap_mt.cpp @@ -32,43 +32,28 @@ #include "core/os/os.h" -void PhysicsServer3DWrapMT::thread_exit() { - exit = true; -} - void PhysicsServer3DWrapMT::thread_step(real_t p_delta) { + server_thread = Thread::get_caller_id(); + command_queue.flush_all(); physics_server_3d->step(p_delta); - step_sem.post(); -} - -void PhysicsServer3DWrapMT::_thread_callback(void *_instance) { - PhysicsServer3DWrapMT *vsmt = reinterpret_cast(_instance); - - vsmt->thread_loop(); + command_queue.flush_all(); // Flush pending commands before and after + server_thread = Thread::UNASSIGNED_ID; } -void PhysicsServer3DWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); - - physics_server_3d->init(); - - exit = false; - step_thread_up = true; - while (!exit) { - // flush commands one by one, until exit is requested - command_queue.wait_and_flush(); +void PhysicsServer3DWrapMT::_main_thread_sync() { + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } - command_queue.flush_all(); // flush all - - physics_server_3d->finish(); + server_thread = Thread::MAIN_ID; } /* EVENT QUEUING */ void PhysicsServer3DWrapMT::step(real_t p_step) { if (create_thread) { - command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step); + task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::thread_step).bind(p_step), true); } else { command_queue.flush_all(); //flush all pending from other threads physics_server_3d->step(p_step); @@ -77,10 +62,9 @@ void PhysicsServer3DWrapMT::step(real_t 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 + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } } physics_server_3d->sync(); @@ -95,24 +79,15 @@ 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); - } - } else { - physics_server_3d->init(); - } + physics_server_3d->init(); } void PhysicsServer3DWrapMT::finish() { - if (thread.is_started()) { - command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit); - thread.wait_to_finish(); - } else { - physics_server_3d->finish(); + if (task_id != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id); + task_id = WorkerThreadPool::INVALID_TASK_ID; } + physics_server_3d->finish(); } PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) : @@ -121,12 +96,12 @@ PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool create_thread = p_create_thread; if (!p_create_thread) { - server_thread = Thread::get_caller_id(); + server_thread = Thread::MAIN_ID; } else { - server_thread = 0; + server_thread = Thread::UNASSIGNED_ID; } - main_thread = Thread::get_caller_id(); + main_thread = Thread::MAIN_ID; } PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() { diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index fc8930977d18..1f3874d56249 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,40 @@ #define SYNC_DEBUG #endif +#ifdef DEBUG_ENABLED +#define MAIN_THREAD_SYNC \ + if (Engine::get_singleton()->notify_frame_server_synced()) { \ + WARN_PRINT("Call to " + String(__FUNCTION__) + " causing PhysicsServer3D synchronizations on every frame. This significantly affects performance."); \ + } \ + const_cast(this)->_main_thread_sync(); +#else +#define MAIN_THREAD_SYNC const_cast(this)->_main_thread_sync(); +#endif + class PhysicsServer3DWrapMT : public PhysicsServer3D { mutable PhysicsServer3D *physics_server_3d; 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; bool create_thread = false; + WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID; - Semaphore step_sem; void thread_step(real_t p_delta); void thread_exit(); + void _main_thread_sync(); + bool first_frame = true; Mutex alloc_mutex; + int pool_max_size = 0; + public: #define ServerName PhysicsServer3D #define ServerNameWrapMT PhysicsServer3DWrapMT @@ -411,4 +422,6 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D { #endif #undef SYNC_DEBUG +#undef MAIN_THREAD_SYNC + #endif // PHYSICS_SERVER_3D_WRAP_MT_H diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index 13767a387591..8e5890a91db3 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -109,6 +109,8 @@ class RendererCompositor { static bool is_low_end() { return low_end; }; virtual bool is_xr_enabled() const; + virtual void context_move_to_current_thread() {} + static RendererCompositor *get_singleton() { return singleton; } RendererCompositor(); virtual ~RendererCompositor() {} diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index bf8ab2772210..4711b5f196ea 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -68,8 +68,22 @@ void RenderingServerDefault::request_frame_drawn_callback(const Callable &p_call frame_drawn_callbacks.push_back(p_callable); } +void RenderingServerDefault::_main_thread_sync() { + sync(); + server_thread = Thread::MAIN_ID; + RSG::rasterizer->context_move_to_current_thread(); +} + 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 + if (create_thread) { + if (server_thread != Thread::get_caller_id()) { + RSG::rasterizer->context_move_to_current_thread(); + } + server_thread = Thread::get_caller_id(); + command_queue.flush_all(); // Flush pending commands + } + RS::get_singleton()->emit_signal(SNAME("frame_pre_draw")); changes = 0; @@ -192,6 +206,11 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { } RSG::utilities->update_memory_info(); + + if (create_thread) { + command_queue.flush_all(); + server_thread = Thread::UNASSIGNED_ID; + } } double RenderingServerDefault::get_frame_setup_time_cpu() const { @@ -202,11 +221,13 @@ bool RenderingServerDefault::has_changed() const { return changes > 0; } -void RenderingServerDefault::_init() { +void RenderingServerDefault::init() { RSG::rasterizer->initialize(); } -void RenderingServerDefault::_finish() { +void RenderingServerDefault::finish() { + sync(); // Just in case there is threaded stuff. + if (test_cube.is_valid()) { free(test_cube); } @@ -215,34 +236,6 @@ void RenderingServerDefault::_finish() { RSG::rasterizer->finalize(); } -void RenderingServerDefault::init() { - if (create_thread) { - print_verbose("RenderingServerWrapMT: Creating 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"); - } else { - _init(); - } -} - -void RenderingServerDefault::finish() { - if (create_thread) { - command_queue.push(this, &RenderingServerDefault::_thread_exit); - if (thread.is_started()) { - thread.wait_to_finish(); - } - } else { - _finish(); - } -} - /* STATUS INFORMATION */ uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) { @@ -333,46 +326,14 @@ Size2i RenderingServerDefault::get_maximum_viewport_size() const { } } -void RenderingServerDefault::_thread_exit() { - exit.set(); -} - -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(_instance); - - vsmt->_thread_loop(); -} - -void RenderingServerDefault::_thread_loop() { - server_thread = Thread::get_caller_id(); - - DisplayServer::get_singleton()->make_rendering_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.flush_all(); // flush all - - _finish(); -} - /* EVENT QUEUING */ void RenderingServerDefault::sync() { if (create_thread) { - command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush); + if (render_task != WorkerThreadPool::INVALID_TASK_ID) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(render_task); + render_task = WorkerThreadPool::INVALID_TASK_ID; + } } else { command_queue.flush_all(); //flush all pending from other threads } @@ -381,7 +342,7 @@ void RenderingServerDefault::sync() { 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()."); if (create_thread) { - command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step); + render_task = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &RenderingServerDefault::_draw).bind(p_swap_buffers, frame_step), true); } else { _draw(p_swap_buffers, frame_step); } @@ -398,9 +359,9 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) : #ifdef THREADS_ENABLED create_thread = p_create_thread; if (!create_thread) { - server_thread = Thread::get_caller_id(); + server_thread = Thread::MAIN_ID; } else { - server_thread = 0; + server_thread = Thread::UNASSIGNED_ID; } #else create_thread = false; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index e8b20692f0fa..fa3a14ff7b51 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" @@ -78,22 +79,17 @@ class RenderingServerDefault : public RenderingServer { static void _thread_callback(void *_instance); void _thread_loop(); - Thread::ID server_thread = 0; + Thread::ID server_thread = Thread::MAIN_ID; // Using main thread by default SafeFlag exit; Thread thread; + SafeFlag draw_thread_up; bool create_thread; + WorkerThreadPool::TaskID render_task = WorkerThreadPool::INVALID_TASK_ID; - void _thread_draw(bool p_swap_buffers, double frame_step); - void _thread_flush(); - - void _thread_exit(); - - Mutex alloc_mutex; + void _main_thread_sync(); void _draw(bool p_swap_buffers, double frame_step); - void _init(); - void _finish(); void _free(RID p_rid); @@ -127,6 +123,16 @@ class RenderingServerDefault : public RenderingServer { #define SYNC_DEBUG #endif +#ifdef DEBUG_ENABLED +#define MAIN_THREAD_SYNC \ + if (Engine::get_singleton()->notify_frame_server_synced()) { \ + WARN_PRINT("Call to " + String(__FUNCTION__) + " causing RenderingServer synchronizations on every frame. This significantly affects performance."); \ + } \ + const_cast(this)->_main_thread_sync(); +#else +#define MAIN_THREAD_SYNC const_cast(this)->_main_thread_sync(); +#endif + #include "servers/server_wrap_mt_common.h" /* TEXTURE API */ @@ -973,6 +979,7 @@ class RenderingServerDefault : public RenderingServer { #undef ServerName #undef WRITE_ACTION #undef SYNC_DEBUG +#undef MAIN_THREAD_SYNC virtual uint64_t get_rendering_info(RenderingInfo p_info) override; virtual RenderingDevice::DeviceType get_video_adapter_type() const override; diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index 1a73c97fc7df..5483c91de814 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -31,17 +31,19 @@ #ifndef SERVER_WRAP_MT_COMMON_H #define SERVER_WRAP_MT_COMMON_H -#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 \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(); \ - } \ +#define FUNC0R(m_r, m_type) \ + virtual m_r m_type() override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(); \ } #define FUNCRIDSPLIT(m_type) \ @@ -61,18 +63,20 @@ return server_name->m_type##_create(); \ } -#define FUNC0RC(m_r, m_type) \ - virtual m_r m_type() const override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(); \ - } \ +#define FUNC0RC(m_r, m_type) \ + virtual m_r m_type() const override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(); \ } #define FUNC0(m_type) \ @@ -96,79 +100,97 @@ } \ } -#define FUNC0S(m_type) \ - virtual void m_type() override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(); \ - } \ +#define FUNC0S(m_type) \ + virtual void m_type() override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(); \ + } \ } -#define FUNC0SC(m_type) \ - virtual void m_type() const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(); \ - } \ +#define FUNC0SC(m_type) \ + virtual void m_type() const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(); \ + } \ } /////////////////////////////////////////////// -#define FUNC1R(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1); \ - } \ +#define FUNC1R(m_r, m_type, m_arg1) \ + virtual m_r m_type(m_arg1 p1) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1); \ } -#define FUNC1RC(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1); \ - } \ +#define FUNC1RC(m_r, m_type, m_arg1) \ + virtual m_r m_type(m_arg1 p1) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1); \ } -#define FUNC1S(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1); \ - } \ +#define FUNC1S(m_type, m_arg1) \ + virtual void m_type(m_arg1 p1) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1); \ } -#define FUNC1SC(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1); \ - } \ +#define FUNC1SC(m_type, m_arg1) \ + virtual void m_type(m_arg1 p1) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1); \ } #define FUNC1(m_type, m_arg1) \ @@ -192,54 +214,64 @@ } \ } -#define FUNC2R(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2); \ - } \ +#define FUNC2R(m_r, m_type, m_arg1, m_arg2) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2); \ } -#define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2); \ - } \ +#define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2); \ } -#define FUNC2S(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2); \ - } \ +#define FUNC2S(m_type, m_arg1, m_arg2) \ + virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2); \ } -#define FUNC2SC(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2); \ - } \ +#define FUNC2SC(m_type, m_arg1, m_arg2) \ + virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2); \ } #define FUNC2(m_type, m_arg1, m_arg2) \ @@ -263,54 +295,64 @@ } \ } -#define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3); \ - } \ +#define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3); \ } -#define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3); \ - } \ +#define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3); \ } -#define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3); \ - } \ +#define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3); \ } -#define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3); \ - } \ +#define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3); \ } #define FUNC3(m_type, m_arg1, m_arg2, m_arg3) \ @@ -334,54 +376,64 @@ } \ } -#define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4); \ } -#define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4); \ } -#define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4); \ } -#define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4); \ } #define FUNC4(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ @@ -405,54 +457,65 @@ } \ } -#define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5); \ - } \ - } - -#define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5); \ - } \ - } - -#define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5); \ } -#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - SYNC_DEBUG \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5); \ + } + +#define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } + +#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } #define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ @@ -476,54 +539,64 @@ } \ } -#define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ - } - -#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ - } - -#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ - WRITE_ACTION \ - 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } + +#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } + +#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ } #define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ } #define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ @@ -547,54 +620,64 @@ } \ } -#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ - WRITE_ACTION \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ +#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ + } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ } #define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ } #define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ WRITE_ACTION \ 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ } #define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ } #define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ @@ -622,50 +705,60 @@ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ } #define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - command_queue.flush_if_pending(); \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ } #define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ WRITE_ACTION \ 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ } #define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ 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 \ - } else { \ - command_queue.flush_if_pending(); \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + if (Thread::get_caller_id() != Thread::MAIN_ID) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + return; \ + } \ + MAIN_THREAD_SYNC \ } \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ } #define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \