[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