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:
authorJacques Lucke <jacques@blender.org>2021-01-12 14:49:34 +0300
committerJacques Lucke <jacques@blender.org>2021-01-12 14:50:29 +0300
commit3a254b93fd8597c47fc4fe55fa0417d1f9fa85fc (patch)
tree00fe1e373f828b23a3242b80c37b65146a2dd1c3 /source/blender/blenkernel/intern/attribute_access.cc
parent58dae919e51547a8fe7e676e317de3ee17b49e64 (diff)
Geometry Nodes: support reading from spans of WriteAttribute
Previously, the span returned by `WriteAttribute`s might not contain the current value of the attribute for performance reasons. To avoid some bugs, the span now always contains the old values (they might have to be copied over from the internal storage, dependending on how the attribute is stored). The old behavior is still available with the `get_span_for_write_only` method. The span that it returns might not contain the current attribute values. Therefore, it should only be used when you want to overwrite an attribute without looking at the old values.
Diffstat (limited to 'source/blender/blenkernel/intern/attribute_access.cc')
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc35
1 files changed, 27 insertions, 8 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 934beb8a848..8d30bc95236 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -97,26 +97,45 @@ WriteAttribute::~WriteAttribute()
/**
* Get a mutable span that can be modified. When all modifications to the attribute are done,
- * #apply_span_if_necessary should be called.
- */
+ * #apply_span should be called. */
fn::GMutableSpan WriteAttribute::get_span()
{
if (size_ == 0) {
return fn::GMutableSpan(cpp_type_);
}
if (array_buffer_ == nullptr) {
- this->initialize_span();
+ this->initialize_span(false);
}
array_should_be_applied_ = true;
return fn::GMutableSpan(cpp_type_, array_buffer_, size_);
}
-void WriteAttribute::initialize_span()
+fn::GMutableSpan WriteAttribute::get_span_for_write_only()
{
- array_buffer_ = MEM_mallocN_aligned(cpp_type_.size() * size_, cpp_type_.alignment(), __func__);
+ if (size_ == 0) {
+ return fn::GMutableSpan(cpp_type_);
+ }
+ if (array_buffer_ == nullptr) {
+ this->initialize_span(true);
+ }
+ array_should_be_applied_ = true;
+ return fn::GMutableSpan(cpp_type_, array_buffer_, size_);
+}
+
+void WriteAttribute::initialize_span(const bool write_only)
+{
+ const int element_size = cpp_type_.size();
+ array_buffer_ = MEM_mallocN_aligned(element_size * size_, cpp_type_.alignment(), __func__);
array_is_temporary_ = true;
- /* This does nothing for trivial types, but is necessary for general correctness. */
- cpp_type_.construct_default_n(array_buffer_, size_);
+ if (write_only) {
+ /* This does nothing for trivial types, but is necessary for general correctness. */
+ cpp_type_.construct_default_n(array_buffer_, size_);
+ }
+ else {
+ for (const int i : IndexRange(size_)) {
+ this->get(i, POINTER_OFFSET(array_buffer_, i * element_size));
+ }
+ }
}
void WriteAttribute::apply_span()
@@ -219,7 +238,7 @@ template<typename T> class ArrayWriteAttribute final : public WriteAttribute {
data_[index] = *reinterpret_cast<const T *>(value);
}
- void initialize_span() override
+ void initialize_span(const bool UNUSED(write_only)) override
{
array_buffer_ = data_.data();
array_is_temporary_ = false;