From 25d30e6c99a2d89bf7babfacb24a8c8aa61b3b3b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 16 Nov 2021 14:49:58 -0600 Subject: Fix T92857: Deadlock in geometry nodes curve multi-threading The spline code, especially Bezier splines, often make use of lazily evaluation and caching. In order to do that, they use mutex locks. When multi-threading, this can lead to problems. Further detail can be found in rBfcc844f8fbd0d1. To fix the deadlock, isolate the task before multi-threading when holding a lock. Differential Revision: https://developer.blender.org/D13229 --- source/blender/blenkernel/intern/spline_bezier.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc index 166fe0f5464..18d195f19da 100644 --- a/source/blender/blenkernel/intern/spline_bezier.cc +++ b/source/blender/blenkernel/intern/spline_bezier.cc @@ -599,7 +599,10 @@ Span BezierSpline::evaluated_mappings() const Span offsets = this->control_point_offsets(); - calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings); + blender::threading::isolate_task([&]() { + /* Isolate the task, since this is function is multi-threaded and holds a lock. */ + calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings); + }); mapping_cache_dirty_ = false; return mappings; @@ -635,10 +638,13 @@ Span BezierSpline::evaluated_positions() const Span offsets = this->control_point_offsets(); const int grain_size = std::max(512 / resolution_, 1); - blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) { - for (const int i : range) { - this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i])); - } + blender::threading::isolate_task([&]() { + /* Isolate the task, since this is function is multi-threaded and holds a lock. */ + blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) { + for (const int i : range) { + this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i])); + } + }); }); if (is_cyclic_) { this->evaluate_segment( -- cgit v1.2.3 From f30e1fd2f0648d6c88bc61142ecc003ffa33ce11 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 16 Nov 2021 14:51:03 -0600 Subject: Fix T93085: Incorrect geometry nodes modifier warning It's valid for a node group connected to the modifier not to have a geometry input, but I didn't consider that case with the last change I made here, f3bdabbe24fe591dc9. Differential Revision: https://developer.blender.org/D13231 --- source/blender/modifiers/intern/MOD_nodes.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source/blender') diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 70f6020f5a9..c1cdfa43920 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1031,11 +1031,9 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) int i; LISTBASE_FOREACH_INDEX (const bNodeSocket *, socket, &nmd->node_group->inputs, i) { /* The first socket is the special geometry socket for the modifier object. */ - if (i == 0) { - if (socket->type == SOCK_GEOMETRY) { - continue; - } - BKE_modifier_set_error(ob, md, "The first node group input must be a geometry"); + if (i == 0 && socket->type == SOCK_GEOMETRY) { + geometry_socket_count++; + continue; } IDProperty *property = IDP_GetPropertyFromGroup(nmd->settings.properties, socket->identifier); @@ -1056,7 +1054,12 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) } } - if (geometry_socket_count > 1) { + if (geometry_socket_count == 1) { + if (((bNodeSocket *)nmd->node_group->inputs.first)->type != SOCK_GEOMETRY) { + BKE_modifier_set_error(ob, md, "Node group's geometry input must be the first"); + } + } + else if (geometry_socket_count > 1) { BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); } } -- cgit v1.2.3