[Bf-blender-cvs] [e029b754fe] id_override_static: Some naive solution to avoid running 'generate auto override' code too often.

Bastien Montagne noreply at git.blender.org
Wed Feb 8 20:26:31 CET 2017


Commit: e029b754fedb20dc57e5ee9e9e87823edc3c8be1
Author: Bastien Montagne
Date:   Wed Feb 8 15:38:25 2017 +0100
Branches: id_override_static
https://developer.blender.org/rBe029b754fedb20dc57e5ee9e9e87823edc3c8be1

Some naive solution to avoid running 'generate auto override' code too often.

Proper solution will come later (probably based on some background job
or so...).

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

M	source/blender/blenkernel/BKE_library_override.h
M	source/blender/blenkernel/intern/library_override.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_access.c

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

diff --git a/source/blender/blenkernel/BKE_library_override.h b/source/blender/blenkernel/BKE_library_override.h
index e170b41069..41d5da6fdf 100644
--- a/source/blender/blenkernel/BKE_library_override.h
+++ b/source/blender/blenkernel/BKE_library_override.h
@@ -60,7 +60,7 @@ bool BKE_override_status_check_reference(struct ID *local);
 bool BKE_override_operations_store_start(struct ID *local);
 void BKE_override_operations_store_end(struct ID *local);
 
-bool BKE_override_operations_create(struct ID *local);
+bool BKE_override_operations_create(struct ID *local, const bool no_skip);
 
 void BKE_override_update(struct ID *local, const bool do_init);
 void BKE_main_override_update(struct Main *bmain, const bool do_init);
diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index abe2573fb9..b236e78db2 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -45,6 +45,10 @@
 #include "RNA_access.h"
 #include "RNA_types.h"
 
+#include "PIL_time.h"
+#include "PIL_time_utildefines.h"
+
+#define OVERRIDE_AUTO_GAP 0.2  /* 200ms between auto-override checks. */
 
 /** Initialize empty overriding of \a reference_id by \a local_id. */
 IDOverride *BKE_override_init(struct ID *local_id, struct ID *reference_id)
@@ -276,6 +280,12 @@ bool BKE_override_status_check_reference(ID *local)
 bool BKE_override_operations_store_start(ID *local)
 {
 	BLI_assert(local->override != NULL);
+	bool ret = false;
+
+	/* Forcefully ensure we now about all needed poverride operations. */
+	BKE_override_operations_create(local, true);
+
+	TIMEIT_START_AVERAGED(BKE_override_operations_store_start);
 
 	/* Here we work on original local data-block, after having made a temp copy of it.
 	 * Once we are done, _store_end() will swap temp and local contents.
@@ -289,7 +299,7 @@ bool BKE_override_operations_store_start(ID *local)
 	id_copy(G.main, local, &tmp_id, false);  /* XXX ...and worse of all, this won't work with scene! */
 
 	if (tmp_id == NULL) {
-		return false;
+		return ret;
 	}
 
 	PointerRNA rnaptr_reference, rnaptr_final;
@@ -298,13 +308,15 @@ bool BKE_override_operations_store_start(ID *local)
 
 	if (!RNA_struct_override_store(&rnaptr_final, &rnaptr_reference, local->override)) {
 		BKE_libblock_free_ex(G.main, tmp_id, true, false);
-		return false;
+	}
+	else {
+		local->tag &= ~LIB_TAG_OVERRIDE_OK;
+		local->newid = tmp_id;
+		ret = true;
 	}
 
-	local->tag &= ~LIB_TAG_OVERRIDE_OK;
-	local->newid = tmp_id;
-
-	return true;
+	TIMEIT_END_AVERAGED(BKE_override_operations_store_start);
+	return ret;
 }
 
 /** Restore given ID modified by \a BKE_override_operations_store_start, to its valid original state. */
@@ -328,23 +340,40 @@ void BKE_override_operations_store_end(ID *local)
  * Compares local and reference data-blocks and create new override operations as needed,
  * or reset to reference values if overriding is not allowed.
  *
+ * \note Defining override operations is only mandatory before saving a .blend file on disk (not for undo!).
+ * Knowing that info at runtime is only useful for UI/UX feedback.
+ *
+ * \note This is by far the biggest operation (the more time-consuming) of the three so far, since it has to go over
+ * all properties in depth (all overridable ones at least). Generating diff values and applying overrides
+ * are much cheaper.
+ *
  * \return true is new overriding op was created, or some local data was reset. */
-bool BKE_override_operations_create(ID *local)
+bool BKE_override_operations_create(ID *local, const bool no_skip)
 {
 	BLI_assert(local->override != NULL);
+	bool ret = false;
+
 	if (local->flag & LIB_AUTOOVERRIDE) {
+		/* This prevents running that (heavy) callback too often when editing data. */
+		const double currtime = PIL_check_seconds_timer();
+		if (!no_skip && (currtime - local->override->last_auto_run) < OVERRIDE_AUTO_GAP) {
+			return ret;
+		}
+		local->override->last_auto_run = currtime;
+
 		PointerRNA rnaptr_local, rnaptr_reference;
 		RNA_id_pointer_create(local, &rnaptr_local);
 		RNA_id_pointer_create(local->override->reference, &rnaptr_reference);
 
-		if (RNA_struct_auto_override(&rnaptr_local, &rnaptr_reference, local->override, NULL)) {
+		ret = RNA_struct_auto_override(&rnaptr_local, &rnaptr_reference, local->override, NULL);
+		if (ret) {
 			printf("We did generate static override rules for %s\n", local->name);
 		}
 		else {
 			printf("No new static override rules for %s\n", local->name);
 		}
 	}
-	return false;
+	return ret;
 }
 
 /** Update given override from its reference (re-applying overriden properties). */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index b128acf776..7d3927e9f0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -178,8 +178,10 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id)
 			comp_node->owner = id_node;
 
 			/* TDOD We most certainly do not want to run this on every deg evaluation! Especially not during animation? */
