From a070dd8bdd6e3765b005dc01ec08036fdda36360 Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Tue, 6 Jul 2021 16:15:03 +0200 Subject: Cleanup: Set execution system as operations member in Compositor --- source/blender/compositor/intern/COM_ExecutionSystem.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/compositor/intern/COM_ExecutionSystem.cc') diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index a12ec774032..abe94ec8f40 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -101,6 +101,9 @@ void ExecutionSystem::set_operations(const Vector &operations, { m_operations = operations; m_groups = groups; + for (NodeOperation *op : m_operations) { + op->set_execution_system(this); + } } void ExecutionSystem::execute() -- cgit v1.2.3 From 46a261e108ee98a4f557dc731ff8be9887cd061c Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Tue, 6 Jul 2021 19:54:13 +0200 Subject: Compositor: Fix execution system unset during constant folding --- source/blender/compositor/intern/COM_ExecutionSystem.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source/blender/compositor/intern/COM_ExecutionSystem.cc') diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index abe94ec8f40..07f4082573c 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -64,7 +64,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, this->m_context.setDisplaySettings(displaySettings); { - NodeOperationBuilder builder(&m_context, editingtree); + NodeOperationBuilder builder(&m_context, editingtree, this); builder.convertToOperations(this); } @@ -101,9 +101,6 @@ void ExecutionSystem::set_operations(const Vector &operations, { m_operations = operations; m_groups = groups; - for (NodeOperation *op : m_operations) { - op->set_execution_system(this); - } } void ExecutionSystem::execute() -- cgit v1.2.3 From 1657fa039dcbf969b5e514ab77d72880817a7f9e Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Wed, 7 Jul 2021 00:06:46 +0200 Subject: Compositor: Fix crash when executing works in constant folding Work scheduler needed initialization and execution models are not created during constant folding. This moves work execution method to execution system. --- .../compositor/intern/COM_ExecutionSystem.cc | 72 +++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'source/blender/compositor/intern/COM_ExecutionSystem.cc') diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index 07f4082573c..dfcf76cdd0a 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -63,6 +63,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, this->m_context.setViewSettings(viewSettings); this->m_context.setDisplaySettings(displaySettings); + BLI_mutex_init(&work_mutex_); + BLI_condition_init(&work_finished_cond_); + { NodeOperationBuilder builder(&m_context, editingtree, this); builder.convertToOperations(this); @@ -83,6 +86,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, ExecutionSystem::~ExecutionSystem() { + BLI_condition_end(&work_finished_cond_); + BLI_mutex_end(&work_mutex_); + delete execution_model_; for (NodeOperation *operation : m_operations) { @@ -109,10 +115,74 @@ void ExecutionSystem::execute() execution_model_->execute(*this); } +/** + * Multi-threadedly execute given work function passing work_rect splits as argument. + */ void ExecutionSystem::execute_work(const rcti &work_rect, std::function work_func) { - execution_model_->execute_work(work_rect, work_func); + if (is_breaked()) { + return; + } + + /* Split work vertically to maximize continuous memory. */ + const int work_height = BLI_rcti_size_y(&work_rect); + const int num_sub_works = MIN2(WorkScheduler::get_num_cpu_threads(), work_height); + const int split_height = num_sub_works == 0 ? 0 : work_height / num_sub_works; + int remaining_height = work_height - split_height * num_sub_works; + + Vector sub_works(num_sub_works); + int sub_work_y = work_rect.ymin; + int num_sub_works_finished = 0; + for (int i = 0; i < num_sub_works; i++) { + int sub_work_height = split_height; + + /* Distribute remaining height between sub-works. */ + if (remaining_height > 0) { + sub_work_height++; + remaining_height--; + } + + WorkPackage &sub_work = sub_works[i]; + sub_work.type = eWorkPackageType::CustomFunction; + sub_work.execute_fn = [=, &work_func, &work_rect]() { + if (is_breaked()) { + return; + } + rcti split_rect; + BLI_rcti_init( + &split_rect, work_rect.xmin, work_rect.xmax, sub_work_y, sub_work_y + sub_work_height); + work_func(split_rect); + }; + sub_work.executed_fn = [&]() { + BLI_mutex_lock(&work_mutex_); + num_sub_works_finished++; + if (num_sub_works_finished == num_sub_works) { + BLI_condition_notify_one(&work_finished_cond_); + } + BLI_mutex_unlock(&work_mutex_); + }; + WorkScheduler::schedule(&sub_work); + sub_work_y += sub_work_height; + } + BLI_assert(sub_work_y == work_rect.ymax); + + WorkScheduler::finish(); + + /* Ensure all sub-works finished. + * TODO: This a workaround for WorkScheduler::finish() not waiting all works on queue threading + * model. Sync code should be removed once it's fixed. */ + BLI_mutex_lock(&work_mutex_); + if (num_sub_works_finished < num_sub_works) { + BLI_condition_wait(&work_finished_cond_, &work_mutex_); + } + BLI_mutex_unlock(&work_mutex_); +} + +bool ExecutionSystem::is_breaked() const +{ + const bNodeTree *btree = m_context.getbNodeTree(); + return btree->test_break(btree->tbh); } } // namespace blender::compositor -- cgit v1.2.3