Merge pull request #82291 from bitsawer/fix_occlusion_culling_leak

Fix RaycastOcclusionCull World3D scenario memory leak
This commit is contained in:
Yuri Sizov 2023-09-28 20:04:25 +02:00
commit 4c95ebddd6
2 changed files with 31 additions and 45 deletions

View file

@ -250,17 +250,15 @@ void RaycastOcclusionCull::free_occluder(RID p_occluder) {
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
void RaycastOcclusionCull::add_scenario(RID p_scenario) { void RaycastOcclusionCull::add_scenario(RID p_scenario) {
if (scenarios.has(p_scenario)) { ERR_FAIL_COND(scenarios.has(p_scenario));
scenarios[p_scenario].removed = false;
} else {
scenarios[p_scenario] = Scenario(); scenarios[p_scenario] = Scenario();
}
} }
void RaycastOcclusionCull::remove_scenario(RID p_scenario) { void RaycastOcclusionCull::remove_scenario(RID p_scenario) {
ERR_FAIL_COND(!scenarios.has(p_scenario)); Scenario *scenario = scenarios.getptr(p_scenario);
Scenario &scenario = scenarios[p_scenario]; ERR_FAIL_NULL(scenario);
scenario.removed = true; scenario->free();
scenarios.erase(p_scenario);
} }
void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) {
@ -390,6 +388,23 @@ void RaycastOcclusionCull::Scenario::_transform_vertices_range(const Vector3 *p_
} }
} }
void RaycastOcclusionCull::Scenario::free() {
if (commit_thread) {
if (commit_thread->is_started()) {
commit_thread->wait_to_finish();
}
memdelete(commit_thread);
commit_thread = nullptr;
}
for (int i = 0; i < 2; i++) {
if (ebr_scene[i]) {
rtcReleaseScene(ebr_scene[i]);
ebr_scene[i] = nullptr;
}
}
}
void RaycastOcclusionCull::Scenario::_commit_scene(void *p_ud) { void RaycastOcclusionCull::Scenario::_commit_scene(void *p_ud) {
Scenario *scenario = (Scenario *)p_ud; Scenario *scenario = (Scenario *)p_ud;
int commit_idx = 1 - (scenario->current_scene_idx); int commit_idx = 1 - (scenario->current_scene_idx);
@ -397,8 +412,8 @@ void RaycastOcclusionCull::Scenario::_commit_scene(void *p_ud) {
scenario->commit_done = true; scenario->commit_done = true;
} }
bool RaycastOcclusionCull::Scenario::update() { void RaycastOcclusionCull::Scenario::update() {
ERR_FAIL_NULL_V(singleton, false); ERR_FAIL_NULL(singleton);
if (commit_thread == nullptr) { if (commit_thread == nullptr) {
commit_thread = memnew(Thread); commit_thread = memnew(Thread);
@ -409,22 +424,12 @@ bool RaycastOcclusionCull::Scenario::update() {
commit_thread->wait_to_finish(); commit_thread->wait_to_finish();
current_scene_idx = 1 - current_scene_idx; current_scene_idx = 1 - current_scene_idx;
} else { } else {
return false; return;
} }
} }
if (removed) {
if (ebr_scene[0]) {
rtcReleaseScene(ebr_scene[0]);
}
if (ebr_scene[1]) {
rtcReleaseScene(ebr_scene[1]);
}
return true;
}
if (!dirty && removed_instances.is_empty() && dirty_instances_array.is_empty()) { if (!dirty && removed_instances.is_empty() && dirty_instances_array.is_empty()) {
return false; return;
} }
for (const RID &scenario : removed_instances) { for (const RID &scenario : removed_instances) {
@ -480,7 +485,6 @@ bool RaycastOcclusionCull::Scenario::update() {
dirty = false; dirty = false;
commit_done = false; commit_done = false;
commit_thread->start(&Scenario::_commit_scene, this); commit_thread->start(&Scenario::_commit_scene, this);
return false;
} }
void RaycastOcclusionCull::Scenario::_raycast(uint32_t p_idx, const RaycastThreadData *p_raycast_data) const { void RaycastOcclusionCull::Scenario::_raycast(uint32_t p_idx, const RaycastThreadData *p_raycast_data) const {
@ -544,13 +548,7 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_
} }
Scenario &scenario = scenarios[buffer.scenario_rid]; Scenario &scenario = scenarios[buffer.scenario_rid];
scenario.update();
bool removed = scenario.update();
if (removed) {
scenarios.erase(buffer.scenario_rid);
return;
}
buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal); buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal);
@ -603,19 +601,7 @@ RaycastOcclusionCull::RaycastOcclusionCull() {
RaycastOcclusionCull::~RaycastOcclusionCull() { RaycastOcclusionCull::~RaycastOcclusionCull() {
for (KeyValue<RID, Scenario> &K : scenarios) { for (KeyValue<RID, Scenario> &K : scenarios) {
Scenario &scenario = K.value; K.value.free();
if (scenario.commit_thread) {
if (scenario.commit_thread->is_started()) {
scenario.commit_thread->wait_to_finish();
}
memdelete(scenario.commit_thread);
}
for (int i = 0; i < 2; i++) {
if (scenario.ebr_scene[i]) {
rtcReleaseScene(scenario.ebr_scene[i]);
}
}
} }
if (ebr_device != nullptr) { if (ebr_device != nullptr) {

View file

@ -132,7 +132,6 @@ private:
Thread *commit_thread = nullptr; Thread *commit_thread = nullptr;
bool commit_done = true; bool commit_done = true;
bool dirty = false; bool dirty = false;
bool removed = false;
RTCScene ebr_scene[2] = { nullptr, nullptr }; RTCScene ebr_scene[2] = { nullptr, nullptr };
int current_scene_idx = 0; int current_scene_idx = 0;
@ -147,7 +146,8 @@ private:
void _transform_vertices_thread(uint32_t p_thread, TransformThreadData *p_data); void _transform_vertices_thread(uint32_t p_thread, TransformThreadData *p_data);
void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to); void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to);
static void _commit_scene(void *p_ud); static void _commit_scene(void *p_ud);
bool update(); void free();
void update();
void _raycast(uint32_t p_thread, const RaycastThreadData *p_raycast_data) const; void _raycast(uint32_t p_thread, const RaycastThreadData *p_raycast_data) const;
void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const; void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const;