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.
This commit is contained in:
parent
93aa158b5e
commit
dbe757102c
6 changed files with 9 additions and 3 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue