Skip to content

Commit

Permalink
Merge pull request #100257 from darksylinc/matias-minimize-leak
Browse files Browse the repository at this point in the history
Keep processing Graphics if there are pending operations
  • Loading branch information
Repiteo committed Dec 11, 2024
2 parents db2088b + acf439e commit 23afda4
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 20 deletions.
13 changes: 9 additions & 4 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions servers/rendering/dummy/rasterizer_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ class RasterizerDummy : public RendererCompositor {

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();
}
}
Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/renderer_compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class RendererCompositor {
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;
Expand Down
8 changes: 3 additions & 5 deletions servers/rendering/renderer_rd/renderer_compositor_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/renderer_rd/renderer_compositor_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class RendererCompositorRD : public RendererCompositor {
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; }
Expand Down
10 changes: 8 additions & 2 deletions servers/rendering/rendering_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down
13 changes: 12 additions & 1 deletion servers/rendering/rendering_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,17 @@ class RenderingDevice : public RenderingDeviceCommons {
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;
Expand Down Expand Up @@ -1520,7 +1531,7 @@ class RenderingDevice : public RenderingDeviceCommons {

uint64_t limit_get(Limit p_limit) const;

void swap_buffers();
void swap_buffers(bool p_present);

uint32_t get_frame_delay() const;

Expand Down
6 changes: 3 additions & 3 deletions servers/rendering/rendering_server_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/rendering_server_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ class RenderingServerDefault : public RenderingServer {

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;
Expand Down

0 comments on commit 23afda4

Please sign in to comment.