Browse Source

Merge pull request #82431 from bitsawer/fix_gpuparticles_free

Fix errors when freeing GPUParticles
Rémi Verschelde 1 year ago
parent
commit
b1371806ad

+ 11 - 8
drivers/gles3/storage/particles_storage.cpp

@@ -94,13 +94,15 @@ RID ParticlesStorage::particles_allocate() {
 }
 }
 
 
 void ParticlesStorage::particles_initialize(RID p_rid) {
 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) {
 void ParticlesStorage::particles_free(RID p_rid) {
-	update_particles();
 	Particles *particles = particles_owner.get_or_null(p_rid);
 	Particles *particles = particles_owner.get_or_null(p_rid);
+
 	particles->dependency.deleted_notify(p_rid);
 	particles->dependency.deleted_notify(p_rid);
+	particles->update_list.remove_from_list();
+
 	_particles_free_data(particles);
 	_particles_free_data(particles);
 	particles_owner.free(p_rid);
 	particles_owner.free(p_rid);
 }
 }
@@ -362,8 +364,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) {
 
 
 	if (!particles->dirty) {
 	if (!particles->dirty) {
 		particles->dirty = true;
 		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);
 	glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer);
 	glBindBuffer(GL_UNIFORM_BUFFER, 0);
 	glBindBuffer(GL_UNIFORM_BUFFER, 0);
 
 
-	while (particle_update_list) {
+	while (particle_update_list.first()) {
 		// Use transform feedback to process particles.
 		// 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->dirty = false;
 
 
 		_particles_update_buffers(particles);
 		_particles_update_buffers(particles);

+ 4 - 3
drivers/gles3/storage/particles_storage.h

@@ -212,7 +212,7 @@ private:
 		uint32_t userdata_count = 0;
 		uint32_t userdata_count = 0;
 
 
 		bool dirty = false;
 		bool dirty = false;
-		Particles *update_list = nullptr;
+		SelfList<Particles> update_list;
 
 
 		double phase = 0.0;
 		double phase = 0.0;
 		double prev_phase = 0.0;
 		double prev_phase = 0.0;
@@ -242,7 +242,8 @@ private:
 		double trail_length = 1.0;
 		double trail_length = 1.0;
 		bool trails_enabled = false;
 		bool trails_enabled = false;
 
 
-		Particles() {
+		Particles() :
+				update_list(this) {
 		}
 		}
 	};
 	};
 
 
@@ -264,7 +265,7 @@ private:
 		RID copy_shader_version;
 		RID copy_shader_version;
 	} particles_shader;
 	} particles_shader;
 
 
-	Particles *particle_update_list = nullptr;
+	SelfList<Particles>::List particle_update_list;
 
 
 	mutable RID_Owner<Particles, true> particles_owner;
 	mutable RID_Owner<Particles, true> particles_owner;
 
 

+ 11 - 9
servers/rendering/renderer_rd/storage_rd/particles_storage.cpp

@@ -224,13 +224,15 @@ RID ParticlesStorage::particles_allocate() {
 }
 }
 
 
 void ParticlesStorage::particles_initialize(RID p_rid) {
 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) {
 void ParticlesStorage::particles_free(RID p_rid) {
-	update_particles();
 	Particles *particles = particles_owner.get_or_null(p_rid);
 	Particles *particles = particles_owner.get_or_null(p_rid);
+
 	particles->dependency.deleted_notify(p_rid);
 	particles->dependency.deleted_notify(p_rid);
+	particles->update_list.remove_from_list();
+
 	_particles_free_data(particles);
 	_particles_free_data(particles);
 	particles_owner.free(p_rid);
 	particles_owner.free(p_rid);
 }
 }
@@ -587,8 +589,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) {
 
 
 	if (!particles->dirty) {
 	if (!particles->dirty) {
 		particles->dirty = true;
 		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() {
 void ParticlesStorage::update_particles() {
 	uint32_t frame = RSG::rasterizer->get_frame_number();
 	uint32_t frame = RSG::rasterizer->get_frame_number();
 	bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;
 	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
 		//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->dirty = false;
 
 
 		_particles_update_buffers(particles);
 		_particles_update_buffers(particles);

+ 4 - 3
servers/rendering/renderer_rd/storage_rd/particles_storage.h

@@ -209,7 +209,7 @@ private:
 		RID particles_sort_uniform_set;
 		RID particles_sort_uniform_set;
 
 
 		bool dirty = false;
 		bool dirty = false;
-		Particles *update_list = nullptr;
+		SelfList<Particles> update_list;
 
 
 		RID sub_emitter;
 		RID sub_emitter;
 
 
@@ -256,7 +256,8 @@ private:
 		LocalVector<ParticlesFrameParams> frame_history;
 		LocalVector<ParticlesFrameParams> frame_history;
 		LocalVector<ParticlesFrameParams> trail_params;
 		LocalVector<ParticlesFrameParams> trail_params;
 
 
-		Particles() {
+		Particles() :
+				update_list(this) {
 		}
 		}
 	};
 	};
 
 
@@ -328,7 +329,7 @@ private:
 
 
 	} particles_shader;
 	} particles_shader;
 
 
-	Particles *particle_update_list = nullptr;
+	SelfList<Particles>::List particle_update_list;
 
 
 	mutable RID_Owner<Particles, true> particles_owner;
 	mutable RID_Owner<Particles, true> particles_owner;