Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid crashes when engine leaks canvas items and friends #85520

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions servers/rendering/renderer_canvas_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,30 @@ bool RendererCanvasCull::free(RID p_rid) {
return true;
}

template <class T>
void RendererCanvasCull::_free_rids(T &p_owner, const char *p_type) {
List<RID> 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do this consistantly on the 3D side but if you search you'll see a few places I added it, but seeing that it can be very difficult to find the cause of the leak simply by a count, I check if a description was recorded for the RID (this is a debug/tools build only feature), than we print the description of the resource being leaked.

This also means off course that we need to get more consistent in recording descriptions when the resource is allocated. Something we can improve on over time.

}
}
}

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 *));
Expand Down
6 changes: 6 additions & 0 deletions servers/rendering/renderer_canvas_cull.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ class RendererCanvasCull {
RID_Owner<Item, true> canvas_item_owner;
RID_Owner<RendererCanvasRender::Light, true> canvas_light_owner;

template <class T>
void _free_rids(T &p_owner, const char *p_type);

bool disable_scale;
bool sdf_used = false;
bool snapping_2d_transforms_to_pixel = false;
Expand Down Expand Up @@ -329,6 +332,9 @@ class RendererCanvasCull {
Rect2 _debug_canvas_item_get_rect(RID p_item);

bool free(RID p_rid);

void finalize();

RendererCanvasCull();
~RendererCanvasCull();
};
Expand Down
2 changes: 2 additions & 0 deletions servers/rendering/renderer_canvas_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions servers/rendering/renderer_compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -57,5 +55,3 @@ RendererCompositor::RendererCompositor() {
xr_enabled = XRServer::get_xr_mode() == XRServer::XRMODE_ON;
}
}

RendererCanvasRender *RendererCanvasRender::singleton = nullptr;
1 change: 1 addition & 0 deletions servers/rendering/rendering_server_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ void RenderingServerDefault::_finish() {
free(test_cube);
}

RSG::canvas->finalize();
RSG::rasterizer->finalize();
}

Expand Down
Loading