From 898d1a2d5fdee2fa2d917cfd7b3275fdf3cd358f Mon Sep 17 00:00:00 2001 From: bitsawer Date: Wed, 27 Sep 2023 11:46:06 +0300 Subject: [PATCH] Fix errors when freeing GPUParticles --- drivers/gles3/storage/particles_storage.cpp | 19 ++++++++++-------- drivers/gles3/storage/particles_storage.h | 7 ++++--- .../storage_rd/particles_storage.cpp | 20 ++++++++++--------- .../storage_rd/particles_storage.h | 7 ++++--- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index 0a6f02511cd..e3e0a8529f3 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -94,13 +94,15 @@ RID ParticlesStorage::particles_allocate() { } void ParticlesStorage::particles_initialize(RID p_rid) { - particles_owner.initialize_rid(p_rid, Particles()); + particles_owner.initialize_rid(p_rid); } void ParticlesStorage::particles_free(RID p_rid) { - update_particles(); Particles *particles = particles_owner.get_or_null(p_rid); + particles->dependency.deleted_notify(p_rid); + particles->update_list.remove_from_list(); + _particles_free_data(particles); particles_owner.free(p_rid); } @@ -355,8 +357,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) { if (!particles->dirty) { particles->dirty = true; - particles->update_list = particle_update_list; - particle_update_list = particles; + + if (!particles->update_list.in_list()) { + particle_update_list.add(&particles->update_list); + } } } @@ -978,13 +982,12 @@ void ParticlesStorage::update_particles() { glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); - while (particle_update_list) { + while (particle_update_list.first()) { // Use transform feedback to process particles. - Particles *particles = particle_update_list; + Particles *particles = particle_update_list.first()->self(); - particle_update_list = particles->update_list; - particles->update_list = nullptr; + particles->update_list.remove_from_list(); particles->dirty = false; _particles_update_buffers(particles); diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h index 5146dc53295..ac61aa9bb62 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -209,7 +209,7 @@ private: uint32_t userdata_count = 0; bool dirty = false; - Particles *update_list = nullptr; + SelfList update_list; double phase = 0.0; double prev_phase = 0.0; @@ -237,7 +237,8 @@ private: double trail_length = 1.0; bool trails_enabled = false; - Particles() { + Particles() : + update_list(this) { } }; @@ -259,7 +260,7 @@ private: RID copy_shader_version; } particles_shader; - Particles *particle_update_list = nullptr; + SelfList::List particle_update_list; mutable RID_Owner particles_owner; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index bf5a597bb93..a97e28f9ac2 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -221,13 +221,15 @@ RID ParticlesStorage::particles_allocate() { } void ParticlesStorage::particles_initialize(RID p_rid) { - particles_owner.initialize_rid(p_rid, Particles()); + particles_owner.initialize_rid(p_rid); } void ParticlesStorage::particles_free(RID p_rid) { - update_particles(); Particles *particles = particles_owner.get_or_null(p_rid); + particles->dependency.deleted_notify(p_rid); + particles->update_list.remove_from_list(); + _particles_free_data(particles); particles_owner.free(p_rid); } @@ -577,8 +579,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) { if (!particles->dirty) { particles->dirty = true; - particles->update_list = particle_update_list; - particle_update_list = particles; + + if (!particles->update_list.in_list()) { + particle_update_list.add(&particles->update_list); + } } } @@ -1345,14 +1349,12 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) { void ParticlesStorage::update_particles() { uint32_t frame = RSG::rasterizer->get_frame_number(); bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0; - while (particle_update_list) { + while (particle_update_list.first()) { //use transform feedback to process particles - Particles *particles = particle_update_list; + Particles *particles = particle_update_list.first()->self(); - //take and remove - particle_update_list = particles->update_list; - particles->update_list = nullptr; + particles->update_list.remove_from_list(); particles->dirty = false; _particles_update_buffers(particles); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index b93932f482c..73f45d8db07 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -206,7 +206,7 @@ private: RID particles_sort_uniform_set; bool dirty = false; - Particles *update_list = nullptr; + SelfList update_list; RID sub_emitter; @@ -250,7 +250,8 @@ private: LocalVector frame_history; LocalVector trail_params; - Particles() { + Particles() : + update_list(this) { } }; @@ -322,7 +323,7 @@ private: } particles_shader; - Particles *particle_update_list = nullptr; + SelfList::List particle_update_list; mutable RID_Owner particles_owner;