Fix #117335: Slow selection in scene with drivers

Change parameters tagging from implicit based on the copy-on-write to
more explicit, allowing to ignore tagging of parameters component for
changes which do not affect drivers.

There is still implicit parameters tagging based on tags for geometry
or transform components to avoid making changes in too many places of
Blender.

Should be no functional changes, only expecting better performance.

Pull Request: https://projects.blender.org/blender/blender/pulls/117336
This commit is contained in:
Sergey Sharybin
2024-01-19 15:21:53 +01:00
committed by Gitea
parent b2b6286366
commit 7a2d04a5c4
3 changed files with 38 additions and 9 deletions

View File

@@ -3427,19 +3427,12 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
/* Notes on exceptions:
* - Parameters component is where drivers are living. Changing any
* of the (custom) properties in the original datablock (even the
* ones which do not imply other component update) need to make
* sure drivers are properly updated.
* This way, for example, changing ID property will properly poke
* all drivers to be updated.
*
* - View layers have cached array of bases in them, which is not
* copied by copy-on-write, and not preserved. PROBABLY it is better
* to preserve that cache in copy-on-write, but for the time being
* we allow flush to layer collections component which will ensure
* that cached array of bases exists and is up-to-date. */
if (ELEM(comp_node->type, NodeType::PARAMETERS, NodeType::LAYER_COLLECTIONS)) {
if (ELEM(comp_node->type, NodeType::LAYER_COLLECTIONS)) {
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
/* Compatibility with the legacy tagging: groups are only tagged for Copy-on-Write when their

View File

@@ -507,6 +507,41 @@ void deg_graph_node_tag_zero(Main *bmain,
deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0, update_source);
}
/* Implicit tagging of the parameters component on other changes.
*
* This takes care of ensuring that if a change made in C side on parameters which affect,
* say, geometry and explicit tag only done for geometry, parameters are also tagged to give
* drivers a chance to re-evaluate for the new values. */
void deg_graph_tag_parameters_if_needed(Main *bmain,
Depsgraph *graph,
ID *id,
IDNode *id_node,
const uint flags,
const eUpdateSource update_source)
{
if (flags == 0) {
/* Tagging for 0 flags is handled in deg_graph_node_tag_zero(), and parameters are handled
* there as well. */
return;
}
if (flags & ID_RECALC_PARAMETERS) {
/* Parameters are already tagged for update explicitly, no need to run extra logic here. */
return;
}
/* Clear flags which are known to not affect parameters usable by drivers. */
const uint clean_flags = flags &
~(ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT | ID_RECALC_BASE_FLAGS);
if (clean_flags == 0) {
/* Changes are limited to only things which are not usable by drivers. */
return;
}
graph_id_tag_update_single_flag(bmain, graph, id, id_node, ID_RECALC_PARAMETERS, update_source);
}
void graph_tag_on_visible_update(Depsgraph *graph, const bool do_time)
{
graph->need_tag_id_on_graph_visibility_update = true;
@@ -709,6 +744,7 @@ void graph_id_tag_update(
graph_id_tag_update_single_flag(
bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
}
deg_graph_tag_parameters_if_needed(bmain, graph, id, id_node, flags, update_source);
}
} // namespace blender::deg

View File

@@ -2276,7 +2276,7 @@ static void rna_property_update(
if (ptr->owner_id != nullptr && ((prop->flag & PROP_NO_DEG_UPDATE) == 0)) {
const short id_type = GS(ptr->owner_id->name);
if (ID_TYPE_IS_COW(id_type)) {
DEG_id_tag_update(ptr->owner_id, ID_RECALC_COPY_ON_WRITE);
DEG_id_tag_update(ptr->owner_id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_PARAMETERS);
}
}
/* End message bus. */