Merge pull request #26784 from humblers/fix-cpuparticles2d

Prevent invisible/inactive cpupparticles2d to redraw
This commit is contained in:
Rémi Verschelde 2019-03-09 16:28:34 +01:00 committed by GitHub
commit 362b42787b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 94 deletions

View File

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

View File

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

View File

@ -47,20 +47,7 @@ PoolVector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const {
void CPUParticles::set_emitting(bool p_emitting) { void CPUParticles::set_emitting(bool p_emitting) {
emitting = p_emitting; emitting = p_emitting;
if (!is_processing_internal()) { set_process_internal(true);
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
}
}
} }
void CPUParticles::set_amount(int p_amount) { 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; } break;
case PARAM_ANIM_OFFSET: { case PARAM_ANIM_OFFSET: {
} break; } break;
default: {} default: {
}
} }
} }
Ref<Curve> CPUParticles::get_param_curve(Parameter p_param) const { Ref<Curve> CPUParticles::get_param_curve(Parameter p_param) const {
@ -1004,6 +992,25 @@ void CPUParticles::_update_particle_data_buffer() {
#endif #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() { void CPUParticles::_update_render_thread() {
#ifndef NO_THREADS #ifndef NO_THREADS
@ -1022,31 +1029,11 @@ void CPUParticles::_update_render_thread() {
void CPUParticles::_notification(int p_what) { void CPUParticles::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) { if (p_what == NOTIFICATION_ENTER_TREE) {
if (is_processing_internal()) { _set_redraw(true);
#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
}
} }
if (p_what == NOTIFICATION_EXIT_TREE) { if (p_what == NOTIFICATION_EXIT_TREE) {
if (is_processing_internal()) { _set_redraw(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);
#ifndef NO_THREADS
update_mutex->unlock();
#endif
}
} }
if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { 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 (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; return;
}
float delta = get_process_delta_time(); float delta = get_process_delta_time();
if (emitting) { if (emitting) {
_set_redraw(true);
inactive_time = 0; inactive_time = 0;
} else { } else {
inactive_time += delta; inactive_time += delta;
if (inactive_time > lifetime * 1.2) { if (inactive_time > lifetime * 1.2) {
set_process_internal(false); set_process_internal(false);
#ifndef NO_THREADS _set_redraw(false);
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
//reset variables //reset variables
time = 0; time = 0;
inactive_time = 0; inactive_time = 0;
@ -1406,6 +1389,7 @@ CPUParticles::CPUParticles() {
inactive_time = 0; inactive_time = 0;
frame_remainder = 0; frame_remainder = 0;
cycle = 0; cycle = 0;
redraw = false;
multimesh = VisualServer::get_singleton()->multimesh_create(); multimesh = VisualServer::get_singleton()->multimesh_create();
set_base(multimesh); set_base(multimesh);

View File

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