diff options
author | Tom Coxon <tom.c.coxon@gmail.com> | 2021-09-07 16:39:37 +0100 |
---|---|---|
committer | Tom Coxon <tom.c.coxon@gmail.com> | 2021-09-21 11:51:39 +0100 |
commit | dbe757102c6503eb564c9edc699c89afe63b91cd (patch) | |
tree | 6d65b969a9f7c2e6b67f73bbc3874622be9f065e | |
parent | 93aa158b5e1b3b11c3482834504e791c3898baf0 (diff) |
Prevent shaders from generating code before the constructor finishes.
Fixes #43733: "creating SpatialMaterial in a separate thread creates invalid
shaders (temporarily)."
The bug occurred because various setters called in materials' constructors add
materials to queues that are processed on the main thread. This means that
when the materials are created in another thread, they can be processed on the
main thread before the constructor has finished.
The fix adds a flag to affected materials that prevents them from being added
to the queue until their constructors have finished initialising all the
members.
-rw-r--r-- | scene/resources/canvas_item_material.cpp | 3 | ||||
-rw-r--r-- | scene/resources/canvas_item_material.h | 1 | ||||
-rw-r--r-- | scene/resources/material.cpp | 3 | ||||
-rw-r--r-- | scene/resources/material.h | 1 | ||||
-rw-r--r-- | scene/resources/particles_material.cpp | 3 | ||||
-rw-r--r-- | scene/resources/particles_material.h | 1 |
6 files changed, 9 insertions, 3 deletions
diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp index 7501efea9e..fa95ab0e79 100644 --- a/scene/resources/canvas_item_material.cpp +++ b/scene/resources/canvas_item_material.cpp @@ -161,7 +161,7 @@ void CanvasItemMaterial::flush_changes() { void CanvasItemMaterial::_queue_shader_change() { MutexLock lock(material_mutex); - if (!element.in_list()) { + if (is_initialized && !element.in_list()) { dirty_materials->add(&element); } } @@ -287,6 +287,7 @@ CanvasItemMaterial::CanvasItemMaterial() : set_particles_anim_loop(false); current_key.invalid_key = 1; + is_initialized = true; _queue_shader_change(); } diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h index 0a813e0ae5..37cd4de136 100644 --- a/scene/resources/canvas_item_material.h +++ b/scene/resources/canvas_item_material.h @@ -102,6 +102,7 @@ private: _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + bool is_initialized = false; BlendMode blend_mode = BLEND_MODE_MIX; LightMode light_mode = LIGHT_MODE_NORMAL; bool particles_animation = false; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 1d2a2ef26c..0a97af65fe 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1301,7 +1301,7 @@ void BaseMaterial3D::flush_changes() { void BaseMaterial3D::_queue_shader_change() { MutexLock lock(material_mutex); - if (!element.in_list()) { + if (is_initialized && !element.in_list()) { dirty_materials->add(&element); } } @@ -2777,6 +2777,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : flags[FLAG_USE_TEXTURE_REPEAT] = true; + is_initialized = true; _queue_shader_change(); } diff --git a/scene/resources/material.h b/scene/resources/material.h index e2838e1399..5d7a5324ca 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -440,6 +440,7 @@ private: _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + bool is_initialized = false; bool orm; Color albedo; diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 0495a9e92c..d9ec0bfd69 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -741,7 +741,7 @@ void ParticlesMaterial::flush_changes() { void ParticlesMaterial::_queue_shader_change() { MutexLock lock(material_mutex); - if (!element.in_list()) { + if (is_initialized && !element.in_list()) { dirty_materials->add(&element); } } @@ -1533,6 +1533,7 @@ ParticlesMaterial::ParticlesMaterial() : current_key.invalid_key = 1; + is_initialized = true; _queue_shader_change(); } diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 8ab26aff77..36bc456978 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -226,6 +226,7 @@ private: _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + bool is_initialized = false; Vector3 direction; float spread; float flatness; |