From 6f4c0b95fc2c651058b284350eadfa394f1b4d13 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Tue, 9 Nov 2021 12:00:07 +0000 Subject: [PATCH] Fix incorrect RID cleanup in Rasterizers Proper cleanup for GLES3 RIDs (preventing leak reports), and added missing destructor for RasterizerSceneGLES2. --- drivers/gles2/rasterizer_gles2.cpp | 3 +++ drivers/gles2/rasterizer_scene_gles2.cpp | 25 +++++++++++++++++ drivers/gles2/rasterizer_scene_gles2.h | 1 + drivers/gles3/rasterizer_gles3.cpp | 3 +++ drivers/gles3/rasterizer_scene_gles3.cpp | 34 +++++++++++++++--------- 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 35c342249fbc..974fcfca0e00 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -537,5 +537,8 @@ RasterizerGLES2::RasterizerGLES2() { RasterizerGLES2::~RasterizerGLES2() { memdelete(scene); memdelete(canvas); + + // Storage needs to be deleted after canvas as canvas destructor frees RIDs + // stored in storage RID owners. memdelete(storage); } diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 4cba74a9e752..b3cb17914cbb 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -4077,3 +4077,28 @@ void RasterizerSceneGLES2::finalize() { RasterizerSceneGLES2::RasterizerSceneGLES2() { _light_counter = 0; } + +RasterizerSceneGLES2::~RasterizerSceneGLES2() { + storage->free(default_material); + default_material = RID(); + storage->free(default_material_twosided); + default_material_twosided = RID(); + storage->free(default_shader); + default_shader = RID(); + storage->free(default_shader_twosided); + default_shader_twosided = RID(); + + storage->free(default_worldcoord_material); + default_worldcoord_material = RID(); + storage->free(default_worldcoord_material_twosided); + default_worldcoord_material_twosided = RID(); + storage->free(default_worldcoord_shader); + default_worldcoord_shader = RID(); + storage->free(default_worldcoord_shader_twosided); + default_worldcoord_shader_twosided = RID(); + + storage->free(default_overdraw_material); + default_overdraw_material = RID(); + storage->free(default_overdraw_shader); + default_overdraw_shader = RID(); +} diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index 4df57d72708f..b9fbde0ca5a7 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -773,6 +773,7 @@ class RasterizerSceneGLES2 : public RasterizerScene { void initialize(); void finalize(); RasterizerSceneGLES2(); + ~RasterizerSceneGLES2(); }; #endif // RASTERIZERSCENEGLES2_H diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 93818015efa1..a602e23363d4 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -499,5 +499,8 @@ RasterizerGLES3::RasterizerGLES3() { RasterizerGLES3::~RasterizerGLES3() { memdelete(scene); memdelete(canvas); + + // storage must be deleted last, + // because it contains RID_owners that are used by scene and canvas destructors memdelete(storage); } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index e0c811e009a5..ca74634d9b1a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -5282,18 +5282,28 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { } RasterizerSceneGLES3::~RasterizerSceneGLES3() { - memdelete(storage->material_owner.getptr(default_material)); - memdelete(storage->material_owner.getptr(default_material_twosided)); - memdelete(storage->shader_owner.getptr(default_shader)); - memdelete(storage->shader_owner.getptr(default_shader_twosided)); - - memdelete(storage->material_owner.getptr(default_worldcoord_material)); - memdelete(storage->material_owner.getptr(default_worldcoord_material_twosided)); - memdelete(storage->shader_owner.getptr(default_worldcoord_shader)); - memdelete(storage->shader_owner.getptr(default_worldcoord_shader_twosided)); - - memdelete(storage->material_owner.getptr(default_overdraw_material)); - memdelete(storage->shader_owner.getptr(default_overdraw_shader)); + storage->free(default_material); + default_material = RID(); + storage->free(default_material_twosided); + default_material_twosided = RID(); + storage->free(default_shader); + default_shader = RID(); + storage->free(default_shader_twosided); + default_shader_twosided = RID(); + + storage->free(default_worldcoord_material); + default_worldcoord_material = RID(); + storage->free(default_worldcoord_material_twosided); + default_worldcoord_material_twosided = RID(); + storage->free(default_worldcoord_shader); + default_worldcoord_shader = RID(); + storage->free(default_worldcoord_shader_twosided); + default_worldcoord_shader_twosided = RID(); + + storage->free(default_overdraw_material); + default_overdraw_material = RID(); + storage->free(default_overdraw_shader); + default_overdraw_shader = RID(); memfree(state.spot_array_tmp); memfree(state.omni_array_tmp);