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; } _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs