From 34ecfff6722be4819707b128ccae561eacf101fc Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Wed, 20 Dec 2023 13:19:46 +0100 Subject: [PATCH] Avoid crashes when engine leaks canvas items and friends --- servers/rendering/renderer_canvas_cull.cpp | 24 +++++++++++++++++++ servers/rendering/renderer_canvas_cull.h | 6 +++++ servers/rendering/renderer_canvas_render.cpp | 2 ++ servers/rendering/renderer_compositor.cpp | 4 ---- .../rendering/rendering_server_default.cpp | 1 + 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index cc51d440428..fdae5f5701a 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -2165,6 +2165,30 @@ bool RendererCanvasCull::free(RID p_rid) { return true; } +template +void RendererCanvasCull::_free_rids(T &p_owner, const char *p_type) { + List owned; + p_owner.get_owned_list(&owned); + if (owned.size()) { + if (owned.size() == 1) { + WARN_PRINT(vformat("1 RID of type \"%s\" was leaked.", p_type)); + } else { + WARN_PRINT(vformat("%d RIDs of type \"%s\" were leaked.", owned.size(), p_type)); + } + for (const RID &E : owned) { + free(E); + } + } +} + +void RendererCanvasCull::finalize() { + _free_rids(canvas_owner, "Canvas"); + _free_rids(canvas_item_owner, "CanvasItem"); + _free_rids(canvas_light_owner, "CanvasLight"); + _free_rids(canvas_light_occluder_owner, "CanvasLightOccluder"); + _free_rids(canvas_light_occluder_polygon_owner, "CanvasLightOccluderPolygon"); +} + RendererCanvasCull::RendererCanvasCull() { z_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *)); z_last_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *)); diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index ba013e667f8..9dfa82a3afd 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -170,6 +170,9 @@ public: RID_Owner canvas_item_owner; RID_Owner canvas_light_owner; + template + void _free_rids(T &p_owner, const char *p_type); + bool disable_scale; bool sdf_used = false; bool snapping_2d_transforms_to_pixel = false; @@ -329,6 +332,9 @@ public: Rect2 _debug_canvas_item_get_rect(RID p_item); bool free(RID p_rid); + + void finalize(); + RendererCanvasCull(); ~RendererCanvasCull(); }; diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp index af0ec621e5e..6eb7bab9c99 100644 --- a/servers/rendering/renderer_canvas_render.cpp +++ b/servers/rendering/renderer_canvas_render.cpp @@ -31,6 +31,8 @@ #include "renderer_canvas_render.h" #include "servers/rendering/rendering_server_globals.h" +RendererCanvasRender *RendererCanvasRender::singleton = nullptr; + const Rect2 &RendererCanvasRender::Item::get_rect() const { if (custom_rect || (!rect_dirty && !update_when_visible && skeleton == RID())) { return rect; diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index a6083fe70df..c36da51e506 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -31,8 +31,6 @@ #include "renderer_compositor.h" #include "core/config/project_settings.h" -#include "core/os/os.h" -#include "core/string/print_string.h" #include "servers/xr_server.h" RendererCompositor *RendererCompositor::singleton = nullptr; @@ -57,5 +55,3 @@ RendererCompositor::RendererCompositor() { xr_enabled = XRServer::get_xr_mode() == XRServer::XRMODE_ON; } } - -RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 77fe91e4c9d..5b526fc6283 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -214,6 +214,7 @@ void RenderingServerDefault::_finish() { free(test_cube); } + RSG::canvas->finalize(); RSG::rasterizer->finalize(); }