Fix #119938: performance regression when adding output attribute

Avoid calling `modify_geometry_sets` because this can potentially result in
additional data copies when the geometry references the final mesh of other objects.

For more details, see https://projects.blender.org/blender/blender/issues/119938#issuecomment-1155109.

This implements a special case to avoid the regression until e.g. #119968 is done.

Pull Request: https://projects.blender.org/blender/blender/pulls/120177
This commit is contained in:
Jacques Lucke 2024-04-02 17:48:03 +02:00
parent 03bcd7390a
commit 77a34791a3
1 changed files with 13 additions and 0 deletions

View File

@ -752,6 +752,19 @@ static void store_output_attributes(bke::GeometrySet &geometry,
if (outputs_by_domain.size() == 0) {
return;
}
const bool only_instance_attributes = outputs_by_domain.size() == 1 &&
*outputs_by_domain.keys().begin() ==
bke::AttrDomain::Instance;
if (only_instance_attributes) {
/* No need to call #modify_geometry_sets when only adding attributes to top-level instances.
* This avoids some unnecessary data copies currently if some sub-geometries are not yet owned
* by the geometry set, i.e. they use #GeometryOwnershipType::Editable/ReadOnly. */
Vector<OutputAttributeToStore> attributes_to_store = compute_attributes_to_store(
geometry, outputs_by_domain, true);
store_computed_output_attributes(geometry, attributes_to_store);
return;
}
geometry.modify_geometry_sets([&](bke::GeometrySet &instance_geometry) {
/* Instance attributes should only be created for the top-level geometry. */
const bool do_instances = &geometry == &instance_geometry;