diff options
author | Jacques Lucke <jacques@blender.org> | 2021-04-17 16:13:20 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-04-17 16:13:20 +0300 |
commit | 36088912828b0b511ce0f293f39187b5d8d770cf (patch) | |
tree | 86f479a323d761a73ac9741ac79c7bb1857d44e5 /source/blender/functions/intern | |
parent | e524a6ecf7cc34618d0118f5bb2e1f6a656fb7f4 (diff) |
Functions: extend virtual array functionality
This adds support for mutable virtual arrays and provides many utilities
for creating virtual arrays for various kinds of data. This commit is
preparation for D10994.
Diffstat (limited to 'source/blender/functions/intern')
4 files changed, 233 insertions, 43 deletions
diff --git a/source/blender/functions/intern/generic_vector_array.cc b/source/blender/functions/intern/generic_vector_array.cc index b3c5517cc43..3335b07e559 100644 --- a/source/blender/functions/intern/generic_vector_array.cc +++ b/source/blender/functions/intern/generic_vector_array.cc @@ -60,21 +60,21 @@ void GVectorArray::extend(const int64_t index, const GVArray &values) void GVectorArray::extend(const int64_t index, const GSpan values) { - GVArrayForGSpan varray{values}; + GVArray_For_GSpan varray{values}; this->extend(index, varray); } void GVectorArray::extend(IndexMask mask, const GVVectorArray &values) { for (const int i : mask) { - GVArrayForGVVectorArrayIndex array{values, i}; + GVArray_For_GVVectorArrayIndex array{values, i}; this->extend(i, array); } } void GVectorArray::extend(IndexMask mask, const GVectorArray &values) { - GVVectorArrayForGVectorArray virtual_values{values}; + GVVectorArray_For_GVectorArray virtual_values{values}; this->extend(mask, virtual_values); } diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc index 9380eb257b2..e11501828f8 100644 --- a/source/blender/functions/intern/generic_virtual_array.cc +++ b/source/blender/functions/intern/generic_virtual_array.cc @@ -18,6 +18,10 @@ namespace blender::fn { +/* -------------------------------------------------------------------- + * GVArray. + */ + void GVArray::materialize_to_uninitialized(const IndexMask mask, void *dst) const { for (const int64_t i : mask) { @@ -37,7 +41,7 @@ bool GVArray::is_span_impl() const return false; } -GSpan GVArray::get_span_impl() const +GSpan GVArray::get_internal_span_impl() const { BLI_assert(false); return GSpan(*type_); @@ -48,60 +52,246 @@ bool GVArray::is_single_impl() const return false; } -void GVArray::get_single_impl(void *UNUSED(r_value)) const +void GVArray::get_internal_single_impl(void *UNUSED(r_value)) const { BLI_assert(false); } -void GVArrayForGSpan::get_impl(const int64_t index, void *r_value) const +const void *GVArray::try_get_internal_varray_impl() const +{ + return nullptr; +} + +/* -------------------------------------------------------------------- + * GVMutableArray. + */ + +void GVMutableArray::set_by_copy_impl(const int64_t index, const void *value) +{ + BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); + type_->copy_to_uninitialized(value, buffer); + this->set_by_move_impl(index, buffer); + type_->destruct(buffer); +} + +void GVMutableArray::set_by_relocate_impl(const int64_t index, void *value) +{ + this->set_by_move_impl(index, value); + type_->destruct(value); +} + +void *GVMutableArray::try_get_internal_mutable_varray_impl() +{ + return nullptr; +} + +void GVMutableArray::fill(const void *value) +{ + if (this->is_span()) { + const GMutableSpan span = this->get_internal_span(); + type_->fill_initialized(value, span.data(), size_); + } + else { + for (int64_t i : IndexRange(size_)) { + this->set_by_copy(i, value); + } + } +} + +/* -------------------------------------------------------------------- + * GVArray_For_GSpan. + */ + +void GVArray_For_GSpan::get_impl(const int64_t index, void *r_value) const { type_->copy_to_initialized(POINTER_OFFSET(data_, element_size_ * index), r_value); } -void GVArrayForGSpan::get_to_uninitialized_impl(const int64_t index, void *r_value) const +void GVArray_For_GSpan::get_to_uninitialized_impl(const int64_t index, void *r_value) const { type_->copy_to_uninitialized(POINTER_OFFSET(data_, element_size_ * index), r_value); } -bool GVArrayForGSpan::is_span_impl() const +bool GVArray_For_GSpan::is_span_impl() const { return true; } -GSpan GVArrayForGSpan::get_span_impl() const +GSpan GVArray_For_GSpan::get_internal_span_impl() const { return GSpan(*type_, data_, size_); } -void GVArrayForSingleValueRef::get_impl(const int64_t UNUSED(index), void *r_value) const +/* -------------------------------------------------------------------- + * GVMutableArray_For_GMutableSpan. + */ + +void GVMutableArray_For_GMutableSpan::get_impl(const int64_t index, void *r_value) const +{ + type_->copy_to_initialized(POINTER_OFFSET(data_, element_size_ * index), r_value); +} + +void GVMutableArray_For_GMutableSpan::get_to_uninitialized_impl(const int64_t index, + void *r_value) const +{ + type_->copy_to_uninitialized(POINTER_OFFSET(data_, element_size_ * index), r_value); +} + +void GVMutableArray_For_GMutableSpan::set_by_copy_impl(const int64_t index, const void *value) +{ + type_->copy_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index)); +} + +void GVMutableArray_For_GMutableSpan::set_by_move_impl(const int64_t index, void *value) +{ + type_->move_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index)); +} + +void GVMutableArray_For_GMutableSpan::set_by_relocate_impl(const int64_t index, void *value) +{ + type_->relocate_to_initialized(value, POINTER_OFFSET(data_, element_size_ * index)); +} + +bool GVMutableArray_For_GMutableSpan::is_span_impl() const +{ + return true; +} + +GSpan GVMutableArray_For_GMutableSpan::get_internal_span_impl() const +{ + return GSpan(*type_, data_, size_); +} + +/* -------------------------------------------------------------------- + * GVArray_For_SingleValueRef. + */ + +void GVArray_For_SingleValueRef::get_impl(const int64_t UNUSED(index), void *r_value) const { type_->copy_to_initialized(value_, r_value); } -void GVArrayForSingleValueRef::get_to_uninitialized_impl(const int64_t UNUSED(index), - void *r_value) const +void GVArray_For_SingleValueRef::get_to_uninitialized_impl(const int64_t UNUSED(index), + void *r_value) const { type_->copy_to_uninitialized(value_, r_value); } -bool GVArrayForSingleValueRef::is_span_impl() const +bool GVArray_For_SingleValueRef::is_span_impl() const { return size_ == 1; } -GSpan GVArrayForSingleValueRef::get_span_impl() const +GSpan GVArray_For_SingleValueRef::get_internal_span_impl() const { return GSpan{*type_, value_, 1}; } -bool GVArrayForSingleValueRef::is_single_impl() const +bool GVArray_For_SingleValueRef::is_single_impl() const { return true; } -void GVArrayForSingleValueRef::get_single_impl(void *r_value) const +void GVArray_For_SingleValueRef::get_internal_single_impl(void *r_value) const { type_->copy_to_initialized(value_, r_value); } +/* -------------------------------------------------------------------- + * GVArray_For_SingleValue. + */ + +GVArray_For_SingleValue::GVArray_For_SingleValue(const CPPType &type, + const int64_t size, + const void *value) + : GVArray_For_SingleValueRef(type, size) +{ + value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__); + type.copy_to_uninitialized(value, (void *)value_); +} + +GVArray_For_SingleValue::~GVArray_For_SingleValue() +{ + type_->destruct((void *)value_); + MEM_freeN((void *)value_); +} + +/* -------------------------------------------------------------------- + * GVArray_GSpan. + */ + +GVArray_GSpan::GVArray_GSpan(const GVArray &varray) : GSpan(varray.type()), varray_(varray) +{ + size_ = varray_.size(); + if (varray_.is_span()) { + data_ = varray_.get_internal_span().data(); + } + else { + owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__); + varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_); + data_ = owned_data_; + } +} + +GVArray_GSpan::~GVArray_GSpan() +{ + if (owned_data_ != nullptr) { + type_->destruct_n(owned_data_, size_); + MEM_freeN(owned_data_); + } +} + +/* -------------------------------------------------------------------- + * GVMutableArray_GSpan. + */ + +GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray &varray, const bool copy_values_to_span) + : GMutableSpan(varray.type()), varray_(varray) +{ + size_ = varray_.size(); + if (varray_.is_span()) { + data_ = varray_.get_internal_span().data(); + } + else { + owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__); + if (copy_values_to_span) { + varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_); + } + else { + type_->construct_default_n(owned_data_, size_); + } + data_ = owned_data_; + } +} + +GVMutableArray_GSpan::~GVMutableArray_GSpan() +{ + if (show_not_saved_warning_) { + if (!save_has_been_called_) { + std::cout << "Warning: Call `apply()` to make sure that changes persist in all cases.\n"; + } + } + if (owned_data_ != nullptr) { + type_->destruct_n(owned_data_, size_); + MEM_freeN(owned_data_); + } +} + +void GVMutableArray_GSpan::save() +{ + save_has_been_called_ = true; + if (data_ != owned_data_) { + return; + } + const int64_t element_size = type_->size(); + for (int64_t i : IndexRange(size_)) { + varray_.set_by_copy(i, POINTER_OFFSET(owned_data_, element_size * i)); + } +} + +void GVMutableArray_GSpan::disable_not_applied_warning() +{ + show_not_saved_warning_ = false; +} + } // namespace blender::fn diff --git a/source/blender/functions/intern/generic_virtual_vector_array.cc b/source/blender/functions/intern/generic_virtual_vector_array.cc index f6504cee41e..aa3d90883c6 100644 --- a/source/blender/functions/intern/generic_virtual_vector_array.cc +++ b/source/blender/functions/intern/generic_virtual_vector_array.cc @@ -18,48 +18,48 @@ namespace blender::fn { -void GVArrayForGVVectorArrayIndex::get_impl(const int64_t index_in_vector, void *r_value) const +void GVArray_For_GVVectorArrayIndex::get_impl(const int64_t index_in_vector, void *r_value) const { vector_array_.get_vector_element(index_, index_in_vector, r_value); } -void GVArrayForGVVectorArrayIndex::get_to_uninitialized_impl(const int64_t index_in_vector, - void *r_value) const +void GVArray_For_GVVectorArrayIndex::get_to_uninitialized_impl(const int64_t index_in_vector, + void *r_value) const { type_->construct_default(r_value); vector_array_.get_vector_element(index_, index_in_vector, r_value); } -int64_t GVVectorArrayForSingleGVArray::get_vector_size_impl(const int64_t UNUSED(index)) const +int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t UNUSED(index)) const { return array_.size(); } -void GVVectorArrayForSingleGVArray::get_vector_element_impl(const int64_t UNUSED(index), - const int64_t index_in_vector, - void *r_value) const +void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t UNUSED(index), + const int64_t index_in_vector, + void *r_value) const { array_.get(index_in_vector, r_value); } -bool GVVectorArrayForSingleGVArray::is_single_vector_impl() const +bool GVVectorArray_For_SingleGVArray::is_single_vector_impl() const { return true; } -int64_t GVVectorArrayForSingleGSpan::get_vector_size_impl(const int64_t UNUSED(index)) const +int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t UNUSED(index)) const { return span_.size(); } -void GVVectorArrayForSingleGSpan::get_vector_element_impl(const int64_t UNUSED(index), - const int64_t index_in_vector, - void *r_value) const +void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t UNUSED(index), + const int64_t index_in_vector, + void *r_value) const { type_->copy_to_initialized(span_[index_in_vector], r_value); } -bool GVVectorArrayForSingleGSpan::is_single_vector_impl() const +bool GVVectorArray_For_SingleGSpan::is_single_vector_impl() const { return true; } diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc index 86ac4f6a179..9a0cb0c35ce 100644 --- a/source/blender/functions/intern/multi_function_network_evaluation.cc +++ b/source/blender/functions/intern/multi_function_network_evaluation.cc @@ -974,11 +974,11 @@ const GVArray &MFNetworkEvaluationStorage::get_single_input__full(const MFInputS if (any_value->type == ValueType::OwnSingle) { OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value); if (value->is_single_allocated) { - return scope.construct<GVArrayForSingleValueRef>( + return scope.construct<GVArray_For_SingleValueRef>( __func__, value->span.type(), min_array_size_, value->span.data()); } - return scope.construct<GVArrayForGSpan>(__func__, value->span); + return scope.construct<GVArray_For_GSpan>(__func__, value->span); } if (any_value->type == ValueType::InputSingle) { InputSingleValue *value = static_cast<InputSingleValue *>(any_value); @@ -987,11 +987,11 @@ const GVArray &MFNetworkEvaluationStorage::get_single_input__full(const MFInputS if (any_value->type == ValueType::OutputSingle) { OutputSingleValue *value = static_cast<OutputSingleValue *>(any_value); BLI_assert(value->is_computed); - return scope.construct<GVArrayForGSpan>(__func__, value->span); + return scope.construct<GVArray_For_GSpan>(__func__, value->span); } BLI_assert(false); - return scope.construct<GVArrayForEmpty>(__func__, CPPType::get<float>()); + return scope.construct<GVArray_For_Empty>(__func__, CPPType::get<float>()); } const GVArray &MFNetworkEvaluationStorage::get_single_input__single(const MFInputSocket &socket, @@ -1004,7 +1004,7 @@ const GVArray &MFNetworkEvaluationStorage::get_single_input__single(const MFInpu if (any_value->type == ValueType::OwnSingle) { OwnSingleValue *value = static_cast<OwnSingleValue *>(any_value); BLI_assert(value->span.size() == 1); - return scope.construct<GVArrayForGSpan>(__func__, value->span); + return scope.construct<GVArray_For_GSpan>(__func__, value->span); } if (any_value->type == ValueType::InputSingle) { InputSingleValue *value = static_cast<InputSingleValue *>(any_value); @@ -1015,11 +1015,11 @@ const GVArray &MFNetworkEvaluationStorage::get_single_input__single(const MFInpu OutputSingleValue *value = static_cast<OutputSingleValue *>(any_value); BLI_assert(value->is_computed); BLI_assert(value->span.size() == 1); - return scope.construct<GVArrayForGSpan>(__func__, value->span); + return scope.construct<GVArray_For_GSpan>(__func__, value->span); } BLI_assert(false); - return scope.construct<GVArrayForEmpty>(__func__, CPPType::get<float>()); + return scope.construct<GVArray_For_Empty>(__func__, CPPType::get<float>()); } const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__full( @@ -1033,10 +1033,10 @@ const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__full( OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value); if (value->vector_array->size() == 1) { GSpan span = (*value->vector_array)[0]; - return scope.construct<GVVectorArrayForSingleGSpan>(__func__, span, min_array_size_); + return scope.construct<GVVectorArray_For_SingleGSpan>(__func__, span, min_array_size_); } - return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array); + return scope.construct<GVVectorArray_For_GVectorArray>(__func__, *value->vector_array); } if (any_value->type == ValueType::InputVector) { InputVectorValue *value = static_cast<InputVectorValue *>(any_value); @@ -1044,11 +1044,11 @@ const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__full( } if (any_value->type == ValueType::OutputVector) { OutputVectorValue *value = static_cast<OutputVectorValue *>(any_value); - return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array); + return scope.construct<GVVectorArray_For_GVectorArray>(__func__, *value->vector_array); } BLI_assert(false); - return scope.construct<GVVectorArrayForSingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0); + return scope.construct<GVVectorArray_For_SingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0); } const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__single( @@ -1061,7 +1061,7 @@ const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__single( if (any_value->type == ValueType::OwnVector) { OwnVectorValue *value = static_cast<OwnVectorValue *>(any_value); BLI_assert(value->vector_array->size() == 1); - return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array); + return scope.construct<GVVectorArray_For_GVectorArray>(__func__, *value->vector_array); } if (any_value->type == ValueType::InputVector) { InputVectorValue *value = static_cast<InputVectorValue *>(any_value); @@ -1071,11 +1071,11 @@ const GVVectorArray &MFNetworkEvaluationStorage::get_vector_input__single( if (any_value->type == ValueType::OutputVector) { OutputVectorValue *value = static_cast<OutputVectorValue *>(any_value); BLI_assert(value->vector_array->size() == 1); - return scope.construct<GVVectorArrayForGVectorArray>(__func__, *value->vector_array); + return scope.construct<GVVectorArray_For_GVectorArray>(__func__, *value->vector_array); } BLI_assert(false); - return scope.construct<GVVectorArrayForSingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0); + return scope.construct<GVVectorArray_For_SingleGSpan>(__func__, GSpan(CPPType::get<float>()), 0); } /** \} */ |