Merge pull request #100257 from darksylinc/matias-minimize-leak

Keep processing Graphics if there are pending operations
This commit is contained in:
Thaddeus Crews 2024-12-11 17:35:35 -06:00
commit 23afda44e4
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
9 changed files with 40 additions and 20 deletions

View File

@ -4441,15 +4441,20 @@ bool Main::iteration() {
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
if ((DisplayServer::get_singleton()->can_any_window_draw() || DisplayServer::get_singleton()->has_additional_outputs()) &&
RenderingServer::get_singleton()->is_render_loop_enabled()) {
const bool has_pending_resources_for_processing = RD::get_singleton() && RD::get_singleton()->has_pending_resources_for_processing();
bool wants_present = (DisplayServer::get_singleton()->can_any_window_draw() ||
DisplayServer::get_singleton()->has_additional_outputs()) &&
RenderingServer::get_singleton()->is_render_loop_enabled();
if (wants_present || has_pending_resources_for_processing) {
wants_present |= force_redraw_requested;
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
RenderingServer::get_singleton()->draw(wants_present, scaled_step); // flush visual commands
Engine::get_singleton()->increment_frames_drawn();
}
} else {
RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands
RenderingServer::get_singleton()->draw(wants_present, scaled_step); // flush visual commands
Engine::get_singleton()->increment_frames_drawn();
force_redraw_requested = false;
}

View File

@ -90,8 +90,8 @@ public:
void gl_end_frame(bool p_swap_buffers) override {}
void end_frame(bool p_swap_buffers) override {
if (p_swap_buffers) {
void end_frame(bool p_present) override {
if (p_present) {
DisplayServer::get_singleton()->swap_buffers();
}
}

View File

@ -99,7 +99,7 @@ public:
virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0;
virtual void gl_end_frame(bool p_swap_buffers) = 0;
virtual void end_frame(bool p_swap_buffers) = 0;
virtual void end_frame(bool p_present) = 0;
virtual void finalize() = 0;
virtual uint64_t get_frame_number() const = 0;
virtual double get_frame_delta_time() const = 0;

View File

@ -112,10 +112,8 @@ void RendererCompositorRD::begin_frame(double frame_step) {
scene->set_time(time, frame_step);
}
void RendererCompositorRD::end_frame(bool p_swap_buffers) {
if (p_swap_buffers) {
RD::get_singleton()->swap_buffers();
}
void RendererCompositorRD::end_frame(bool p_present) {
RD::get_singleton()->swap_buffers(p_present);
}
void RendererCompositorRD::initialize() {
@ -267,7 +265,7 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
RD::get_singleton()->draw_list_end();
RD::get_singleton()->swap_buffers();
RD::get_singleton()->swap_buffers(true);
texture_storage->texture_free(texture);
RD::get_singleton()->free(sampler);

View File

@ -128,7 +128,7 @@ public:
void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount);
void gl_end_frame(bool p_swap_buffers) {}
void end_frame(bool p_swap_buffers);
void end_frame(bool p_present);
void finalize();
_ALWAYS_INLINE_ uint64_t get_frame_number() const { return frame; }

View File

@ -6029,6 +6029,8 @@ void RenderingDevice::_free_internal(RID p_id) {
ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()));
#endif
}
frames_pending_resources_for_processing = uint32_t(frames.size());
}
// The full list of resources that can be named is in the VkObjectType enum.
@ -6131,11 +6133,11 @@ String RenderingDevice::get_device_pipeline_cache_uuid() const {
return driver->get_pipeline_cache_uuid();
}
void RenderingDevice::swap_buffers() {
void RenderingDevice::swap_buffers(bool p_present) {
ERR_RENDER_THREAD_GUARD();
_end_frame();
_execute_frame(true);
_execute_frame(p_present);
// Advance to the next frame and begin recording again.
frame = (frame + 1) % frames.size();
@ -6238,6 +6240,10 @@ void RenderingDevice::_free_pending_resources(int p_frame) {
frames[p_frame].buffers_to_dispose_of.pop_front();
}
if (frames_pending_resources_for_processing > 0u) {
--frames_pending_resources_for_processing;
}
}
uint32_t RenderingDevice::get_frame_delay() const {

View File

@ -1469,6 +1469,17 @@ private:
TightLocalVector<Frame> frames;
uint64_t frames_drawn = 0;
// Whenever logic/physics request a graphics operation (not just deleting a resource) that requires
// us to flush all graphics commands, we must set frames_pending_resources_for_processing = frames.size().
// This is important for when the user requested for the logic loop to still be updated while
// graphics should not (e.g. headless Multiplayer servers, minimized windows that need to still
// process something on the background).
uint32_t frames_pending_resources_for_processing = 0u;
public:
bool has_pending_resources_for_processing() const { return frames_pending_resources_for_processing != 0u; }
private:
void _free_pending_resources(int p_frame);
uint64_t texture_memory = 0;
@ -1520,7 +1531,7 @@ public:
uint64_t limit_get(Limit p_limit) const;
void swap_buffers();
void swap_buffers(bool p_present);
uint32_t get_frame_delay() const;

View File

@ -406,15 +406,15 @@ void RenderingServerDefault::sync() {
}
}
void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
void RenderingServerDefault::draw(bool p_present, 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"));
changes = 0;
if (create_thread) {
command_queue.push(this, &RenderingServerDefault::_draw, p_swap_buffers, frame_step);
command_queue.push(this, &RenderingServerDefault::_draw, p_present, frame_step);
} else {
_draw(p_swap_buffers, frame_step);
_draw(p_present, frame_step);
}
}

View File

@ -1124,7 +1124,7 @@ public:
virtual void request_frame_drawn_callback(const Callable &p_callable) override;
virtual void draw(bool p_swap_buffers, double frame_step) override;
virtual void draw(bool p_present, double frame_step) override;
virtual void sync() override;
virtual bool has_changed() const override;
virtual void init() override;