diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index 296d721cd12..1caa3bbe353 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); } @@ -362,8 +364,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); + } } } @@ -1003,13 +1007,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 d4c4b497fff..8451986a615 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -212,7 +212,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; @@ -242,7 +242,8 @@ private: double trail_length = 1.0; bool trails_enabled = false; - Particles() { + Particles() : + update_list(this) { } }; @@ -264,7 +265,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 3065da4d05c..3d3cb585ac1 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -224,13 +224,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); } @@ -587,8 +589,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); + } } } @@ -1373,14 +1377,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 435ef14d753..a28d7b41540 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -209,7 +209,7 @@ private: RID particles_sort_uniform_set; bool dirty = false; - Particles *update_list = nullptr; + SelfList update_list; RID sub_emitter; @@ -256,7 +256,8 @@ private: LocalVector frame_history; LocalVector trail_params; - Particles() { + Particles() : + update_list(this) { } }; @@ -328,7 +329,7 @@ private: } particles_shader; - Particles *particle_update_list = nullptr; + SelfList::List particle_update_list; mutable RID_Owner particles_owner;