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-10-29 10:28:31 +0300
committerJacques Lucke <jacques@blender.org>2021-10-29 10:28:31 +0300
commitcf771807b7997949611dbf76b43150592c9977cb (patch)
treed1b986d9cd4bf56c93edf9755d6163cc6263b0dc /source/blender/blenkernel/intern/attribute_access.cc
parentb546202a9afa5ee358893d82e6a1ba0f69cca254 (diff)
Geometry Nodes: do cache invalidation after writing attributes
This is a better and more general fix for T92511 and T92508 than the ones that I committed before. Previously, we tagged caches dirty when first accessing attributes. This led to incorrect caches when under some circumstances. Now cache invalidation is part of `OutputAttribute.save()`. A nice side benefit of this change is that it may make things more efficient in some cases, because we don't invalidate caches when they don't have to be invalidated. Differential Revision: https://developer.blender.org/D13009
Diffstat (limited to 'source/blender/blenkernel/intern/attribute_access.cc')
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc43
1 files changed, 36 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 1ea7f522bef..01b53baf237 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -360,7 +360,7 @@ GVArrayPtr BuiltinCustomDataLayerProvider::try_get_for_read(
return as_read_attribute_(data, domain_size);
}
-GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write(
+WriteAttributeLookup BuiltinCustomDataLayerProvider::try_get_for_write(
GeometryComponent &component) const
{
if (writable_ != Writable) {
@@ -397,10 +397,14 @@ GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write(
data = new_data;
}
+ std::function<void()> tag_modified_fn;
if (update_on_write_ != nullptr) {
- update_on_write_(component);
+ tag_modified_fn = [component = &component, update = update_on_write_]() {
+ update(*component);
+ };
}
- return as_write_attribute_(data, domain_size);
+
+ return {as_write_attribute_(data, domain_size), domain_, std::move(tag_modified_fn)};
}
bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) const
@@ -925,7 +929,7 @@ blender::bke::WriteAttributeLookup GeometryComponent::attribute_try_get_for_writ
const BuiltinAttributeProvider *builtin_provider =
providers->builtin_attribute_providers().lookup_default_as(attribute_id.name(), nullptr);
if (builtin_provider != nullptr) {
- return {builtin_provider->try_get_for_write(*this), builtin_provider->domain()};
+ return builtin_provider->try_get_for_write(*this);
}
}
for (const DynamicAttributesProvider *dynamic_provider :
@@ -1249,6 +1253,20 @@ static void save_output_attribute(OutputAttribute &output_attribute)
varray.get(i, buffer);
write_attribute.varray->set_by_relocate(i, buffer);
}
+ if (write_attribute.tag_modified_fn) {
+ write_attribute.tag_modified_fn();
+ }
+}
+
+static std::function<void(OutputAttribute &)> get_simple_output_attribute_save_method(
+ const blender::bke::WriteAttributeLookup &attribute)
+{
+ if (!attribute.tag_modified_fn) {
+ return {};
+ }
+ return [tag_modified_fn = attribute.tag_modified_fn](OutputAttribute &UNUSED(attribute)) {
+ tag_modified_fn();
+ };
}
static OutputAttribute create_output_attribute(GeometryComponent &component,
@@ -1293,14 +1311,21 @@ static OutputAttribute create_output_attribute(GeometryComponent &component,
/* Builtin attribute is on different domain. */
return {};
}
+
GVMutableArrayPtr varray = std::move(attribute.varray);
if (varray->type() == *cpp_type) {
/* Builtin attribute matches exactly. */
- return OutputAttribute(std::move(varray), domain, {}, ignore_old_values);
+ return OutputAttribute(std::move(varray),
+ domain,
+ get_simple_output_attribute_save_method(attribute),
+ ignore_old_values);
}
/* Builtin attribute is on the same domain but has a different data type. */
varray = conversions.try_convert(std::move(varray), *cpp_type);
- return OutputAttribute(std::move(varray), domain, {}, ignore_old_values);
+ return OutputAttribute(std::move(varray),
+ domain,
+ get_simple_output_attribute_save_method(attribute),
+ ignore_old_values);
}
const int domain_size = component.attribute_domain_size(domain);
@@ -1324,7 +1349,11 @@ static OutputAttribute create_output_attribute(GeometryComponent &component,
}
if (attribute.domain == domain && attribute.varray->type() == *cpp_type) {
/* Existing generic attribute matches exactly. */
- return OutputAttribute(std::move(attribute.varray), domain, {}, ignore_old_values);
+
+ return OutputAttribute(std::move(attribute.varray),
+ domain,
+ get_simple_output_attribute_save_method(attribute),
+ ignore_old_values);
}
/* Allocate a new array that lives next to the existing attribute. It will overwrite the existing