diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-02-21 18:41:19 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-02-21 18:57:13 +0300 |
commit | 4c30dc343165a643e2173a055ed2aca3137991a5 (patch) | |
tree | cd6e0d51f2acf7a1d3b172a32ce18457ab934605 /source/blender/depsgraph/intern/depsgraph_build.cc | |
parent | b8c7ff564cf580e72f1647e95fe6e02352aad3d2 (diff) |
Fix T73593: Drivers on hide_viewport and hide_render are unreliable
This fixes a threading issue (T73593) between drivers that write to the
same memory address. Driver nodes in the depsgraph now get relations to
each other in order to ensure serialisation.
These relations are only added between drivers that target the same
struct in RNA, which is determined by removing everything after the last
period. For example, a driver with data path
`pose.bones["Arm_L"].rotation_euler[2]` will be grouped with all other
drivers on that datablock with a data path that starts with
`pose.bones["Arm_L"]` to form a 'driver group'.
To find a suitable relation within such a driver group, say the relation
(from → to), a depth-first search is performed (turned out to be
marginally faster than a breadth-first in my test case) to see whether
this will create a cycle, and to see whether there already is such a
connection (direct or transitive). This is done by recursively
inspecting the incoming connections of the 'to' node and thereby walking
from it towards the 'from' node. This is an order of magnitde faster
than inspecting the outgoing connections of the 'from' node.
This approach generalises the special case for array properties, so the
code to support that special case has been removed from
`DepsgraphRelationBuilder::build_animdata_drivers()`.
A test on the Spring rig [1] shows that this process adds approximately
8% to the build time of the dependency graph. In my test case, it takes
28 ms for this process on a total 329 ms construction time. However,
since it also made some code obsolete, it only adds 24 ms (=8%) to the
construction time. I have experimented with a simple cache to keep track
of known-connected (from, to) node pairs, but this did not significantly
improve the timing.
Note that animation data and drivers are already connected by a
relation, which means that animating a field and also changing it with a
driver will not cause conflicts.
[1] https://cloud.blender.org/p/spring/5d30a1076249366fa1939cf1
Differential Revision: https://developer.blender.org/D6905
Reviewed By: sergey, mont29
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_build.cc')
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_build.cc | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index a570e042c26..3fe585ff73c 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -251,6 +251,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph, relation_builder.begin_build(); relation_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY); relation_builder.build_copy_on_write_relations(); + relation_builder.build_driver_relations(); /* Finalize building. */ graph_build_finalize_common(deg_graph, bmain); /* Finish statistics. */ @@ -284,6 +285,7 @@ void DEG_graph_build_for_render_pipeline(Depsgraph *graph, relation_builder.begin_build(); relation_builder.build_scene_render(scene, view_layer); relation_builder.build_copy_on_write_relations(); + relation_builder.build_driver_relations(); /* Finalize building. */ graph_build_finalize_common(deg_graph, bmain); /* Finish statistics. */ @@ -317,6 +319,7 @@ void DEG_graph_build_for_compositor_preview( relation_builder.build_scene_render(scene, view_layer); relation_builder.build_nodetree(nodetree); relation_builder.build_copy_on_write_relations(); + relation_builder.build_driver_relations(); /* Finalize building. */ graph_build_finalize_common(deg_graph, bmain); /* Finish statistics. */ @@ -458,6 +461,7 @@ void DEG_graph_build_from_ids(Depsgraph *graph, relation_builder.build_id(ids[i]); } relation_builder.build_copy_on_write_relations(); + relation_builder.build_driver_relations(); /* Finalize building. */ graph_build_finalize_common(deg_graph, bmain); /* Finish statistics. */ |