Merge branch 'blender-v3.4-release'

This commit is contained in:
Jacques Lucke 2022-11-06 15:45:45 +01:00
commit 37ca6e4fd1
7 changed files with 46 additions and 6 deletions

View File

@ -80,4 +80,15 @@ class HintReceiver {
~HintReceiver();
};
/**
* Used to make sure that lazy-threading hints don't propagate through task isolation. This is
* necessary to avoid deadlocks when isolated regions are used together with e.g. task pools. For
* more info see the comment on #BLI_task_isolate.
*/
class ReceiverIsolation {
public:
ReceiverIsolation();
~ReceiverIsolation();
};
} // namespace blender::lazy_threading

View File

@ -129,6 +129,7 @@ void parallel_invoke(const bool use_threading, Functions &&...functions)
template<typename Function> void isolate_task(const Function &function)
{
#ifdef WITH_TBB
lazy_threading::ReceiverIsolation isolation;
tbb::this_task_arena::isolate(function);
#else
function();

View File

@ -1,30 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_lazy_threading.hh"
#include "BLI_stack.hh"
#include "BLI_vector.hh"
namespace blender::lazy_threading {
/**
* This is a #RawVector so that it can be destructed after Blender checks for memory leaks.
* This uses a "raw" stack and vector so that it can be destructed after Blender checks for memory
* leaks. A new list of receivers is created whenever an isolated region is entered to avoid
* deadlocks.
*/
thread_local RawVector<FunctionRef<void()>, 0> hint_receivers;
using HintReceivers = RawStack<RawVector<FunctionRef<void()>, 0>, 0>;
thread_local HintReceivers hint_receivers = []() {
HintReceivers receivers;
/* Make sure there is always at least one vector. */
receivers.push_as();
return receivers;
}();
void send_hint()
{
for (const FunctionRef<void()> &fn : hint_receivers) {
for (const FunctionRef<void()> &fn : hint_receivers.peek()) {
fn();
}
}
HintReceiver::HintReceiver(const FunctionRef<void()> fn)
{
hint_receivers.append(fn);
hint_receivers.peek().append(fn);
}
HintReceiver::~HintReceiver()
{
hint_receivers.pop_last();
hint_receivers.peek().pop_last();
}
ReceiverIsolation::ReceiverIsolation()
{
hint_receivers.push_as();
}
ReceiverIsolation::~ReceiverIsolation()
{
BLI_assert(hint_receivers.peek().is_empty());
hint_receivers.pop();
}
} // namespace blender::lazy_threading

View File

@ -8,6 +8,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_lazy_threading.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
@ -67,6 +68,7 @@ int BLI_task_scheduler_num_threads()
void BLI_task_isolate(void (*func)(void *userdata), void *userdata)
{
#ifdef WITH_TBB
blender::lazy_threading::ReceiverIsolation isolation;
tbb::this_task_arena::isolate([&] { func(userdata); });
#else
func(userdata);

View File

@ -876,6 +876,9 @@ static void find_side_effect_nodes_for_viewer_path(
if (found_node->id == nullptr) {
return;
}
if (found_node->is_muted()) {
return;
}
group_node_stack.push(found_node);
group = reinterpret_cast<bNodeTree *>(found_node->id);
compute_context_builder.push<blender::bke::NodeGroupComputeContext>(group_node_name);

View File

@ -309,6 +309,7 @@ class SampleCurveFunction : public fn::MultiFunction {
if (curves.points_num() == 0) {
return return_default();
}
curves.ensure_can_interpolate_to_evaluated();
Span<float3> evaluated_positions = curves.evaluated_positions();
Span<float3> evaluated_tangents;
Span<float3> evaluated_normals;

View File

@ -24,11 +24,13 @@ static void set_resolution(bke::CurvesGeometry &curves,
MutableAttributeAccessor attributes = curves.attributes_for_write();
AttributeWriter<int> resolutions = attributes.lookup_or_add_for_write<int>("resolution",
ATTR_DOMAIN_CURVE);
bke::AttributeValidator validator = attributes.lookup_validator("resolution");
bke::CurvesFieldContext field_context{curves, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{field_context, curves.curves_num()};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(resolution_field, resolutions.varray);
evaluator.add_with_destination(validator.validate_field_if_necessary(resolution_field),
resolutions.varray);
evaluator.evaluate();
resolutions.finish();