mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 11:32:13 +00:00
Apply additional fixes to servers' threading
This commit is contained in:
parent
6f0760beb3
commit
1589433e8f
@ -388,6 +388,8 @@ class CommandQueueMT {
|
|||||||
} while (sync_head != sync_head_goal); // Can't use lower-than because of wraparound.
|
} while (sync_head != sync_head_goal); // Can't use lower-than because of wraparound.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _no_op() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void lock();
|
void lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
@ -409,10 +411,15 @@ public:
|
|||||||
_flush();
|
_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_all() {
|
void flush_all() {
|
||||||
_flush();
|
_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sync() {
|
||||||
|
push_and_sync(this, &CommandQueueMT::_no_op);
|
||||||
|
}
|
||||||
|
|
||||||
void wait_and_flush() {
|
void wait_and_flush() {
|
||||||
ERR_FAIL_COND(pump_task_id == WorkerThreadPool::INVALID_TASK_ID);
|
ERR_FAIL_COND(pump_task_id == WorkerThreadPool::INVALID_TASK_ID);
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(pump_task_id);
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(pump_task_id);
|
||||||
@ -420,7 +427,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_pump_task_id(WorkerThreadPool::TaskID p_task_id) {
|
void set_pump_task_id(WorkerThreadPool::TaskID p_task_id) {
|
||||||
|
lock();
|
||||||
pump_task_id = p_task_id;
|
pump_task_id = p_task_id;
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandQueueMT();
|
CommandQueueMT();
|
||||||
|
@ -395,10 +395,13 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
|
|||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
|
||||||
|
|
||||||
if (p_first) {
|
if (p_first) {
|
||||||
Size2i win_size = DisplayServer::get_singleton()->window_get_size();
|
|
||||||
if (p_screen_rect.position != Vector2() || p_screen_rect.size != rt->size) {
|
if (p_screen_rect.position != Vector2() || p_screen_rect.size != rt->size) {
|
||||||
// Viewport doesn't cover entire window so clear window to black before blitting.
|
// Viewport doesn't cover entire window so clear window to black before blitting.
|
||||||
glViewport(0, 0, win_size.width, win_size.height);
|
// Querying the actual window size from the DisplayServer would deadlock in separate render thread mode,
|
||||||
|
// so let's set the biggest viewport the implementation supports, to be sure the window is fully covered.
|
||||||
|
GLsizei max_vp[2] = {};
|
||||||
|
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_vp);
|
||||||
|
glViewport(0, 0, max_vp[0], max_vp[1]);
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
@ -32,45 +32,37 @@
|
|||||||
|
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::thread_exit() {
|
void PhysicsServer2DWrapMT::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
|
||||||
|
server_thread = Thread::get_caller_id();
|
||||||
|
server_task_id = p_pump_task_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsServer2DWrapMT::_thread_exit() {
|
||||||
exit = true;
|
exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
|
void PhysicsServer2DWrapMT::_thread_loop() {
|
||||||
physics_server_2d->step(p_delta);
|
|
||||||
step_sem.post();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::thread_loop() {
|
|
||||||
server_thread = Thread::get_caller_id();
|
|
||||||
|
|
||||||
physics_server_2d->init();
|
|
||||||
|
|
||||||
command_queue.set_pump_task_id(server_task_id);
|
|
||||||
while (!exit) {
|
while (!exit) {
|
||||||
WorkerThreadPool::get_singleton()->yield();
|
WorkerThreadPool::get_singleton()->yield();
|
||||||
command_queue.flush_all();
|
command_queue.flush_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
command_queue.flush_all();
|
|
||||||
|
|
||||||
physics_server_2d->finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVENT QUEUING */
|
/* EVENT QUEUING */
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::step(real_t p_step) {
|
void PhysicsServer2DWrapMT::step(real_t p_step) {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step);
|
command_queue.push(physics_server_2d, &PhysicsServer2D::step, p_step);
|
||||||
} else {
|
} else {
|
||||||
command_queue.flush_all(); // Flush all pending from other threads.
|
|
||||||
physics_server_2d->step(p_step);
|
physics_server_2d->step(p_step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::sync() {
|
void PhysicsServer2DWrapMT::sync() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
step_sem.wait();
|
command_queue.sync();
|
||||||
|
} else {
|
||||||
|
command_queue.flush_all(); // Flush all pending from other threads.
|
||||||
}
|
}
|
||||||
physics_server_2d->sync();
|
physics_server_2d->sync();
|
||||||
}
|
}
|
||||||
@ -85,21 +77,26 @@ void PhysicsServer2DWrapMT::end_sync() {
|
|||||||
|
|
||||||
void PhysicsServer2DWrapMT::init() {
|
void PhysicsServer2DWrapMT::init() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
exit = false;
|
WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::_thread_loop), true);
|
||||||
server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::thread_loop), true);
|
command_queue.set_pump_task_id(tid);
|
||||||
step_sem.post();
|
command_queue.push(this, &PhysicsServer2DWrapMT::_assign_mt_ids, tid);
|
||||||
|
command_queue.push_and_sync(physics_server_2d, &PhysicsServer2D::init);
|
||||||
|
DEV_ASSERT(server_task_id == tid);
|
||||||
} else {
|
} else {
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
physics_server_2d->init();
|
physics_server_2d->init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer2DWrapMT::finish() {
|
void PhysicsServer2DWrapMT::finish() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
|
command_queue.push(physics_server_2d, &PhysicsServer2D::finish);
|
||||||
|
command_queue.push(this, &PhysicsServer2DWrapMT::_thread_exit);
|
||||||
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
||||||
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
}
|
}
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
} else {
|
} else {
|
||||||
physics_server_2d->finish();
|
physics_server_2d->finish();
|
||||||
}
|
}
|
||||||
@ -108,9 +105,6 @@ void PhysicsServer2DWrapMT::finish() {
|
|||||||
PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) {
|
PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) {
|
||||||
physics_server_2d = p_contained;
|
physics_server_2d = p_contained;
|
||||||
create_thread = p_create_thread;
|
create_thread = p_create_thread;
|
||||||
if (!create_thread) {
|
|
||||||
server_thread = Thread::MAIN_ID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {
|
PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {
|
||||||
|
@ -53,17 +53,14 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D {
|
|||||||
|
|
||||||
mutable CommandQueueMT command_queue;
|
mutable CommandQueueMT command_queue;
|
||||||
|
|
||||||
void thread_loop();
|
|
||||||
|
|
||||||
Thread::ID server_thread = Thread::UNASSIGNED_ID;
|
Thread::ID server_thread = Thread::UNASSIGNED_ID;
|
||||||
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
Semaphore step_sem;
|
|
||||||
bool create_thread = false;
|
bool create_thread = false;
|
||||||
|
|
||||||
void thread_step(real_t p_delta);
|
void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id);
|
||||||
|
void _thread_exit();
|
||||||
void thread_exit();
|
void _thread_loop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#define ServerName PhysicsServer2D
|
#define ServerName PhysicsServer2D
|
||||||
|
@ -32,45 +32,37 @@
|
|||||||
|
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::thread_exit() {
|
void PhysicsServer3DWrapMT::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
|
||||||
|
server_thread = Thread::get_caller_id();
|
||||||
|
server_task_id = p_pump_task_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsServer3DWrapMT::_thread_exit() {
|
||||||
exit = true;
|
exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::thread_step(real_t p_delta) {
|
void PhysicsServer3DWrapMT::_thread_loop() {
|
||||||
physics_server_3d->step(p_delta);
|
|
||||||
step_sem.post();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::thread_loop() {
|
|
||||||
server_thread = Thread::get_caller_id();
|
|
||||||
|
|
||||||
physics_server_3d->init();
|
|
||||||
|
|
||||||
command_queue.set_pump_task_id(server_task_id);
|
|
||||||
while (!exit) {
|
while (!exit) {
|
||||||
WorkerThreadPool::get_singleton()->yield();
|
WorkerThreadPool::get_singleton()->yield();
|
||||||
command_queue.flush_all();
|
command_queue.flush_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
command_queue.flush_all(); // flush all
|
|
||||||
|
|
||||||
physics_server_3d->finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVENT QUEUING */
|
/* EVENT QUEUING */
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::step(real_t p_step) {
|
void PhysicsServer3DWrapMT::step(real_t p_step) {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step);
|
command_queue.push(physics_server_3d, &PhysicsServer3D::step, p_step);
|
||||||
} else {
|
} else {
|
||||||
command_queue.flush_all(); // Flush all pending from other threads.
|
|
||||||
physics_server_3d->step(p_step);
|
physics_server_3d->step(p_step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::sync() {
|
void PhysicsServer3DWrapMT::sync() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
step_sem.wait();
|
command_queue.sync();
|
||||||
|
} else {
|
||||||
|
command_queue.flush_all(); // Flush all pending from other threads.
|
||||||
}
|
}
|
||||||
physics_server_3d->sync();
|
physics_server_3d->sync();
|
||||||
}
|
}
|
||||||
@ -85,21 +77,26 @@ void PhysicsServer3DWrapMT::end_sync() {
|
|||||||
|
|
||||||
void PhysicsServer3DWrapMT::init() {
|
void PhysicsServer3DWrapMT::init() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
exit = false;
|
WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::_thread_loop), true);
|
||||||
server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::thread_loop), true);
|
command_queue.set_pump_task_id(tid);
|
||||||
step_sem.post();
|
command_queue.push(this, &PhysicsServer3DWrapMT::_assign_mt_ids, tid);
|
||||||
|
command_queue.push_and_sync(physics_server_3d, &PhysicsServer3D::init);
|
||||||
|
DEV_ASSERT(server_task_id == tid);
|
||||||
} else {
|
} else {
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
physics_server_3d->init();
|
physics_server_3d->init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsServer3DWrapMT::finish() {
|
void PhysicsServer3DWrapMT::finish() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit);
|
command_queue.push(physics_server_3d, &PhysicsServer3D::finish);
|
||||||
|
command_queue.push(this, &PhysicsServer3DWrapMT::_thread_exit);
|
||||||
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
||||||
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
}
|
}
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
} else {
|
} else {
|
||||||
physics_server_3d->finish();
|
physics_server_3d->finish();
|
||||||
}
|
}
|
||||||
@ -108,9 +105,6 @@ void PhysicsServer3DWrapMT::finish() {
|
|||||||
PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) {
|
PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) {
|
||||||
physics_server_3d = p_contained;
|
physics_server_3d = p_contained;
|
||||||
create_thread = p_create_thread;
|
create_thread = p_create_thread;
|
||||||
if (!create_thread) {
|
|
||||||
server_thread = Thread::MAIN_ID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {
|
PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {
|
||||||
|
@ -52,17 +52,15 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D {
|
|||||||
|
|
||||||
mutable CommandQueueMT command_queue;
|
mutable CommandQueueMT command_queue;
|
||||||
|
|
||||||
void thread_loop();
|
|
||||||
|
|
||||||
Thread::ID server_thread = Thread::UNASSIGNED_ID;
|
Thread::ID server_thread = Thread::UNASSIGNED_ID;
|
||||||
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
Semaphore step_sem;
|
|
||||||
bool create_thread = false;
|
bool create_thread = false;
|
||||||
|
|
||||||
void thread_step(real_t p_delta);
|
void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id);
|
||||||
|
void _thread_exit();
|
||||||
void thread_exit();
|
void _thread_step(real_t p_delta);
|
||||||
|
void _thread_loop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#define ServerName PhysicsServer3D
|
#define ServerName PhysicsServer3D
|
||||||
|
@ -678,7 +678,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
|||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
|
RSG::texture_storage->set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sorted_active_viewports_dirty) {
|
if (sorted_active_viewports_dirty) {
|
||||||
@ -1521,10 +1521,6 @@ void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererViewport::set_default_clear_color(const Color &p_color) {
|
|
||||||
RSG::texture_storage->set_default_clear_color(p_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) {
|
void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) {
|
||||||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||||
ERR_FAIL_NULL(viewport);
|
ERR_FAIL_NULL(viewport);
|
||||||
|
@ -303,7 +303,6 @@ public:
|
|||||||
|
|
||||||
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
|
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
|
||||||
|
|
||||||
void set_default_clear_color(const Color &p_color);
|
|
||||||
void draw_viewports(bool p_swap_buffers);
|
void draw_viewports(bool p_swap_buffers);
|
||||||
|
|
||||||
bool free(RID p_rid);
|
bool free(RID p_rid);
|
||||||
|
@ -69,8 +69,6 @@ void RenderingServerDefault::request_frame_drawn_callback(const Callable &p_call
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
||||||
changes = 0;
|
|
||||||
|
|
||||||
RSG::rasterizer->begin_frame(frame_step);
|
RSG::rasterizer->begin_frame(frame_step);
|
||||||
|
|
||||||
TIMESTAMP_BEGIN()
|
TIMESTAMP_BEGIN()
|
||||||
@ -102,19 +100,11 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
|||||||
RSG::canvas->update_visibility_notifiers();
|
RSG::canvas->update_visibility_notifiers();
|
||||||
RSG::scene->update_visibility_notifiers();
|
RSG::scene->update_visibility_notifiers();
|
||||||
|
|
||||||
while (frame_drawn_callbacks.front()) {
|
if (create_thread) {
|
||||||
Callable c = frame_drawn_callbacks.front()->get();
|
callable_mp(this, &RenderingServerDefault::_run_post_draw_steps).call_deferred();
|
||||||
Variant result;
|
} else {
|
||||||
Callable::CallError ce;
|
_run_post_draw_steps();
|
||||||
c.callp(nullptr, 0, result, ce);
|
|
||||||
if (ce.error != Callable::CallError::CALL_OK) {
|
|
||||||
String err = Variant::get_callable_error_text(c, nullptr, 0, ce);
|
|
||||||
ERR_PRINT("Error calling frame drawn function: " + err);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_drawn_callbacks.pop_front();
|
|
||||||
}
|
}
|
||||||
RS::get_singleton()->emit_signal(SNAME("frame_post_draw"));
|
|
||||||
|
|
||||||
if (RSG::utilities->get_captured_timestamps_count()) {
|
if (RSG::utilities->get_captured_timestamps_count()) {
|
||||||
Vector<FrameProfileArea> new_profile;
|
Vector<FrameProfileArea> new_profile;
|
||||||
@ -194,6 +184,23 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
|||||||
RSG::utilities->update_memory_info();
|
RSG::utilities->update_memory_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingServerDefault::_run_post_draw_steps() {
|
||||||
|
while (frame_drawn_callbacks.front()) {
|
||||||
|
Callable c = frame_drawn_callbacks.front()->get();
|
||||||
|
Variant result;
|
||||||
|
Callable::CallError ce;
|
||||||
|
c.callp(nullptr, 0, result, ce);
|
||||||
|
if (ce.error != Callable::CallError::CALL_OK) {
|
||||||
|
String err = Variant::get_callable_error_text(c, nullptr, 0, ce);
|
||||||
|
ERR_PRINT("Error calling frame drawn function: " + err);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_drawn_callbacks.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_signal(SNAME("frame_post_draw"));
|
||||||
|
}
|
||||||
|
|
||||||
double RenderingServerDefault::get_frame_setup_time_cpu() const {
|
double RenderingServerDefault::get_frame_setup_time_cpu() const {
|
||||||
return frame_setup_time;
|
return frame_setup_time;
|
||||||
}
|
}
|
||||||
@ -203,7 +210,25 @@ bool RenderingServerDefault::has_changed() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::_init() {
|
void RenderingServerDefault::_init() {
|
||||||
|
RSG::threaded = create_thread;
|
||||||
|
|
||||||
|
RSG::canvas = memnew(RendererCanvasCull);
|
||||||
|
RSG::viewport = memnew(RendererViewport);
|
||||||
|
RendererSceneCull *sr = memnew(RendererSceneCull);
|
||||||
|
RSG::camera_attributes = memnew(RendererCameraAttributes);
|
||||||
|
RSG::scene = sr;
|
||||||
|
RSG::rasterizer = RendererCompositor::create();
|
||||||
|
RSG::utilities = RSG::rasterizer->get_utilities();
|
||||||
RSG::rasterizer->initialize();
|
RSG::rasterizer->initialize();
|
||||||
|
RSG::light_storage = RSG::rasterizer->get_light_storage();
|
||||||
|
RSG::material_storage = RSG::rasterizer->get_material_storage();
|
||||||
|
RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
|
||||||
|
RSG::particles_storage = RSG::rasterizer->get_particles_storage();
|
||||||
|
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
|
||||||
|
RSG::gi = RSG::rasterizer->get_gi();
|
||||||
|
RSG::fog = RSG::rasterizer->get_fog();
|
||||||
|
RSG::canvas_render = RSG::rasterizer->get_canvas();
|
||||||
|
sr->set_scene_render(RSG::rasterizer->get_scene());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::_finish() {
|
void RenderingServerDefault::_finish() {
|
||||||
@ -212,26 +237,38 @@ void RenderingServerDefault::_finish() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RSG::canvas->finalize();
|
RSG::canvas->finalize();
|
||||||
|
memdelete(RSG::canvas);
|
||||||
RSG::rasterizer->finalize();
|
RSG::rasterizer->finalize();
|
||||||
|
memdelete(RSG::viewport);
|
||||||
|
memdelete(RSG::rasterizer);
|
||||||
|
memdelete(RSG::scene);
|
||||||
|
memdelete(RSG::camera_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::init() {
|
void RenderingServerDefault::init() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
print_verbose("RenderingServerWrapMT: Starting render thread");
|
print_verbose("RenderingServerWrapMT: Starting render thread");
|
||||||
DisplayServer::get_singleton()->release_rendering_thread();
|
DisplayServer::get_singleton()->release_rendering_thread();
|
||||||
server_task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &RenderingServerDefault::_thread_loop), true);
|
WorkerThreadPool::TaskID tid = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &RenderingServerDefault::_thread_loop), true);
|
||||||
|
command_queue.set_pump_task_id(tid);
|
||||||
|
command_queue.push(this, &RenderingServerDefault::_assign_mt_ids, tid);
|
||||||
|
command_queue.push_and_sync(this, &RenderingServerDefault::_init);
|
||||||
|
DEV_ASSERT(server_task_id == tid);
|
||||||
} else {
|
} else {
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
_init();
|
_init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::finish() {
|
void RenderingServerDefault::finish() {
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
|
command_queue.push(this, &RenderingServerDefault::_finish);
|
||||||
command_queue.push(this, &RenderingServerDefault::_thread_exit);
|
command_queue.push(this, &RenderingServerDefault::_thread_exit);
|
||||||
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
if (server_task_id != WorkerThreadPool::INVALID_TASK_ID) {
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(server_task_id);
|
||||||
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
}
|
}
|
||||||
|
server_thread = Thread::MAIN_ID;
|
||||||
} else {
|
} else {
|
||||||
_finish();
|
_finish();
|
||||||
}
|
}
|
||||||
@ -268,17 +305,12 @@ Vector<RenderingServer::FrameProfileArea> RenderingServerDefault::get_frame_prof
|
|||||||
|
|
||||||
/* TESTING */
|
/* TESTING */
|
||||||
|
|
||||||
void RenderingServerDefault::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
|
|
||||||
redraw_request();
|
|
||||||
RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color RenderingServerDefault::get_default_clear_color() {
|
Color RenderingServerDefault::get_default_clear_color() {
|
||||||
return RSG::texture_storage->get_default_clear_color();
|
return RSG::texture_storage->get_default_clear_color();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::set_default_clear_color(const Color &p_color) {
|
void RenderingServerDefault::set_default_clear_color(const Color &p_color) {
|
||||||
RSG::viewport->set_default_clear_color(p_color);
|
RSG::texture_storage->set_default_clear_color(p_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
@ -327,29 +359,23 @@ Size2i RenderingServerDefault::get_maximum_viewport_size() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingServerDefault::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
|
||||||
|
server_thread = Thread::get_caller_id();
|
||||||
|
server_task_id = p_pump_task_id;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::_thread_exit() {
|
void RenderingServerDefault::_thread_exit() {
|
||||||
exit = true;
|
exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) {
|
|
||||||
_draw(p_swap_buffers, frame_step);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderingServerDefault::_thread_loop() {
|
void RenderingServerDefault::_thread_loop() {
|
||||||
server_thread = Thread::get_caller_id();
|
|
||||||
|
|
||||||
DisplayServer::get_singleton()->gl_window_make_current(DisplayServer::MAIN_WINDOW_ID); // Move GL to this thread.
|
DisplayServer::get_singleton()->gl_window_make_current(DisplayServer::MAIN_WINDOW_ID); // Move GL to this thread.
|
||||||
_init();
|
|
||||||
|
|
||||||
command_queue.set_pump_task_id(server_task_id);
|
|
||||||
while (!exit) {
|
while (!exit) {
|
||||||
WorkerThreadPool::get_singleton()->yield();
|
WorkerThreadPool::get_singleton()->yield();
|
||||||
command_queue.flush_all();
|
command_queue.flush_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
command_queue.flush_all();
|
|
||||||
|
|
||||||
_finish();
|
|
||||||
DisplayServer::get_singleton()->release_rendering_thread();
|
DisplayServer::get_singleton()->release_rendering_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +392,9 @@ void RenderingServerDefault::set_physics_interpolation_enabled(bool p_enabled) {
|
|||||||
/* EVENT QUEUING */
|
/* EVENT QUEUING */
|
||||||
|
|
||||||
void RenderingServerDefault::sync() {
|
void RenderingServerDefault::sync() {
|
||||||
if (!create_thread) {
|
if (create_thread) {
|
||||||
|
command_queue.sync();
|
||||||
|
} else {
|
||||||
command_queue.flush_all(); // Flush all pending from other threads.
|
command_queue.flush_all(); // Flush all pending from other threads.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,8 +403,9 @@ 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().");
|
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.
|
// 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"));
|
RS::get_singleton()->emit_signal(SNAME("frame_pre_draw"));
|
||||||
|
changes = 0;
|
||||||
if (create_thread) {
|
if (create_thread) {
|
||||||
command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step);
|
command_queue.push(this, &RenderingServerDefault::_draw, p_swap_buffers, frame_step);
|
||||||
} else {
|
} else {
|
||||||
_draw(p_swap_buffers, frame_step);
|
_draw(p_swap_buffers, frame_step);
|
||||||
}
|
}
|
||||||
@ -390,36 +419,7 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) {
|
|||||||
RenderingServer::init();
|
RenderingServer::init();
|
||||||
|
|
||||||
create_thread = p_create_thread;
|
create_thread = p_create_thread;
|
||||||
if (!create_thread) {
|
|
||||||
server_thread = Thread::MAIN_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
RSG::threaded = create_thread;
|
|
||||||
|
|
||||||
RSG::canvas = memnew(RendererCanvasCull);
|
|
||||||
RSG::viewport = memnew(RendererViewport);
|
|
||||||
RendererSceneCull *sr = memnew(RendererSceneCull);
|
|
||||||
RSG::camera_attributes = memnew(RendererCameraAttributes);
|
|
||||||
RSG::scene = sr;
|
|
||||||
RSG::rasterizer = RendererCompositor::create();
|
|
||||||
RSG::utilities = RSG::rasterizer->get_utilities();
|
|
||||||
RSG::light_storage = RSG::rasterizer->get_light_storage();
|
|
||||||
RSG::material_storage = RSG::rasterizer->get_material_storage();
|
|
||||||
RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
|
|
||||||
RSG::particles_storage = RSG::rasterizer->get_particles_storage();
|
|
||||||
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
|
|
||||||
RSG::gi = RSG::rasterizer->get_gi();
|
|
||||||
RSG::fog = RSG::rasterizer->get_fog();
|
|
||||||
RSG::canvas_render = RSG::rasterizer->get_canvas();
|
|
||||||
sr->set_scene_render(RSG::rasterizer->get_scene());
|
|
||||||
|
|
||||||
frame_profile_frame = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingServerDefault::~RenderingServerDefault() {
|
RenderingServerDefault::~RenderingServerDefault() {
|
||||||
memdelete(RSG::canvas);
|
|
||||||
memdelete(RSG::viewport);
|
|
||||||
memdelete(RSG::rasterizer);
|
|
||||||
memdelete(RSG::scene);
|
|
||||||
memdelete(RSG::camera_attributes);
|
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class RenderingServerDefault : public RenderingServer {
|
|||||||
|
|
||||||
static void _changes_changed() {}
|
static void _changes_changed() {}
|
||||||
|
|
||||||
uint64_t frame_profile_frame;
|
uint64_t frame_profile_frame = 0;
|
||||||
Vector<FrameProfileArea> frame_profile;
|
Vector<FrameProfileArea> frame_profile;
|
||||||
|
|
||||||
double frame_setup_time = 0;
|
double frame_setup_time = 0;
|
||||||
@ -76,18 +76,17 @@ class RenderingServerDefault : public RenderingServer {
|
|||||||
|
|
||||||
mutable CommandQueueMT command_queue;
|
mutable CommandQueueMT command_queue;
|
||||||
|
|
||||||
void _thread_loop();
|
Thread::ID server_thread = Thread::MAIN_ID;
|
||||||
|
|
||||||
Thread::ID server_thread = Thread::UNASSIGNED_ID;
|
|
||||||
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
WorkerThreadPool::TaskID server_task_id = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
bool create_thread = false;
|
bool create_thread = false;
|
||||||
|
|
||||||
void _thread_draw(bool p_swap_buffers, double frame_step);
|
void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id);
|
||||||
|
|
||||||
void _thread_exit();
|
void _thread_exit();
|
||||||
|
void _thread_loop();
|
||||||
|
|
||||||
void _draw(bool p_swap_buffers, double frame_step);
|
void _draw(bool p_swap_buffers, double frame_step);
|
||||||
|
void _run_post_draw_steps();
|
||||||
void _init();
|
void _init();
|
||||||
void _finish();
|
void _finish();
|
||||||
|
|
||||||
@ -998,9 +997,22 @@ public:
|
|||||||
FUNC1(global_shader_parameters_load_settings, bool)
|
FUNC1(global_shader_parameters_load_settings, bool)
|
||||||
FUNC0(global_shader_parameters_clear)
|
FUNC0(global_shader_parameters_clear)
|
||||||
|
|
||||||
|
/* COMPOSITOR */
|
||||||
|
|
||||||
#undef server_name
|
#undef server_name
|
||||||
#undef ServerName
|
#undef ServerName
|
||||||
|
#define ServerName RendererCompositor
|
||||||
|
#define server_name RSG::rasterizer
|
||||||
|
|
||||||
|
FUNC4S(set_boot_image, const Ref<Image> &, const Color &, bool, bool)
|
||||||
|
|
||||||
/* STATUS INFORMATION */
|
/* STATUS INFORMATION */
|
||||||
|
|
||||||
|
#undef server_name
|
||||||
|
#undef ServerName
|
||||||
|
|
||||||
|
/* UTILITIES */
|
||||||
|
|
||||||
#define ServerName RendererUtilities
|
#define ServerName RendererUtilities
|
||||||
#define server_name RSG::utilities
|
#define server_name RSG::utilities
|
||||||
FUNC0RC(String, get_video_adapter_name)
|
FUNC0RC(String, get_video_adapter_name)
|
||||||
@ -1056,7 +1068,7 @@ public:
|
|||||||
virtual void call_on_render_thread(const Callable &p_callable) override {
|
virtual void call_on_render_thread(const Callable &p_callable) override {
|
||||||
if (Thread::get_caller_id() == server_thread) {
|
if (Thread::get_caller_id() == server_thread) {
|
||||||
command_queue.flush_if_pending();
|
command_queue.flush_if_pending();
|
||||||
_call_on_render_thread(p_callable);
|
p_callable.call();
|
||||||
} else {
|
} else {
|
||||||
command_queue.push(this, &RenderingServerDefault::_call_on_render_thread, p_callable);
|
command_queue.push(this, &RenderingServerDefault::_call_on_render_thread, p_callable);
|
||||||
}
|
}
|
||||||
@ -1066,7 +1078,6 @@ public:
|
|||||||
|
|
||||||
virtual double get_frame_setup_time_cpu() const override;
|
virtual double get_frame_setup_time_cpu() const override;
|
||||||
|
|
||||||
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override;
|
|
||||||
virtual Color get_default_clear_color() override;
|
virtual Color get_default_clear_color() override;
|
||||||
virtual void set_default_clear_color(const Color &p_color) override;
|
virtual void set_default_clear_color(const Color &p_color) override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user