Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/intern')
-rw-r--r--source/blender/functions/intern/generic_vector_array.cc6
-rw-r--r--source/blender/functions/intern/generic_virtual_array.cc309
-rw-r--r--source/blender/functions/intern/generic_virtual_vector_array.cc26
-rw-r--r--source/blender/functions/intern/multi_function_network_evaluation.cc28
4 files changed, 326 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..87dae06ccdc 100644
--- a/source/blender/functions/intern/generic_virtual_array.cc
+++ b/source/blender/functions/intern/generic_virtual_array.cc
@@ -18,8 +18,72 @@
namespace blender::fn {
+/* --------------------------------------------------------------------
+ * GVArray_For_ShallowCopy.
+ */
+
+class GVArray_For_ShallowCopy : public GVArray {
+ private:
+ const GVArray &varray_;
+
+ public:
+ GVArray_For_ShallowCopy(const GVArray &varray)
+ : GVArray(varray.type(), varray.size()), varray_(varray)
+ {
+ }
+
+ private:
+ void get_impl(const int64_t index, void *r_value) const override
+ {
+ varray_.get(index, r_value);
+ }
+
+ void get_to_uninitialized_impl(const int64_t index, void *r_value) const override
+ {
+ varray_.get_to_uninitialized(index, r_value);
+ }
+
+ void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override
+ {
+ varray_.materialize_to_uninitialized(mask, dst);
+ }
+};
+
+/* --------------------------------------------------------------------
+ * GVArray.
+ */
+
+void GVArray::materialize(void *dst) const
+{
+ this->materialize(IndexMask(size_), dst);
+}
+
+void GVArray::materialize(const IndexMask mask, void *dst) const
+{
+ this->materialize_impl(mask, dst);
+}
+
+void GVArray::materialize_impl(const IndexMask mask, void *dst) const
+{
+ for (const int64_t i : mask) {
+ void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
+ this->get(i, elem_dst);
+ }
+}
+
+void GVArray::materialize_to_uninitialized(void *dst) const
+{
+ this->materialize_to_uninitialized(IndexMask(size_), dst);
+}
+
void GVArray::materialize_to_uninitialized(const IndexMask mask, void *dst) const
{
+ BLI_assert(mask.min_array_size() <= size_);
+ this->materialize_to_uninitialized_impl(mask, dst);
+}
+
+void GVArray::materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const
+{
for (const int64_t i : mask) {
void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
this->get_to_uninitialized(i, elem_dst);
@@ -37,7 +101,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 +112,279 @@ 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;
+}
+
+/**
+ * Creates a new `std::unique_ptr<GVArray>` based on this `GVArray`.
+ * The lifetime of the returned virtual array must not be longer than the lifetime of this virtual
+ * array.
+ */
+GVArrayPtr GVArray::shallow_copy() const
+{
+ if (this->is_span()) {
+ return std::make_unique<GVArray_For_GSpan>(this->get_internal_span());
+ }
+ if (this->is_single()) {
+ BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer);
+ this->get_internal_single(buffer);
+ std::unique_ptr new_varray = std::make_unique<GVArray_For_SingleValue>(*type_, size_, buffer);
+ type_->destruct(buffer);
+ return new_varray;
+ }
+ return std::make_unique<GVArray_For_ShallowCopy>(*this);
+}
+
+/* --------------------------------------------------------------------
+ * 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::set_all_impl(const void *src)
+{
+ if (this->is_span()) {
+ const GMutableSpan span = this->get_internal_span();
+ type_->copy_to_initialized_n(src, span.data(), size_);
+ }
+ else {
+ for (int64_t i : IndexRange(size_)) {
+ this->set_by_copy(i, POINTER_OFFSET(src, type_->size() * i));
+ }
+ }
+}
+
+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);
}
/** \} */