[Bf-blender-cvs] [643c5a2] master: Depsgraph: Fix race condition writing drivers to array property

Sergey Sharybin noreply at git.blender.org
Wed Nov 2 18:09:00 CET 2016


Commit: 643c5a24d56f00c45d03b52f4b1211c05a78bf0f
Author: Sergey Sharybin
Date:   Wed Nov 2 18:05:38 2016 +0100
Branches: master
https://developer.blender.org/rB643c5a24d56f00c45d03b52f4b1211c05a78bf0f

Depsgraph: Fix race condition writing drivers to array property

Animation system has separate fcurves for each of array elements and
dependency graph creates separate nodes for each of fcurve, This is
needed to keep granularity of updates, but causes issues because
animation system will actually write the whole array to property when
modifying single value (this is a limitation of RNA API).

Worked around by adding operation relation between array drivers
so we never write same array form multiple threads.

===================================================================

M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc

===================================================================

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 47672d2..e506b87 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -842,6 +842,55 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
 		/* create the driver's relations to targets */
 		build_driver(id, fcu);
 
+		/* Special case for array drivers: we can not multithread them because
+		 * of the way how they work internally: animation system will write the
+		 * whole array back to RNA even when changing individual array value.
+		 *
+		 * Some tricky things here:
+		 * - array_index is -1 for single channel drivers, meaning we only have
+		 *   to do some magic when array_index is not -1.
+		 * - We do relation from next array index to a previous one, so we don't
+		 *   have to deal with array index 0.
+		 *
+		 * TODO(sergey): Avoid liner lookup somehow.
+		 */
+		if (fcu->array_index > 0) {
+			FCurve *fcu_prev = NULL;
+			for (FCurve *fcu_candidate = (FCurve *)adt->drivers.first;
+			     fcu_candidate != NULL;
+			     fcu_candidate = fcu_candidate->next)
+			{
+				/* Writing to different RNA paths is  */
+				if (!STREQ(fcu_candidate->rna_path, fcu->rna_path)) {
+					continue;
+				}
+				/* We only do relation from previous fcurve to previous one. */
+				if (fcu_candidate->array_index >= fcu->array_index) {
+					continue;
+				}
+				/* Choose fcurve with highest possible array index. */
+				if (fcu_prev == NULL ||
+				    fcu_candidate->array_index > fcu_prev->array_index)
+				{
+					fcu_prev = fcu_candidate;
+				}
+			}
+			if (fcu_prev != NULL) {
+				OperationKey prev_driver_key(id,
+				                             DEPSNODE_TYPE_PARAMETERS,
+				                             DEG_OPCODE_DRIVER,
+				                             deg_fcurve_id_name(fcu_prev));
+				OperationKey driver_key(id,
+				                        DEPSNODE_TYPE_PARAMETERS,
+				                        DEG_OPCODE_DRIVER,
+				                        deg_fcurve_id_name(fcu));
+				add_relation(prev_driver_key,
+				             driver_key,
+				             DEPSREL_TYPE_OPERATION,
+				             "[Driver Order]");
+			}
+		}
+
 		/* prevent driver from occurring before own animation... */
 		if (adt->action || adt->nla_tracks.first) {
 			add_relation(adt_key, driver_key, DEPSREL_TYPE_OPERATION,




More information about the Bf-blender-cvs mailing list