1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-31 18:41:20 +00:00

Make physics interpolation compatible with separate-thread rendering

This commit is contained in:
Pedro J. Estébanez
2025-12-15 21:36:52 +01:00
parent 42b054a401
commit 49700eb84b
6 changed files with 43 additions and 2 deletions

View File

@@ -2352,6 +2352,8 @@ bool Main::iteration() {
double step = advance.idle_step;
double scaled_step = step * time_scale;
VisualServer::get_singleton()->sync_and_halt();
Engine::get_singleton()->_frame_step = step;
Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction;
@@ -2386,9 +2388,11 @@ bool Main::iteration() {
// may be the same, and no interpolation takes place.
OS::get_singleton()->get_main_loop()->iteration_prepare();
PhysicsServer::get_singleton()->flush_queries();
Physics2DServer::get_singleton()->sync();
VisualServer::get_singleton()->thaw();
PhysicsServer::get_singleton()->flush_queries();
Physics2DServer::get_singleton()->flush_queries();
if (OS::get_singleton()->get_main_loop()->iteration(frame_slice * time_scale)) {
@@ -2400,6 +2404,8 @@ bool Main::iteration() {
NavigationServer::get_singleton_mut()->process(frame_slice * time_scale);
message_queue->flush();
VisualServer::get_singleton()->sync_and_halt();
PhysicsServer::get_singleton()->step(frame_slice * time_scale);
Physics2DServer::get_singleton()->end_sync();
@@ -2415,6 +2421,8 @@ bool Main::iteration() {
Engine::get_singleton()->_in_physics = false;
}
VisualServer::get_singleton()->thaw();
if (InputDefault::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) {
InputDefault::get_singleton()->flush_buffered_events();
}

View File

@@ -133,9 +133,16 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
}
VS::get_singleton()->emit_signal("frame_post_draw");
}
void VisualServerRaster::sync() {
}
void VisualServerRaster::sync_and_halt() {
}
void VisualServerRaster::thaw() {
}
void VisualServerRaster::set_physics_interpolation_enabled(bool p_enabled) {
VSG::scene->set_physics_interpolation_enabled(p_enabled);
VSG::canvas->set_physics_interpolation_enabled(p_enabled);

View File

@@ -803,6 +803,8 @@ public:
virtual void pre_draw(bool p_will_draw);
virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
virtual void sync_and_halt();
virtual void thaw();
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const;
virtual void init();
virtual void finish();

View File

@@ -43,6 +43,10 @@ void VisualServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) {
void VisualServerWrapMT::thread_flush() {
}
void VisualServerWrapMT::thread_halt() {
thread_halt_semaphore.wait();
}
void VisualServerWrapMT::_thread_callback(void *_instance) {
VisualServerWrapMT *vsmt = reinterpret_cast<VisualServerWrapMT *>(_instance);
@@ -102,6 +106,19 @@ void VisualServerWrapMT::sync() {
}
}
void VisualServerWrapMT::sync_and_halt() {
if (create_thread) {
command_queue.push_and_sync(this, &VisualServerWrapMT::thread_flush);
command_queue.push(this, &VisualServerWrapMT::thread_halt);
}
}
void VisualServerWrapMT::thaw() {
if (create_thread) {
thread_halt_semaphore.post();
}
}
void VisualServerWrapMT::draw(bool p_swap_buffers, double frame_step) {
if (create_thread) {
command_queue.push(this, &VisualServerWrapMT::thread_draw, p_swap_buffers, frame_step);

View File

@@ -54,6 +54,9 @@ class VisualServerWrapMT : public VisualServer {
void thread_draw(bool p_swap_buffers, double frame_step);
void thread_flush();
Semaphore thread_halt_semaphore;
void thread_halt();
void thread_exit();
Mutex alloc_mutex;
@@ -709,6 +712,8 @@ public:
virtual void pre_draw(bool p_will_draw);
virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
virtual void sync_and_halt();
virtual void thaw();
FUNC1RC(bool, has_changed, ChangedPriority)
virtual void set_physics_interpolation_enabled(bool p_enabled);

View File

@@ -1189,6 +1189,8 @@ public:
virtual void draw(bool p_swap_buffers = true, double frame_step = 0.0) = 0;
virtual void sync() = 0;
virtual void sync_and_halt() = 0;
virtual void thaw() = 0;
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const = 0;
virtual void init() = 0;
virtual void finish() = 0;