-			add_operation_node(comp_node, DEPSOP_TYPE_INIT, function_bind(BKE_override_operations_create, id),
-							   DEG_OPCODE_OPERATION, "override_generator", 0);
+			/* Ideally, putting this in some kind of queue (only one entry per ID in whole queue) and consuming it in a
+			 * low-priority background thread would be ideal, but we need to ensure IDs remain valid for the thread? */
+			add_operation_node(comp_node, DEPSOP_TYPE_INIT, function_bind(BKE_override_operations_create, id, false),
+			                   DEG_OPCODE_OPERATION, "override_generator", 0);
 		}
 	}
 
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 0db7840816..c05f19227c 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -159,6 +159,10 @@ typedef struct IDOverrideProperty {
 typedef struct IDOverride {
 	struct ID *reference;  /* Reference linked ID which this one overrides. */
 	ListBase properties;  /* List of IDOverrideProperty structs. */
+
+	/* Runtime data. */
+	void *pad_p1;
+	double last_auto_run;  /* Last time auto-override detection was run, to avoid too mush overhead on that. */
 } IDOverride;
 
 
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 73360b5063..d914d22a12 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1015,7 +1015,7 @@ char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int
  * call RNA_struct_find_property. The names have to exist as RNA properties
  * for the type in the pointer, if they do not exist an error will be printed.
  *
- * There is no support for pointers and collections here yet, these can be 
+ * There is no support for pointers and collections here yet, these can be
  * added when ID properties support them. */
 
 int  RNA_boolean_get(PointerRNA *ptr, const char *name);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index f607182419..dae31b55fd 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -6828,7 +6828,7 @@ bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNAEqualsMode mode)
 }
 
 /* Low-level functions, also used by non-override RNA API like copy or equality check. */
-
+#include "PIL_time_utildefines.h"
 /* Used for both Pointer and Collection properties. */
 static bool rna_property_override_equals_propptr(
         PointerRNA *propptr_a, PointerRNA *propptr_b, eRNAEqualsMode mode,
@@ -7889,6 +7889,7 @@ bool RNA_struct_override_store(PointerRNA *local, PointerRNA *reference, IDOverr
 {
 	bool changed = false;
 
+	TIMEIT_START_AVERAGED(RNA_struct_override_store);
 	for (IDOverrideProperty *op = override->properties.first; op; op = op->next) {
 		/* Simplified for now! */
 		PointerRNA src_data, dst_data;
@@ -7900,6 +7901,7 @@ bool RNA_struct_override_store(PointerRNA *local, PointerRNA *reference, IDOverr
 			changed = changed || rna_property_override_operation_store(&dst_data, &src_data, src_prop, op);
 		}
 	}
+	TIMEIT_END_AVERAGED(RNA_struct_override_store);
 
 	return changed;
 }
@@ -7918,6 +7920,7 @@ void RNA_property_override_apply(
 /** Apply given \a override operations on \a dst, using \a src as source. */
 void RNA_struct_override_apply(PointerRNA *dst, PointerRNA *src, IDOverride *override, const bool do_init)
 {
+	TIMEIT_START_AVERAGED(RNA_struct_override_apply);
 	for (IDOverrideProperty *op = override->properties.first; op; op = op->next) {
 		/* Simplified for now! */
 		PointerRNA src_data, dst_data;
@@ -7930,6 +7933,7 @@ void RNA_struct_override_apply(PointerRNA *dst, PointerRNA *src, IDOverride *ove
 			RNA_property_override_apply(&dst_data, &src_data, src_prop, op, do_init);
 		}
 	}
+	TIMEIT_END_AVERAGED(RNA_struct_override_apply);
 }
 
 /** Automatically define override rules by comparing \a local and \a reference RNA structs. */
@@ -7946,6 +7950,13 @@ bool RNA_struct_auto_override(PointerRNA *local, PointerRNA *reference, IDOverri
 		return changed;
 	}
 
+	static float _sum_time = 0.0f;
+	static float _num_time = 0.0f;
+	double _timeit_time;
+	if (!root_path) {
+		_timeit_time = PIL_check_seconds_timer();
+	}
+
 	iterprop = RNA_struct_iterator_property(local->type);
 
 	for (RNA_property_collection_begin(local, iterprop, &iter); iter.valid; RNA_property_collection_next(&iter)) {
@@ -7974,6 +7985,15 @@ bool RNA_struct_auto_override(PointerRNA *local, PointerRNA *reference, IDOverri
 	}
 	RNA_property_collection_end(&iter);
 
+	if (!root_path) {
+		const float _delta_time = (float)(PIL_check_seconds_timer() - _timeit_time);
+		_sum_time += _delta_time;
+		_num_time++;
+		printf("ID: %s\n", ((ID *)local->id.data)->name);
+		printf("time end      (%s): %.6f\n", __func__, _delta_time);
+		printf("time averaged (%s): %.6f (total: %.6f, in %d runs)\n", __func__, (_sum_time / _num_time), _sum_time, (int)_num_time);
+	}
+
 	return changed;
 }




More information about the Bf-blender-cvs mailing list