diff options
Diffstat (limited to 'source/blender/depsgraph')
12 files changed, 120 insertions, 48 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index c3099c9486d..49c510d9d3e 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -115,11 +115,4 @@ set(SRC set(LIB ) -if(WITH_BOOST) - list(APPEND INC_SYS - ${BOOST_INCLUDE_DIR} - ) - add_definitions(-DHAVE_BOOST_FUNCTION_BINDINGS) -endif() - blender_add_lib(bf_depsgraph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 36c6d246097..4cbdd169980 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -204,7 +204,7 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) /* Re-tag IDs for update if it was tagged before the relations * update tag. */ for (IDNode *id_node : graph->id_nodes) { - ID *id = id_node->id_orig; + ID *id_orig = id_node->id_orig; id_node->finalize_build(graph); int flag = 0; /* Tag rebuild if special evaluation flags changed. */ @@ -219,10 +219,13 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) flag |= ID_RECALC_COPY_ON_WRITE; /* This means ID is being added to the dependency graph first * time, which is similar to "ob-visible-change" */ - if (GS(id->name) == ID_OB) { + if (GS(id_orig->name) == ID_OB) { flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY; } } + /* Restore recalc flags from original ID, which could possibly contain recalc flags set by + * an operator and then were carried on by the undo system. */ + flag |= id_orig->recalc; if (flag != 0) { graph_id_tag_update(bmain, graph, id_node->id_orig, flag, DEG_UPDATE_SOURCE_RELATIONS); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index fa6d7bc6028..986f65df3fc 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -623,7 +623,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, is_parent_collection_visible_ = is_current_parent_collection_visible; add_operation_node(&object->id, NodeType::DUPLI, OperationCode::DUPLI); } - /* Syncronization back to original object. */ + /* Synchronization back to original object. */ add_operation_node(&object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL, @@ -1557,7 +1557,7 @@ void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip) add_operation_node(clip_id, NodeType::PARAMETERS, OperationCode::MOVIECLIP_EVAL, - function_bind(BKE_movieclip_eval_update, _1, clip_cow)); + function_bind(BKE_movieclip_eval_update, _1, bmain_, clip_cow)); add_operation_node(clip_id, NodeType::BATCH_CACHE, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 86cbb330170..0e608bdf903 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -677,7 +677,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) } /* Point caches. */ build_object_pointcache(object); - /* Syncronization back to original object. */ + /* Synchronization back to original object. */ OperationKey synchronize_key( &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); add_relation(final_transform_key, synchronize_key, "Synchronize to Original"); @@ -695,7 +695,7 @@ void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object) OperationKey object_flags_key( &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_BASE_FLAGS); add_relation(view_layer_done_key, object_flags_key, "Base flags flush"); - /* Syncronization back to original object. */ + /* Synchronization back to original object. */ OperationKey synchronize_key( &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); add_relation(object_flags_key, synchronize_key, "Synchronize to Original"); @@ -1321,7 +1321,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) void DepsgraphRelationBuilder::build_animation_images(ID *id) { - /* TODO: can we check for existance of node for performance? */ + /* TODO: can we check for existence of node for performance? */ if (BKE_image_user_id_has_animation(id)) { OperationKey image_animation_key(id, NodeType::ANIMATION, OperationCode::IMAGE_ANIMATION); TimeSourceKey time_src_key; @@ -1999,7 +1999,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) } } } - /* Syncronization back to original object. */ + /* Synchronization back to original object. */ ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY); OperationKey synchronize_key( &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); @@ -2536,7 +2536,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) * copied by copy-on-write, and not preserved. PROBABLY it is better * to preserve that cache in copy-on-write, but for the time being * we allow flush to layer collections component which will ensure - * that cached array fo bases exists and is up-to-date. */ + * that cached array of bases exists and is up-to-date. */ if (comp_node->type == NodeType::PARAMETERS || comp_node->type == NodeType::LAYER_COLLECTIONS) { rel_flag &= ~RELATION_FLAG_NO_FLUSH; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 5bb3ebf40c4..be494104522 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -279,7 +279,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, } else if (RNA_struct_is_a(ptr->type, &RNA_Mesh) || RNA_struct_is_a(ptr->type, &RNA_Modifier) || RNA_struct_is_a(ptr->type, &RNA_GpencilModifier) || - RNA_struct_is_a(ptr->type, &RNA_Spline) || RNA_struct_is_a(ptr->type, &RNA_TextBox)) { + RNA_struct_is_a(ptr->type, &RNA_Spline) || RNA_struct_is_a(ptr->type, &RNA_TextBox) || + RNA_struct_is_a(ptr->type, &RNA_GPencilLayer)) { /* When modifier is used as FROM operation this is likely referencing to * the property (for example, modifier's influence). * But when it's used as TO operation, this is geometry component. */ diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index d8a9b41206b..6d3aed65a14 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -68,6 +68,7 @@ template<typename T> static void remove_from_vector(vector<T> *vector, const T & Depsgraph::Depsgraph(Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) : time_source(NULL), need_update(true), + need_update_time(false), scene(scene), view_layer(view_layer), mode(mode), diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index f194a44346b..15ce57cb169 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -73,7 +73,7 @@ enum RelationFlag { RELATION_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2), /* The relation can not be killed by the cyclic dependencies solver. */ RELATION_FLAG_GODMODE = (1 << 4), - /* Relation will check existance before being added. */ + /* Relation will check existence before being added. */ RELATION_CHECK_BEFORE_ADD = (1 << 5), }; @@ -160,6 +160,10 @@ struct Depsgraph { /* Nodes which have been tagged as "directly modified". */ GSet *entry_tags; + /* Special entry tag for time source. Allows to tag invisible dependency graphs for update when + * scene frame changes, so then when dependency graph becomes visible it is on a proper state. */ + bool need_update_time; + /* Convenience Data ................... */ /* XXX: should be collected after building (if actually needed?) */ diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 6f3262174b4..55241d03e94 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -61,6 +61,7 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); } DEG::deg_evaluate_on_refresh(deg_graph); + deg_graph->need_update_time = false; } /* Frame-change happened for root scene that graph belongs to. */ @@ -79,10 +80,11 @@ void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime) } /* Perform recalculation updates. */ DEG::deg_evaluate_on_refresh(deg_graph); + deg_graph->need_update_time = false; } bool DEG_needs_eval(Depsgraph *graph) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - return BLI_gset_len(deg_graph->entry_tags) != 0; + return BLI_gset_len(deg_graph->entry_tags) != 0 || deg_graph->need_update_time; } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 583191490d2..392514990e3 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -229,6 +229,12 @@ void depsgraph_tag_to_component_opcode(const ID *id, case ID_RECALC_PARAMETERS: *component_type = NodeType::PARAMETERS; break; + case ID_RECALC_SOURCE: + *component_type = NodeType::PARAMETERS; + break; + case ID_RECALC_TIME: + BLI_assert(!"Should be handled outside of this function"); + break; case ID_RECALC_ALL: case ID_RECALC_PSYS_ALL: BLI_assert(!"Should not happen"); @@ -319,25 +325,31 @@ void deg_graph_id_tag_legacy_compat( * tagging here. */ case ID_ME: { Mesh *mesh = (Mesh *)id; - ID *key_id = &mesh->key->id; - if (key_id != NULL) { - graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + if (mesh->key != NULL) { + ID *key_id = &mesh->key->id; + if (key_id != NULL) { + graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + } } break; } case ID_LT: { Lattice *lattice = (Lattice *)id; - ID *key_id = &lattice->key->id; - if (key_id != NULL) { - graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + if (lattice->key != NULL) { + ID *key_id = &lattice->key->id; + if (key_id != NULL) { + graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + } } break; } case ID_CU: { Curve *curve = (Curve *)id; - ID *key_id = &curve->key->id; - if (key_id != NULL) { - graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + if (curve->key != NULL) { + ID *key_id = &curve->key->id; + if (key_id != NULL) { + graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source); + } } break; } @@ -360,6 +372,12 @@ static void graph_id_tag_update_single_flag(Main *bmain, } return; } + else if (tag == ID_RECALC_TIME) { + if (graph != NULL) { + graph->need_update_time = true; + } + return; + } /* Get description of what is to be tagged. */ NodeType component_type; OperationCode operation_code; @@ -438,6 +456,24 @@ const char *update_source_as_string(eUpdateSource source) return "UNKNOWN"; } +int deg_recalc_flags_for_legacy_zero() +{ + return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE); +} + +int deg_recalc_flags_effective(Depsgraph *graph, int flags) +{ + if (graph != NULL) { + if (!graph->is_active) { + return 0; + } + } + if (flags == 0) { + return deg_recalc_flags_for_legacy_zero(); + } + return flags; +} + /* Special tag function which tags all components which needs to be tagged * for update flag=0. * @@ -453,7 +489,7 @@ void deg_graph_node_tag_zero(Main *bmain, } ID *id = id_node->id_orig; /* TODO(sergey): Which recalc flags to set here? */ - id_node->id_cow->recalc |= ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION); + id_node->id_cow->recalc |= deg_recalc_flags_for_legacy_zero(); GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { if (comp_node->type == NodeType::ANIMATION) { continue; @@ -598,6 +634,16 @@ void graph_id_tag_update( if (id_node != NULL) { id_node->id_cow->recalc |= flag; } + /* When ID is tagged for update based on an user edits store the recalc flags in the original ID. + * This way IDs in the undo steps will have this flag preserved, making it possible to restore + * all needed tags when new dependency graph is created on redo. + * This is the only way to ensure modifications to animation data (such as keyframes i.e.) + * properly triggers animation update for the newely constructed dependency graph on redo (while + * usually newly created dependency graph skips animation update to avoid loss of unkeyed + * changes). */ + if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) { + id->recalc |= deg_recalc_flags_effective(graph, flag); + } int current_flag = flag; while (current_flag != 0) { IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(¤t_flag)); @@ -664,6 +710,10 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag) return "AUDIO"; case ID_RECALC_PARAMETERS: return "PARAMETERS"; + case ID_RECALC_TIME: + return "TIME"; + case ID_RECALC_SOURCE: + return "SOURCE"; case ID_RECALC_ALL: return "ALL"; } @@ -768,9 +818,19 @@ void DEG_ids_check_recalc( DEG::deg_editors_scene_update(&update_ctx, updated); } +static void deg_graph_clear_id_recalc_flags(ID *id) +{ + id->recalc &= ~ID_RECALC_ALL; + bNodeTree *ntree = ntreeFromID(id); + /* Clear embedded node trees too. */ + if (ntree) { + ntree->id.recalc &= ~ID_RECALC_ALL; + } +} + static void deg_graph_clear_id_node_func(void *__restrict data_v, const int i, - const ParallelRangeTLS *__restrict /*tls*/) + const TaskParallelTLS *__restrict /*tls*/) { /* TODO: we clear original ID recalc flags here, but this may not work * correctly when there are multiple depsgraph with others still using @@ -779,12 +839,10 @@ static void deg_graph_clear_id_node_func(void *__restrict data_v, DEG::IDNode *id_node = deg_graph->id_nodes[i]; id_node->is_user_modified = false; - id_node->id_cow->recalc &= ~ID_RECALC_ALL; - /* Clear embedded node trees too. */ - bNodeTree *ntree_cow = ntreeFromID(id_node->id_cow); - if (ntree_cow) { - ntree_cow->id.recalc &= ~ID_RECALC_ALL; + deg_graph_clear_id_recalc_flags(id_node->id_cow); + if (deg_graph->is_active) { + deg_graph_clear_id_recalc_flags(id_node->id_orig); } } @@ -798,7 +856,7 @@ void DEG_ids_clear_recalc(Main *UNUSED(bmain), Depsgraph *depsgraph) } /* Go over all ID nodes nodes, clearing tags. */ const int num_id_nodes = deg_graph->id_nodes.size(); - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 1024; BLI_task_parallel_range(0, num_id_nodes, deg_graph, deg_graph_clear_id_node_func, &settings); diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 950deee2b07..b2415c9e89d 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -108,7 +108,7 @@ static bool check_operation_node_visible(OperationNode *op_node) static void calculate_pending_func(void *__restrict data_v, const int i, - const ParallelRangeTLS *__restrict /*tls*/) + const TaskParallelTLS *__restrict /*tls*/) { CalculatePendingData *data = (CalculatePendingData *)data_v; Depsgraph *graph = data->graph; @@ -148,7 +148,7 @@ static void calculate_pending_parents(Depsgraph *graph) const int num_operations = graph->operations.size(); CalculatePendingData data; data.graph = graph; - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 1024; BLI_task_parallel_range(0, num_operations, &data, calculate_pending_func, &settings); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 83fcf4c6ea1..2479373b687 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -29,16 +29,18 @@ #include <deque> #include <cmath> -#include "BKE_object.h" - #include "BLI_utildefines.h" #include "BLI_listbase.h" #include "BLI_math_vector.h" #include "BLI_task.h" #include "BLI_ghash.h" +#include "BKE_object.h" +#include "BKE_scene.h" + extern "C" { #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DRW_engine.h" } /* extern "C" */ @@ -53,6 +55,7 @@ extern "C" { #include "intern/node/deg_node_factory.h" #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" +#include "intern/node/deg_node_time.h" #include "intern/eval/deg_eval_copy_on_write.h" @@ -86,7 +89,7 @@ namespace { void flush_init_operation_node_func(void *__restrict data_v, const int i, - const ParallelRangeTLS *__restrict /*tls*/) + const TaskParallelTLS *__restrict /*tls*/) { Depsgraph *graph = (Depsgraph *)data_v; OperationNode *node = graph->operations[i]; @@ -95,7 +98,7 @@ void flush_init_operation_node_func(void *__restrict data_v, void flush_init_id_node_func(void *__restrict data_v, const int i, - const ParallelRangeTLS *__restrict /*tls*/) + const TaskParallelTLS *__restrict /*tls*/) { Depsgraph *graph = (Depsgraph *)data_v; IDNode *id_node = graph->id_nodes[i]; @@ -109,14 +112,14 @@ BLI_INLINE void flush_prepare(Depsgraph *graph) { { const int num_operations = graph->operations.size(); - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 1024; BLI_task_parallel_range(0, num_operations, graph, flush_init_operation_node_func, &settings); } { const int num_id_nodes = graph->id_nodes.size(); - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 1024; BLI_task_parallel_range(0, num_id_nodes, graph, flush_init_id_node_func, &settings); @@ -348,9 +351,16 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) BLI_assert(bmain != NULL); BLI_assert(graph != NULL); /* Nothing to update, early out. */ - if (BLI_gset_len(graph->entry_tags) == 0) { + if (BLI_gset_len(graph->entry_tags) == 0 && !graph->need_update_time) { return; } + if (graph->need_update_time) { + const Scene *scene_orig = graph->scene; + const float ctime = BKE_scene_frame_get(scene_orig); + DEG::TimeSourceNode *time_source = graph->find_time_source(); + graph->ctime = ctime; + time_source->tag_update(graph, DEG::DEG_UPDATE_SOURCE_TIME); + } /* Reset all flags, get ready for the flush. */ flush_prepare(graph); /* Starting from the tagged "entry" nodes, flush outwards. */ @@ -387,7 +397,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) static void graph_clear_operation_func(void *__restrict data_v, const int i, - const ParallelRangeTLS *__restrict /*tls*/) + const TaskParallelTLS *__restrict /*tls*/) { Depsgraph *graph = (Depsgraph *)data_v; OperationNode *node = graph->operations[i]; @@ -402,7 +412,7 @@ void deg_graph_clear_tags(Depsgraph *graph) /* Go over all operation nodes, clearing tags. */ { const int num_operations = graph->operations.size(); - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.min_iter_per_thread = 1024; BLI_task_parallel_range(0, num_operations, graph, graph_clear_operation_func, &settings); diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 8dd01050753..e14513a1aa2 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -58,7 +58,7 @@ const char *linkedStateAsString(eDepsNode_LinkedState_Type linked_state) return "DIRECTLY"; } BLI_assert(!"Unhandled linked state, should never happen."); - return "UNKNOW"; + return "UNKNOWN"; } IDNode::ComponentIDKey::ComponentIDKey(NodeType type, const char *name) : type(type), name(name) |