2
0
Эх сурвалжийг харах

Merge pull request #26784 from humblers/fix-cpuparticles2d

Prevent invisible/inactive cpupparticles2d to redraw
Rémi Verschelde 6 жил өмнө
parent
commit
362b42787b

+ 33 - 48
scene/2d/cpu_particles_2d.cpp

@@ -37,20 +37,7 @@
 void CPUParticles2D::set_emitting(bool p_emitting) {
 
 	emitting = p_emitting;
-	if (!is_processing_internal()) {
-		set_process_internal(true);
-		if (is_inside_tree()) {
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
-
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
-	}
+	set_process_internal(true);
 }
 
 void CPUParticles2D::set_amount(int p_amount) {
@@ -365,7 +352,8 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
 		} break;
 		case PARAM_ANIM_OFFSET: {
 		} break;
-		default: {}
+		default: {
+		}
 	}
 }
 Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const {
@@ -941,6 +929,26 @@ void CPUParticles2D::_update_particle_data_buffer() {
 #endif
 }
 
+void CPUParticles2D::_set_redraw(bool p_redraw) {
+	if (redraw == p_redraw)
+		return;
+	redraw = p_redraw;
+#ifndef NO_THREADS
+	update_mutex->lock();
+#endif
+	if (redraw) {
+		VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
+		VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
+	} else {
+		VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
+		VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
+	}
+#ifndef NO_THREADS
+	update_mutex->unlock();
+#endif
+	update(); // redraw to update render list
+}
+
 void CPUParticles2D::_update_render_thread() {
 
 #ifndef NO_THREADS
@@ -957,38 +965,19 @@ void CPUParticles2D::_update_render_thread() {
 void CPUParticles2D::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
-		if (is_processing_internal()) {
-
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
-
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
+		_set_redraw(true);
 	}
 
 	if (p_what == NOTIFICATION_EXIT_TREE) {
-		if (is_processing_internal()) {
-
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
+		_set_redraw(false);
 	}
 
 	if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
 	}
 
 	if (p_what == NOTIFICATION_DRAW) {
+		if (!redraw)
+			return; // dont add to render list
 
 		RID texrid;
 		if (texture.is_valid()) {
@@ -1005,26 +994,21 @@ void CPUParticles2D::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
 
-		if (particles.size() == 0 || !is_visible_in_tree())
+		if (particles.size() == 0 || !is_visible_in_tree()) {
+			_set_redraw(false);
 			return;
+		}
 
 		float delta = get_process_delta_time();
 		if (emitting) {
-
+			_set_redraw(true);
 			inactive_time = 0;
 		} else {
 			inactive_time += delta;
 			if (inactive_time > lifetime * 1.2) {
 				set_process_internal(false);
-#ifndef NO_THREADS
-				update_mutex->lock();
-#endif
-				VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
-				VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
+				_set_redraw(false);
 
-#ifndef NO_THREADS
-				update_mutex->unlock();
-#endif
 				//reset variables
 				time = 0;
 				inactive_time = 0;
@@ -1354,6 +1338,7 @@ CPUParticles2D::CPUParticles2D() {
 	inactive_time = 0;
 	frame_remainder = 0;
 	cycle = 0;
+	redraw = false;
 
 	mesh = VisualServer::get_singleton()->mesh_create();
 	multimesh = VisualServer::get_singleton()->multimesh_create();

+ 3 - 0
scene/2d/cpu_particles_2d.h

@@ -103,6 +103,7 @@ private:
 	float inactive_time;
 	float frame_remainder;
 	int cycle;
+	bool redraw;
 
 	RID mesh;
 	RID multimesh;
@@ -179,6 +180,8 @@ private:
 
 	void _update_mesh_texture();
 
+	void _set_redraw(bool p_redraw);
+
 protected:
 	static void _bind_methods();
 	void _notification(int p_what);

+ 30 - 46
scene/3d/cpu_particles.cpp

@@ -47,20 +47,7 @@ PoolVector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const {
 void CPUParticles::set_emitting(bool p_emitting) {
 
 	emitting = p_emitting;
-	if (!is_processing_internal()) {
-		set_process_internal(true);
-		if (is_inside_tree()) {
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
-
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
-	}
+	set_process_internal(true);
 }
 
 void CPUParticles::set_amount(int p_amount) {
@@ -343,7 +330,8 @@ void CPUParticles::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve)
 		} break;
 		case PARAM_ANIM_OFFSET: {
 		} break;
-		default: {}
+		default: {
+		}
 	}
 }
 Ref<Curve> CPUParticles::get_param_curve(Parameter p_param) const {
@@ -1004,6 +992,25 @@ void CPUParticles::_update_particle_data_buffer() {
 #endif
 }
 
+void CPUParticles::_set_redraw(bool p_redraw) {
+	if (redraw == p_redraw)
+		return;
+	redraw = p_redraw;
+#ifndef NO_THREADS
+	update_mutex->lock();
+#endif
+	if (redraw) {
+		VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
+		VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
+	} else {
+		VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
+		VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
+	}
+#ifndef NO_THREADS
+	update_mutex->unlock();
+#endif
+}
+
 void CPUParticles::_update_render_thread() {
 
 #ifndef NO_THREADS
@@ -1022,31 +1029,11 @@ void CPUParticles::_update_render_thread() {
 void CPUParticles::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
-		if (is_processing_internal()) {
-
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
+		_set_redraw(true);
 	}
 
 	if (p_what == NOTIFICATION_EXIT_TREE) {
-		if (is_processing_internal()) {
-
-#ifndef NO_THREADS
-			update_mutex->lock();
-#endif
-			VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
-			VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
-#ifndef NO_THREADS
-			update_mutex->unlock();
-#endif
-		}
+		_set_redraw(false);
 	}
 
 	if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
@@ -1054,26 +1041,22 @@ void CPUParticles::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
 
-		if (particles.size() == 0 || !is_visible_in_tree())
+		if (particles.size() == 0 || !is_visible_in_tree()) {
+			_set_redraw(false);
 			return;
+		}
 
 		float delta = get_process_delta_time();
 		if (emitting) {
 
+			_set_redraw(true);
 			inactive_time = 0;
 		} else {
 			inactive_time += delta;
 			if (inactive_time > lifetime * 1.2) {
 				set_process_internal(false);
-#ifndef NO_THREADS
-				update_mutex->lock();
-#endif
-				VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
-				VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
+				_set_redraw(false);
 
-#ifndef NO_THREADS
-				update_mutex->unlock();
-#endif
 				//reset variables
 				time = 0;
 				inactive_time = 0;
@@ -1406,6 +1389,7 @@ CPUParticles::CPUParticles() {
 	inactive_time = 0;
 	frame_remainder = 0;
 	cycle = 0;
+	redraw = false;
 
 	multimesh = VisualServer::get_singleton()->multimesh_create();
 	set_base(multimesh);

+ 3 - 0
scene/3d/cpu_particles.h

@@ -104,6 +104,7 @@ private:
 	float inactive_time;
 	float frame_remainder;
 	int cycle;
+	bool redraw;
 
 	RID multimesh;
 
@@ -178,6 +179,8 @@ private:
 
 	void _update_render_thread();
 
+	void _set_redraw(bool p_redraw);
+
 protected:
 	static void _bind_methods();
 	void _notification(int p_what);