diff options
Diffstat (limited to 'source/blender/depsgraph')
38 files changed, 310 insertions, 479 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index c94a8876ab0..d735d3b89bc 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -184,7 +184,7 @@ void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func, DEG_EditorUpdateSce /* Evaluation ----------------------------------- */ -bool DEG_is_evaluating(struct Depsgraph *depsgraph); +bool DEG_is_evaluating(const struct Depsgraph *depsgraph); bool DEG_is_active(const struct Depsgraph *depsgraph); void DEG_make_active(struct Depsgraph *depsgraph); diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 26b46376a0a..3d570536223 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -111,14 +111,14 @@ struct ID *DEG_get_original_id(struct ID *id); * * Original IDs are considered all the IDs which are not covered by copy-on-write system and are * not out-of-main localized data-blocks. */ -bool DEG_is_original_id(struct ID *id); -bool DEG_is_original_object(struct Object *object); +bool DEG_is_original_id(const struct ID *id); +bool DEG_is_original_object(const struct Object *object); /* Opposite of the above. * * If the data-block is not original it must be evaluated, and vice versa. */ -bool DEG_is_evaluated_id(struct ID *id); -bool DEG_is_evaluated_object(struct Object *object); +bool DEG_is_evaluated_id(const struct ID *id); +bool DEG_is_evaluated_object(const struct Object *object); /* Check whether depsgraph os fully evaluated. This includes the following checks: * - Relations are up-to-date. diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index d880618753c..82f3ea7d182 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -31,7 +31,6 @@ #include "DNA_layer_types.h" #include "DNA_object_types.h" -#include "BLI_ghash.h" #include "BLI_stack.h" #include "BLI_utildefines.h" @@ -157,10 +156,9 @@ void deg_graph_build_flush_visibility(Depsgraph *graph) BLI_Stack *stack = BLI_stack_new(sizeof(OperationNode *), "DEG flush layers stack"); for (IDNode *id_node : graph->id_nodes) { - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (ComponentNode *comp_node : id_node->components.values()) { comp_node->affects_directly_visible |= id_node->is_directly_visible; } - GHASH_FOREACH_END(); } for (OperationNode *op_node : graph->operations) { op_node->custom_flags = 0; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index f6834feeeae..10307df0dc4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -60,6 +60,7 @@ extern "C" { #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_simulation_types.h" #include "DNA_sound_types.h" #include "DNA_speaker_types.h" #include "DNA_texture_types.h" @@ -74,7 +75,7 @@ extern "C" { #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_effect.h" -#include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_gpencil.h" #include "BKE_gpencil_modifier.h" #include "BKE_idprop.h" @@ -120,20 +121,6 @@ extern "C" { namespace DEG { -namespace { - -void free_copy_on_write_datablock(void *id_info_v) -{ - DepsgraphNodeBuilder::IDInfo *id_info = (DepsgraphNodeBuilder::IDInfo *)id_info_v; - if (id_info->id_cow != nullptr) { - deg_free_copy_on_write_datablock(id_info->id_cow); - MEM_freeN(id_info->id_cow); - } - MEM_freeN(id_info); -} - -} /* namespace */ - /* ************ */ /* Node Builder */ @@ -147,15 +134,18 @@ DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain, view_layer_(nullptr), view_layer_index_(-1), collection_(nullptr), - is_parent_collection_visible_(true), - id_info_hash_(nullptr) + is_parent_collection_visible_(true) { } DepsgraphNodeBuilder::~DepsgraphNodeBuilder() { - if (id_info_hash_ != nullptr) { - BLI_ghash_free(id_info_hash_, nullptr, free_copy_on_write_datablock); + for (IDInfo *id_info : id_info_hash_.values()) { + if (id_info->id_cow != nullptr) { + deg_free_copy_on_write_datablock(id_info->id_cow); + MEM_freeN(id_info->id_cow); + } + MEM_freeN(id_info); } } @@ -166,7 +156,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id) IDComponentsMask previously_visible_components_mask = 0; uint32_t previous_eval_flags = 0; DEGCustomDataMeshMasks previous_customdata_masks; - IDInfo *id_info = (IDInfo *)BLI_ghash_lookup(id_info_hash_, id); + IDInfo *id_info = id_info_hash_.lookup_default(id, nullptr); if (id_info != nullptr) { id_cow = id_info->id_cow; previously_visible_components_mask = id_info->previously_visible_components_mask; @@ -182,7 +172,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id) /* Currently all ID nodes are supposed to have copy-on-write logic. * * NOTE: Zero number of components indicates that ID node was just created. */ - if (BLI_ghash_len(id_node->components) == 0) { + if (id_node->components.is_empty()) { ComponentNode *comp_cow = id_node->add_component(NodeType::COPY_ON_WRITE); OperationNode *op_cow = comp_cow->add_operation( function_bind(deg_evaluate_copy_on_write, _1, id_node), @@ -320,7 +310,6 @@ void DepsgraphNodeBuilder::begin_build() { /* Store existing copy-on-write versions of datablock, so we can re-use * them for new ID nodes. */ - id_info_hash_ = BLI_ghash_ptr_new("Depsgraph id hash"); for (IDNode *id_node : graph_->id_nodes) { /* It is possible that the ID does not need to have CoW version in which case id_cow is the * same as id_orig. Additionally, such ID might have been removed, which makes the check @@ -344,11 +333,11 @@ void DepsgraphNodeBuilder::begin_build() id_info->previously_visible_components_mask = id_node->visible_components_mask; id_info->previous_eval_flags = id_node->eval_flags; id_info->previous_customdata_masks = id_node->customdata_masks; - BLI_ghash_insert(id_info_hash_, id_node->id_orig, id_info); + id_info_hash_.add_new(id_node->id_orig, id_info); id_node->id_cow = nullptr; } - GSET_FOREACH_BEGIN (OperationNode *, op_node, graph_->entry_tags) { + for (OperationNode *op_node : graph_->entry_tags) { ComponentNode *comp_node = op_node->owner; IDNode *id_node = comp_node->owner; @@ -360,12 +349,11 @@ void DepsgraphNodeBuilder::begin_build() entry_tag.name_tag = op_node->name_tag; saved_entry_tags_.push_back(entry_tag); } - GSET_FOREACH_END(); /* Make sure graph has no nodes left from previous state. */ graph_->clear_all_nodes(); graph_->operations.clear(); - BLI_gset_clear(graph_->entry_tags, nullptr); + graph_->entry_tags.clear(); } void DepsgraphNodeBuilder::end_build() @@ -482,6 +470,9 @@ void DepsgraphNodeBuilder::build_id(ID *id) case ID_SCE: build_scene_parameters((Scene *)id); break; + case ID_SIM: + build_simulation((Simulation *)id); + break; default: fprintf(stderr, "Unhandled ID %s\n", id->name); BLI_assert(!"Should never happen"); @@ -519,8 +510,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti } else if (from_layer_collection == nullptr && !id_node->is_collection_fully_expanded) { /* Initially collection was built from layer now, and was requested - * to not recurs into object. But nw it's asked to recurs into all - * objects. */ + * to not recurs into object. But now it's asked to recurs into all objects. */ } else { return; @@ -1757,6 +1747,16 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound) build_parameters(&sound->id); } +void DepsgraphNodeBuilder::build_simulation(Simulation *simulation) +{ + if (built_map_.checkIsBuiltAndTag(simulation)) { + return; + } + add_id_node(&simulation->id); + build_animdata(&simulation->id); + build_parameters(&simulation->id); +} + void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene) { if (scene->ed == nullptr) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 16beedabc2a..5cd7f7449a2 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -37,7 +37,6 @@ struct Collection; struct FCurve; struct FreestyleLineSet; struct FreestyleLineStyle; -struct GHash; struct ID; struct IDProperty; struct Image; @@ -53,6 +52,7 @@ struct MovieClip; struct Object; struct ParticleSettings; struct Scene; +struct Simulation; struct Speaker; struct Tex; struct World; @@ -221,6 +221,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_lightprobe(LightProbe *probe); virtual void build_speaker(Speaker *speaker); virtual void build_sound(bSound *sound); + virtual void build_simulation(Simulation *simulation); virtual void build_scene_sequencer(Scene *scene); virtual void build_scene_audio(Scene *scene); virtual void build_scene_speakers(Scene *scene, ViewLayer *view_layer); @@ -279,7 +280,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { bool is_parent_collection_visible_; /* Indexed by original ID, values are IDInfo. */ - GHash *id_info_hash_; + Map<const ID *, IDInfo *> id_info_hash_; /* Set of IDs which were already build. Makes it easier to keep track of * what was already built and what was not. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc index ecacfcf7ee9..a0179181866 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc @@ -26,104 +26,55 @@ #include <stdio.h> #include <string.h> -#include "BLI_ghash.h" #include "BLI_utildefines.h" namespace DEG { -static void free_rootpchanmap_valueset(void *val) -{ - /* Just need to free the set itself - the names stored are all references. */ - GSet *values = (GSet *)val; - BLI_gset_free(values, nullptr); -} - RootPChanMap::RootPChanMap() { - /* Just create empty map. */ - map_ = BLI_ghash_str_new("RootPChanMap"); } RootPChanMap::~RootPChanMap() { - /* Free the map, and all the value sets. */ - BLI_ghash_free(map_, nullptr, free_rootpchanmap_valueset); } /* Debug contents of map */ void RootPChanMap::print_debug() { - GHashIterator it1; - GSetIterator it2; - - printf("Root PChan Map:\n"); - GHASH_ITER (it1, map_) { - const char *item = (const char *)BLI_ghashIterator_getKey(&it1); - GSet *values = (GSet *)BLI_ghashIterator_getValue(&it1); - - printf(" %s : { ", item); - GSET_ITER (it2, values) { - const char *val = (const char *)BLI_gsetIterator_getKey(&it2); - printf("%s, ", val); + map_.foreach_item([](StringRefNull key, const Set<StringRefNull> &values) { + printf(" %s : { ", key.data()); + for (StringRefNull val : values) { + printf("%s, ", val.data()); } printf("}\n"); - } + }); } /* Add a mapping. */ void RootPChanMap::add_bone(const char *bone, const char *root) { - if (BLI_ghash_haskey(map_, bone)) { - /* Add new entry, but only add the root if it doesn't already - * exist in there. */ - GSet *values = (GSet *)BLI_ghash_lookup(map_, bone); - BLI_gset_add(values, (void *)root); - } - else { - /* Create new set and mapping. */ - GSet *values = BLI_gset_new( - BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "RootPChanMap Value Set"); - BLI_ghash_insert(map_, (void *)bone, (void *)values); - - /* Add new entry now. */ - BLI_gset_insert(values, (void *)root); - } + map_.lookup_or_add_default(bone).add(root); } /* Check if there's a common root bone between two bones. */ bool RootPChanMap::has_common_root(const char *bone1, const char *bone2) const { - /* Ensure that both are in the map... */ - if (BLI_ghash_haskey(map_, bone1) == false) { + const Set<StringRefNull> *bone1_roots = map_.lookup_ptr(bone1); + const Set<StringRefNull> *bone2_roots = map_.lookup_ptr(bone2); + + if (bone1_roots == nullptr) { // fprintf("RootPChanMap: bone1 '%s' not found (%s => %s)\n", bone1, bone1, bone2); // print_debug(); return false; } - if (BLI_ghash_haskey(map_, bone2) == false) { + if (bone2_roots == nullptr) { // fprintf("RootPChanMap: bone2 '%s' not found (%s => %s)\n", bone2, bone1, bone2); // print_debug(); return false; } - GSet *bone1_roots = (GSet *)BLI_ghash_lookup(map_, (void *)bone1); - GSet *bone2_roots = (GSet *)BLI_ghash_lookup(map_, (void *)bone2); - - GSetIterator it1, it2; - GSET_ITER (it1, bone1_roots) { - GSET_ITER (it2, bone2_roots) { - const char *v1 = (const char *)BLI_gsetIterator_getKey(&it1); - const char *v2 = (const char *)BLI_gsetIterator_getKey(&it2); - - if (strcmp(v1, v2) == 0) { - // fprintf("RootPchanMap: %s in common for %s => %s\n", v1, bone1, bone2); - return true; - } - } - } - - // fprintf("RootPChanMap: No common root found (%s => %s)\n", bone1, bone2); - return false; + return Set<StringRefNull>::Intersects(*bone1_roots, *bone2_roots); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h index 1442f547b08..c3c90e5aae4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h @@ -23,7 +23,7 @@ #pragma once -struct GHash; +#include "intern/depsgraph_type.h" namespace DEG { @@ -42,13 +42,11 @@ struct RootPChanMap { bool has_common_root(const char *bone1, const char *bone2) const; protected: - /* The actual map: - * - Keys are "strings" (const char *) - not dynamically allocated. - * - Values are "sets" (const char *) - not dynamically allocated. - * - * We don't use the C++ maps here, as it's more convenient to use - * Blender's GHash and be able to compare by-value instead of by-ref. */ - struct GHash *map_; + /** + * The strings are only referenced by this map. Users of RootPChanMap have to make sure that the + * life-time of the strings is long enough. + */ + Map<StringRefNull, Set<StringRefNull>> map_; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 552546ff094..7a1df5bcb27 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -28,7 +28,6 @@ #include <cstring> /* required for STREQ later on. */ #include <stdio.h> #include <stdlib.h> -#include <unordered_set> #include "MEM_guardedalloc.h" @@ -62,6 +61,7 @@ extern "C" { #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_simulation_types.h" #include "DNA_sound_types.h" #include "DNA_speaker_types.h" #include "DNA_texture_types.h" @@ -76,7 +76,7 @@ extern "C" { #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_effect.h" -#include "BKE_fcurve.h" +#include "BKE_fcurve_driver.h" #include "BKE_gpencil_modifier.h" #include "BKE_idprop.h" #include "BKE_image.h" @@ -122,8 +122,6 @@ extern "C" { namespace DEG { -using std::unordered_set; - /* ***************** */ /* Relations Builder */ @@ -559,6 +557,9 @@ void DepsgraphRelationBuilder::build_id(ID *id) case ID_SCE: build_scene_parameters((Scene *)id); break; + case ID_SIM: + build_simulation((Simulation *)id); + break; default: fprintf(stderr, "Unhandled ID %s\n", id->name); BLI_assert(!"Should never happen"); @@ -2399,22 +2400,28 @@ void DepsgraphRelationBuilder::build_texture(Tex *texture) return; } /* texture itself */ + ComponentKey texture_key(&texture->id, NodeType::GENERIC_DATABLOCK); build_idproperties(texture->id.properties); build_animdata(&texture->id); build_parameters(&texture->id); + /* texture's nodetree */ build_nodetree(texture->nodetree); + build_nested_nodetree(&texture->id, texture->nodetree); + /* Special cases for different IDs which texture uses. */ if (texture->type == TEX_IMAGE) { if (texture->ima != nullptr) { build_image(texture->ima); + + ComponentKey image_key(&texture->ima->id, NodeType::GENERIC_DATABLOCK); + add_relation(image_key, texture_key, "Texture Image"); } } - build_nested_nodetree(&texture->id, texture->nodetree); + if (check_id_has_anim_component(&texture->id)) { ComponentKey animation_key(&texture->id, NodeType::ANIMATION); - ComponentKey datablock_key(&texture->id, NodeType::GENERIC_DATABLOCK); - add_relation(animation_key, datablock_key, "Datablock Animation"); + add_relation(animation_key, texture_key, "Datablock Animation"); } } @@ -2565,6 +2572,15 @@ void DepsgraphRelationBuilder::build_sound(bSound *sound) build_parameters(&sound->id); } +void DepsgraphRelationBuilder::build_simulation(Simulation *simulation) +{ + if (built_map_.checkIsBuiltAndTag(simulation)) { + return; + } + build_animdata(&simulation->id); + build_parameters(&simulation->id); +} + void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene) { if (scene->ed == nullptr) { @@ -2680,7 +2696,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) Node *node_cow = find_node(copy_on_write_key); OperationNode *op_cow = node_cow->get_exit_operation(); /* Plug any other components to this one. */ - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (ComponentNode *comp_node : id_node->components.values()) { if (comp_node->type == NodeType::COPY_ON_WRITE) { /* Copy-on-write component never depends on itself. */ continue; @@ -2723,11 +2739,11 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) rel->flag |= rel_flag; } /* All dangling operations should also be executed after copy-on-write. */ - GHASH_FOREACH_BEGIN (OperationNode *, op_node, comp_node->operations_map) { + for (OperationNode *op_node : comp_node->operations_map->values()) { if (op_node == op_entry) { continue; } - if (op_node->inlinks.size() == 0) { + if (op_node->inlinks.is_empty()) { Relation *rel = graph_->add_new_relation(op_cow, op_node, "CoW Dependency"); rel->flag |= rel_flag; } @@ -2749,7 +2765,6 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) } } } - GHASH_FOREACH_END(); /* NOTE: We currently ignore implicit relations to an external * data-blocks for copy-on-write operations. This means, for example, * copy-on-write component of Object will not wait for copy-on-write @@ -2758,7 +2773,6 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) * evaluation step needs geometry, it will have transitive dependency * to Mesh copy-on-write already. */ } - GHASH_FOREACH_END(); /* TODO(sergey): This solves crash for now, but causes too many * updates potentially. */ if (GS(id_orig->name) == ID_OB) { @@ -2807,7 +2821,7 @@ static bool is_reachable(const Node *const from, const Node *const to) // Perform a graph walk from 'to' towards its incoming connections. // Walking from 'from' towards its outgoing connections is 10x slower on the Spring rig. deque<const Node *> queue; - unordered_set<const Node *> seen; + Set<const Node *> seen; queue.push_back(to); while (!queue.empty()) { // Visit the next node to inspect. @@ -2821,7 +2835,7 @@ static bool is_reachable(const Node *const from, const Node *const to) // Queue all incoming relations that we haven't seen before. for (Relation *relation : visit->inlinks) { const Node *prev_node = relation->from; - if (seen.insert(prev_node).second) { + if (seen.add(prev_node)) { queue.push_back(prev_node); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 3c9bd8a9856..aa6d8ababd3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -69,6 +69,7 @@ struct Object; struct ParticleSettings; struct ParticleSystem; struct Scene; +struct Simulation; struct Speaker; struct Tex; struct ViewLayer; @@ -286,6 +287,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_lightprobe(LightProbe *probe); virtual void build_speaker(Speaker *speaker); virtual void build_sound(bSound *sound); + virtual void build_simulation(Simulation *simulation); virtual void build_scene_sequencer(Scene *scene); virtual void build_scene_audio(Scene *scene); virtual void build_scene_speakers(Scene *scene, ViewLayer *view_layer); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index ff2bc2ac3ea..b75252aa325 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -69,7 +69,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object, RootPChanMap *root_map) { if ((con->flag & CONSTRAINT_DISABLE) != 0) { - /* Do not add disabled IK constraints to the relations. If these needs to be temporarly + /* Do not add disabled IK constraints to the relations. If these needs to be temporarily * enabled, they will be added as temporary constraints during transform. */ return; } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc index 2ce1f1f1c1d..c6545362bb1 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc @@ -43,7 +43,7 @@ static inline bool is_unused_noop(OperationNode *op_node) if (op_node->flag & OperationFlag::DEPSOP_FLAG_PINNED) { return false; } - return op_node->is_noop() && op_node->outlinks.empty(); + return op_node->is_noop() && op_node->outlinks.is_empty(); } void deg_graph_remove_unused_noops(Depsgraph *graph) @@ -61,7 +61,7 @@ void deg_graph_remove_unused_noops(Depsgraph *graph) OperationNode *to_remove = queue.front(); queue.pop_front(); - while (!to_remove->inlinks.empty()) { + while (!to_remove->inlinks.is_empty()) { Relation *rel_in = to_remove->inlinks[0]; Node *dependency = rel_in->from; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 73f6730be03..a35b69df60d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -27,7 +27,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" @@ -57,37 +56,33 @@ namespace DEG { class RNANodeQueryIDData { public: - explicit RNANodeQueryIDData(const ID *id) : id_(id), contraint_to_pchan_map_(nullptr) + explicit RNANodeQueryIDData(const ID *id) : id_(id), constraint_to_pchan_map_(nullptr) { } ~RNANodeQueryIDData() { - if (contraint_to_pchan_map_ != nullptr) { - BLI_ghash_free(contraint_to_pchan_map_, nullptr, nullptr); - } + delete constraint_to_pchan_map_; } const bPoseChannel *get_pchan_for_constraint(const bConstraint *constraint) { ensure_constraint_to_pchan_map(); - return static_cast<bPoseChannel *>(BLI_ghash_lookup(contraint_to_pchan_map_, constraint)); + return constraint_to_pchan_map_->lookup_default(constraint, nullptr); } void ensure_constraint_to_pchan_map() { - if (contraint_to_pchan_map_ != nullptr) { + if (constraint_to_pchan_map_ != nullptr) { return; } BLI_assert(GS(id_->name) == ID_OB); const Object *object = reinterpret_cast<const Object *>(id_); - contraint_to_pchan_map_ = BLI_ghash_ptr_new("id data pchan constraint map"); + constraint_to_pchan_map_ = new Map<const bConstraint *, const bPoseChannel *>(); if (object->pose != nullptr) { LISTBASE_FOREACH (const bPoseChannel *, pchan, &object->pose->chanbase) { LISTBASE_FOREACH (const bConstraint *, constraint, &pchan->constraints) { - BLI_ghash_insert(contraint_to_pchan_map_, - const_cast<bConstraint *>(constraint), - const_cast<bPoseChannel *>(pchan)); + constraint_to_pchan_map_->add_new(constraint, pchan); } } } @@ -99,7 +94,7 @@ class RNANodeQueryIDData { /* indexed by bConstraint*, returns pose channel which contains that * constraint. */ - GHash *contraint_to_pchan_map_; + Map<const bConstraint *, const bPoseChannel *> *constraint_to_pchan_map_; }; /* ***************************** Node Identifier **************************** */ @@ -121,26 +116,13 @@ bool RNANodeIdentifier::is_valid() const /* ********************************** Query ********************************* */ -namespace { - -void ghash_id_data_free_func(void *value) -{ - RNANodeQueryIDData *id_data = static_cast<RNANodeQueryIDData *>(value); - OBJECT_GUARDED_DELETE(id_data, RNANodeQueryIDData); -} - -} // namespace - RNANodeQuery::RNANodeQuery(Depsgraph *depsgraph, DepsgraphBuilder *builder) - : depsgraph_(depsgraph), - builder_(builder), - id_data_map_(BLI_ghash_ptr_new("rna node query id data hash")) + : depsgraph_(depsgraph), builder_(builder) { } RNANodeQuery::~RNANodeQuery() { - BLI_ghash_free(id_data_map_, nullptr, ghash_id_data_free_func); } Node *RNANodeQuery::find_node(const PointerRNA *ptr, @@ -384,12 +366,9 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNANodeQueryIDData *RNANodeQuery::ensure_id_data(const ID *id) { - RNANodeQueryIDData **id_data_ptr; - if (!BLI_ghash_ensure_p( - id_data_map_, const_cast<ID *>(id), reinterpret_cast<void ***>(&id_data_ptr))) { - *id_data_ptr = OBJECT_GUARDED_NEW(RNANodeQueryIDData, id); - } - return *id_data_ptr; + unique_ptr<RNANodeQueryIDData> &id_data = id_data_map_.lookup_or_add( + id, [&]() { return BLI::make_unique<RNANodeQueryIDData>(id); }); + return id_data.get(); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h index 8a79d9abef9..bd806ce058a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h @@ -26,7 +26,6 @@ #include "intern/node/deg_node.h" #include "intern/node/deg_node_operation.h" -struct GHash; struct ID; struct PointerRNA; struct PropertyRNA; @@ -83,7 +82,7 @@ class RNANodeQuery { DepsgraphBuilder *builder_; /* Indexed by an ID, returns RNANodeQueryIDData associated with that ID. */ - GHash *id_data_map_; + Map<const ID *, unique_ptr<RNANodeQueryIDData>> id_data_map_; /* Construct identifier of the node which corresponds given configuration * of RNA property. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc index 3f828ef5bb0..22ceac899b8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc @@ -72,6 +72,8 @@ static void deg_graph_tag_paths_recursive(Node *node) void deg_graph_transitive_reduction(Depsgraph *graph) { int num_removed_relations = 0; + Vector<Relation *> relations_to_remove; + for (OperationNode *target : graph->operations) { /* Clear tags. */ for (OperationNode *node : graph->operations) { @@ -85,25 +87,24 @@ void deg_graph_transitive_reduction(Depsgraph *graph) deg_graph_tag_paths_recursive(rel->from); } /* Remove redundant paths to the target. */ - for (Node::Relations::const_iterator it_rel = target->inlinks.begin(); - it_rel != target->inlinks.end();) { - Relation *rel = *it_rel; + for (Relation *rel : target->inlinks) { if (rel->from->type == NodeType::TIMESOURCE) { /* HACK: time source nodes don't get "custom_flags" flag * set/cleared. */ /* TODO: there will be other types in future, so iterators above * need modifying. */ - ++it_rel; + continue; } else if (rel->from->custom_flags & OP_REACHABLE) { - rel->unlink(); - OBJECT_GUARDED_DELETE(rel, Relation); - num_removed_relations++; - } - else { - ++it_rel; + relations_to_remove.append(rel); } } + for (Relation *rel : relations_to_remove) { + rel->unlink(); + OBJECT_GUARDED_DELETE(rel, Relation); + } + num_removed_relations += relations_to_remove.size(); + relations_to_remove.clear(); } DEG_DEBUG_PRINTF((::Depsgraph *)graph, BUILD, "Removed %d relations\n", num_removed_relations); } diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc index 7080f8a1a9b..14a095fdb8e 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc @@ -25,7 +25,6 @@ #include <cstdarg> -#include "BLI_ghash.h" #include "BLI_utildefines.h" extern "C" { @@ -407,15 +406,14 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node) switch (node->type) { case NodeType::ID_REF: { const IDNode *id_node = (const IDNode *)node; - if (BLI_ghash_len(id_node->components) == 0) { + if (id_node->components.is_empty()) { deg_debug_graphviz_node_single(ctx, node); } else { deg_debug_graphviz_node_cluster_begin(ctx, node); - GHASH_FOREACH_BEGIN (const ComponentNode *, comp, id_node->components) { + for (const ComponentNode *comp : id_node->components.values()) { deg_debug_graphviz_node(ctx, comp); } - GHASH_FOREACH_END(); deg_debug_graphviz_node_cluster_end(ctx); } break; @@ -472,7 +470,7 @@ static bool deg_debug_graphviz_is_cluster(const Node *node) switch (node->type) { case NodeType::ID_REF: { const IDNode *id_node = (const IDNode *)node; - return BLI_ghash_len(id_node->components) > 0; + return !id_node->components.is_empty(); } case NodeType::PARAMETERS: case NodeType::ANIMATION: @@ -568,12 +566,11 @@ static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgr static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph) { for (IDNode *id_node : graph->id_nodes) { - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (ComponentNode *comp_node : id_node->components.values()) { for (OperationNode *op_node : comp_node->operations) { deg_debug_graphviz_node_relations(ctx, op_node); } } - GHASH_FOREACH_END(); } TimeSourceNode *time_source = graph->find_time_source(); diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 6d88782d68c..faf375155b5 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -31,7 +31,6 @@ #include "MEM_guardedalloc.h" #include "BLI_console.h" -#include "BLI_ghash.h" #include "BLI_hash.h" #include "BLI_utildefines.h" @@ -60,12 +59,6 @@ extern "C" { namespace DEG { -/* TODO(sergey): Find a better place for this. */ -template<typename T> static void remove_from_vector(vector<T> *vector, const T &value) -{ - vector->erase(std::remove(vector->begin(), vector->end(), value), vector->end()); -} - Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) : time_source(nullptr), need_update(true), @@ -81,8 +74,6 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati is_render_pipeline_depsgraph(false) { BLI_spin_init(&lock); - id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); - entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags"); memset(id_type_updated, 0, sizeof(id_type_updated)); memset(id_type_exist, 0, sizeof(id_type_exist)); memset(physics_relations, 0, sizeof(physics_relations)); @@ -91,8 +82,6 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati Depsgraph::~Depsgraph() { clear_id_nodes(); - BLI_ghash_free(id_hash, nullptr, nullptr); - BLI_gset_free(entry_tags, nullptr); if (time_source != nullptr) { OBJECT_GUARDED_DELETE(time_source, TimeSourceNode); } @@ -117,7 +106,7 @@ TimeSourceNode *Depsgraph::find_time_source() const IDNode *Depsgraph::find_id_node(const ID *id) const { - return reinterpret_cast<IDNode *>(BLI_ghash_lookup(id_hash, id)); + return id_hash.lookup_default(id, nullptr); } IDNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint) @@ -132,7 +121,7 @@ IDNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint) * * NOTE: We address ID nodes by the original ID pointer they are * referencing to. */ - BLI_ghash_insert(id_hash, id, id_node); + id_hash.add_new(id, id_node); id_nodes.push_back(id_node); id_type_exist[BKE_idtype_idcode_to_index(GS(id->name))] = 1; @@ -170,7 +159,7 @@ void Depsgraph::clear_id_nodes() OBJECT_GUARDED_DELETE(id_node, IDNode); } /* Clear containers. */ - BLI_ghash_clear(id_hash, nullptr, nullptr); + id_hash.clear(); id_nodes.clear(); /* Clear physics relation caches. */ clear_physics_relations(this); @@ -233,7 +222,7 @@ void Depsgraph::add_entry_tag(OperationNode *node) * from. * NOTE: this is necessary since we have several thousand nodes to play * with. */ - BLI_gset_insert(entry_tags, node); + entry_tags.add(node); } void Depsgraph::clear_all_nodes() @@ -320,9 +309,9 @@ void DEG_graph_free(Depsgraph *graph) OBJECT_GUARDED_DELETE(deg_depsgraph, Depsgraph); } -bool DEG_is_evaluating(struct Depsgraph *depsgraph) +bool DEG_is_evaluating(const struct Depsgraph *depsgraph) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph); + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph); return deg_graph->is_evaluating; } diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 7801f95e008..672f202338e 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -43,8 +43,6 @@ #include "intern/debug/deg_debug.h" #include "intern/depsgraph_type.h" -struct GHash; -struct GSet; struct ID; struct Scene; struct ViewLayer; @@ -97,7 +95,7 @@ struct Depsgraph { /* <ID : IDNode> mapping from ID blocks to nodes representing these * blocks, used for quick lookups. */ - GHash *id_hash; + Map<const ID *, IDNode *> id_hash; /* Ordered list of ID nodes, order matches ID allocation order. * Used for faster iteration, especially for areas which are critical to @@ -119,7 +117,7 @@ struct Depsgraph { /* Quick-Access Temp Data ............. */ /* Nodes which have been tagged as "directly modified". */ - GSet *entry_tags; + Set<OperationNode *> 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. */ @@ -169,7 +167,7 @@ struct Depsgraph { /* Cached list of colliders/effectors for collections and the scene * created along with relations, for fast lookup during evaluation. */ - GHash *physics_relations[DEG_PHYSICS_RELATIONS_NUM]; + Map<const ID *, ListBase *> *physics_relations[DEG_PHYSICS_RELATIONS_NUM]; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index d78bc07ac5e..59065ea671a 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -25,7 +25,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc index c713a4a3fb1..8b6984c9870 100644 --- a/source/blender/depsgraph/intern/depsgraph_debug.cc +++ b/source/blender/depsgraph/intern/depsgraph_debug.cc @@ -23,7 +23,6 @@ * Implementation of tools for debugging the depsgraph */ -#include "BLI_ghash.h" #include "BLI_utildefines.h" extern "C" { @@ -224,13 +223,12 @@ void DEG_stats_simple(const Depsgraph *graph, for (DEG::IDNode *id_node : deg_graph->id_nodes) { tot_outer++; - GHASH_FOREACH_BEGIN (DEG::ComponentNode *, comp_node, id_node->components) { + for (DEG::ComponentNode *comp_node : id_node->components.values()) { tot_outer++; for (DEG::OperationNode *op_node : comp_node->operations) { tot_rels += op_node->inlinks.size(); } } - GHASH_FOREACH_END(); } DEG::TimeSourceNode *time_source = deg_graph->find_time_source(); diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 9251d975125..c5628a4f8b9 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -25,7 +25,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" @@ -87,5 +86,5 @@ void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime) bool DEG_needs_eval(Depsgraph *graph) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - return BLI_gset_len(deg_graph->entry_tags) != 0 || deg_graph->need_update_time; + return !deg_graph->entry_tags.is_empty() || deg_graph->need_update_time; } diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc index d7c09780845..20375e447c3 100644 --- a/source/blender/depsgraph/intern/depsgraph_physics.cc +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -28,7 +28,6 @@ #include "MEM_guardedalloc.h" #include "BLI_compiler_compat.h" -#include "BLI_ghash.h" #include "BLI_listbase.h" extern "C" { @@ -72,8 +71,8 @@ ListBase *DEG_get_effector_relations(const Depsgraph *graph, Collection *collect } ID *collection_orig = DEG_get_original_id(&collection->id); - return (ListBase *)BLI_ghash_lookup(deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR], - collection_orig); + return deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR]->lookup_default(collection_orig, + nullptr); } ListBase *DEG_get_collision_relations(const Depsgraph *graph, @@ -86,7 +85,7 @@ ListBase *DEG_get_collision_relations(const Depsgraph *graph, return nullptr; } ID *collection_orig = DEG_get_original_id(&collection->id); - return (ListBase *)BLI_ghash_lookup(deg_graph->physics_relations[type], collection_orig); + return deg_graph->physics_relations[type]->lookup_default(collection_orig, nullptr); } /********************** Depsgraph Building API ************************/ @@ -165,19 +164,15 @@ namespace DEG { ListBase *build_effector_relations(Depsgraph *graph, Collection *collection) { - GHash *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; + Map<const ID *, ListBase *> *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; if (hash == nullptr) { - graph->physics_relations[DEG_PHYSICS_EFFECTOR] = BLI_ghash_ptr_new( - "Depsgraph physics relations hash"); + graph->physics_relations[DEG_PHYSICS_EFFECTOR] = new Map<const ID *, ListBase *>(); hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; } - ListBase *relations = reinterpret_cast<ListBase *>(BLI_ghash_lookup(hash, collection)); - if (relations == nullptr) { + return hash->lookup_or_add(&collection->id, [&]() { ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph); - relations = BKE_effector_relations_create(depsgraph, graph->view_layer, collection); - BLI_ghash_insert(hash, &collection->id, relations); - } - return relations; + return BKE_effector_relations_create(depsgraph, graph->view_layer, collection); + }); } ListBase *build_collision_relations(Depsgraph *graph, @@ -185,48 +180,38 @@ ListBase *build_collision_relations(Depsgraph *graph, unsigned int modifier_type) { const ePhysicsRelationType type = modifier_to_relation_type(modifier_type); - GHash *hash = graph->physics_relations[type]; + Map<const ID *, ListBase *> *hash = graph->physics_relations[type]; if (hash == nullptr) { - graph->physics_relations[type] = BLI_ghash_ptr_new("Depsgraph physics relations hash"); + graph->physics_relations[type] = new Map<const ID *, ListBase *>(); hash = graph->physics_relations[type]; } - ListBase *relations = reinterpret_cast<ListBase *>(BLI_ghash_lookup(hash, collection)); - if (relations == nullptr) { + return hash->lookup_or_add(&collection->id, [&]() { ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph); - relations = BKE_collision_relations_create(depsgraph, collection, modifier_type); - BLI_ghash_insert(hash, &collection->id, relations); - } - return relations; -} - -namespace { - -void free_effector_relations(void *value) -{ - BKE_effector_relations_free(reinterpret_cast<ListBase *>(value)); + return BKE_collision_relations_create(depsgraph, collection, modifier_type); + }); } -void free_collision_relations(void *value) -{ - BKE_collision_relations_free(reinterpret_cast<ListBase *>(value)); -} - -} // namespace - void clear_physics_relations(Depsgraph *graph) { for (int i = 0; i < DEG_PHYSICS_RELATIONS_NUM; i++) { - if (graph->physics_relations[i]) { + Map<const ID *, ListBase *> *hash = graph->physics_relations[i]; + if (hash) { const ePhysicsRelationType type = (ePhysicsRelationType)i; switch (type) { case DEG_PHYSICS_EFFECTOR: - BLI_ghash_free(graph->physics_relations[i], nullptr, free_effector_relations); + for (ListBase *list : hash->values()) { + BKE_effector_relations_free(list); + } + hash->clear(); break; case DEG_PHYSICS_COLLISION: case DEG_PHYSICS_SMOKE_COLLISION: case DEG_PHYSICS_DYNAMIC_BRUSH: - BLI_ghash_free(graph->physics_relations[i], nullptr, free_collision_relations); + for (ListBase *list : hash->values()) { + BKE_collision_relations_free(list); + } + hash->clear(); break; case DEG_PHYSICS_RELATIONS_NUM: break; diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 6e85b2e8bd9..b64b6c0e715 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -28,7 +28,6 @@ extern "C" { #include <string.h> // XXX: memcpy -#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" @@ -271,7 +270,7 @@ ID *DEG_get_original_id(ID *id) return (ID *)id->orig_id; } -bool DEG_is_original_id(ID *id) +bool DEG_is_original_id(const ID *id) { /* Some explanation of the logic. * @@ -296,17 +295,17 @@ bool DEG_is_original_id(ID *id) return true; } -bool DEG_is_original_object(Object *object) +bool DEG_is_original_object(const Object *object) { return DEG_is_original_id(&object->id); } -bool DEG_is_evaluated_id(ID *id) +bool DEG_is_evaluated_id(const ID *id) { return !DEG_is_original_id(id); } -bool DEG_is_evaluated_object(Object *object) +bool DEG_is_evaluated_object(const Object *object) { return !DEG_is_original_object(object); } @@ -319,7 +318,7 @@ bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph) return false; } /* Check whether IDs are up to date. */ - if (BLI_gset_len(deg_graph->entry_tags) > 0) { + if (!deg_graph->entry_tags.is_empty()) { return false; } return true; diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc index efd7d6e77ef..b68c4b91fcc 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc @@ -23,14 +23,9 @@ * Implementation of Querying and Filtering API's */ -#include <unordered_set> - #include "MEM_guardedalloc.h" -extern "C" { -#include "BLI_ghash.h" #include "BLI_utildefines.h" -} /* extern "C" */ #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -50,8 +45,6 @@ extern "C" { namespace DEG { namespace { -using std::unordered_set; - typedef deque<OperationNode *> TraversalQueue; typedef void (*DEGForeachOperation)(OperationNode *op_node, void *user_data); @@ -66,11 +59,12 @@ bool deg_foreach_needs_visit(const OperationNode *op_node, const int flags) return true; } -static void deg_foreach_dependent_operation(const IDNode *target_id_node, - eDepsObjectComponentType source_component_type, - int flags, - DEGForeachOperation callback, - void *user_data) +void deg_foreach_dependent_operation(const Depsgraph *UNUSED(graph), + const IDNode *target_id_node, + eDepsObjectComponentType source_component_type, + int flags, + DEGForeachOperation callback, + void *user_data) { if (target_id_node == nullptr) { /* TODO(sergey): Shall we inform or assert here about attempt to start @@ -79,8 +73,8 @@ static void deg_foreach_dependent_operation(const IDNode *target_id_node, } /* Start with scheduling all operations from ID node. */ TraversalQueue queue; - unordered_set<OperationNode *> scheduled; - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, target_id_node->components) { + Set<OperationNode *> scheduled; + for (ComponentNode *comp_node : target_id_node->components.values()) { if (source_component_type != DEG_OB_COMP_ANY && nodeTypeToObjectComponent(comp_node->type) != source_component_type) { continue; @@ -90,10 +84,9 @@ static void deg_foreach_dependent_operation(const IDNode *target_id_node, continue; } queue.push_back(op_node); - scheduled.insert(op_node); + scheduled.add(op_node); } } - GHASH_FOREACH_END(); /* Process the queue. */ while (!queue.empty()) { /* get next operation node to process. */ @@ -104,9 +97,8 @@ static void deg_foreach_dependent_operation(const IDNode *target_id_node, /* Schedule outgoing operation nodes. */ if (op_node->outlinks.size() == 1) { OperationNode *to_node = (OperationNode *)op_node->outlinks[0]->to; - if (scheduled.find(to_node) == scheduled.end() && - deg_foreach_needs_visit(to_node, flags)) { - scheduled.insert(to_node); + if (!scheduled.contains(to_node) && deg_foreach_needs_visit(to_node, flags)) { + scheduled.add_new(to_node); op_node = to_node; } else { @@ -116,10 +108,9 @@ static void deg_foreach_dependent_operation(const IDNode *target_id_node, else { for (Relation *rel : op_node->outlinks) { OperationNode *to_node = (OperationNode *)rel->to; - if (scheduled.find(to_node) == scheduled.end() && - deg_foreach_needs_visit(to_node, flags)) { + if (!scheduled.contains(to_node) && deg_foreach_needs_visit(to_node, flags)) { queue.push_front(to_node); - scheduled.insert(to_node); + scheduled.add_new(to_node); } } break; @@ -132,7 +123,7 @@ struct ForeachIDComponentData { DEGForeachIDComponentCallback callback; void *user_data; IDNode *target_id_node; - unordered_set<ComponentNode *> visited; + Set<ComponentNode *> visited; }; void deg_foreach_dependent_component_callback(OperationNode *op_node, void *user_data_v) @@ -140,11 +131,10 @@ void deg_foreach_dependent_component_callback(OperationNode *op_node, void *user ForeachIDComponentData *user_data = reinterpret_cast<ForeachIDComponentData *>(user_data_v); ComponentNode *comp_node = op_node->owner; IDNode *id_node = comp_node->owner; - if (id_node != user_data->target_id_node && - user_data->visited.find(comp_node) == user_data->visited.end()) { + if (id_node != user_data->target_id_node && !user_data->visited.contains(comp_node)) { user_data->callback( id_node->id_orig, nodeTypeToObjectComponent(comp_node->type), user_data->user_data); - user_data->visited.insert(comp_node); + user_data->visited.add_new(comp_node); } } @@ -159,7 +149,8 @@ void deg_foreach_dependent_ID_component(const Depsgraph *graph, data.callback = callback; data.user_data = user_data; data.target_id_node = graph->find_id_node(id); - deg_foreach_dependent_operation(data.target_id_node, + deg_foreach_dependent_operation(graph, + data.target_id_node, source_component_type, flags, deg_foreach_dependent_component_callback, @@ -170,7 +161,7 @@ struct ForeachIDData { DEGForeachIDCallback callback; void *user_data; IDNode *target_id_node; - unordered_set<IDNode *> visited; + Set<IDNode *> visited; }; void deg_foreach_dependent_ID_callback(OperationNode *op_node, void *user_data_v) @@ -178,10 +169,9 @@ void deg_foreach_dependent_ID_callback(OperationNode *op_node, void *user_data_v ForeachIDData *user_data = reinterpret_cast<ForeachIDData *>(user_data_v); ComponentNode *comp_node = op_node->owner; IDNode *id_node = comp_node->owner; - if (id_node != user_data->target_id_node && - user_data->visited.find(id_node) == user_data->visited.end()) { + if (id_node != user_data->target_id_node && !user_data->visited.contains(id_node)) { user_data->callback(id_node->id_orig, user_data->user_data); - user_data->visited.insert(id_node); + user_data->visited.add_new(id_node); } } @@ -195,7 +185,7 @@ void deg_foreach_dependent_ID(const Depsgraph *graph, data.user_data = user_data; data.target_id_node = graph->find_id_node(id); deg_foreach_dependent_operation( - data.target_id_node, DEG_OB_COMP_ANY, 0, deg_foreach_dependent_ID_callback, &data); + graph, data.target_id_node, DEG_OB_COMP_ANY, 0, deg_foreach_dependent_ID_callback, &data); } void deg_foreach_ancestor_ID(const Depsgraph *graph, @@ -212,16 +202,15 @@ void deg_foreach_ancestor_ID(const Depsgraph *graph, } /* Start with scheduling all operations from ID node. */ TraversalQueue queue; - unordered_set<OperationNode *> scheduled; - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, target_id_node->components) { + Set<OperationNode *> scheduled; + for (ComponentNode *comp_node : target_id_node->components.values()) { for (OperationNode *op_node : comp_node->operations) { queue.push_back(op_node); - scheduled.insert(op_node); + scheduled.add(op_node); } } - GHASH_FOREACH_END(); - unordered_set<IDNode *> visited; - visited.insert(target_id_node); + Set<IDNode *> visited; + visited.add_new(target_id_node); /* Process the queue. */ while (!queue.empty()) { /* get next operation node to process. */ @@ -231,18 +220,17 @@ void deg_foreach_ancestor_ID(const Depsgraph *graph, /* Check whether we need to inform callee about corresponding ID node. */ ComponentNode *comp_node = op_node->owner; IDNode *id_node = comp_node->owner; - if (visited.find(id_node) == visited.end()) { + if (!visited.contains(id_node)) { /* TODO(sergey): Is it orig or CoW? */ callback(id_node->id_orig, user_data); - visited.insert(id_node); + visited.add_new(id_node); } /* Schedule incoming operation nodes. */ if (op_node->inlinks.size() == 1) { Node *from = op_node->inlinks[0]->from; if (from->get_class() == NodeClass::OPERATION) { OperationNode *from_node = (OperationNode *)from; - if (scheduled.find(from_node) == scheduled.end()) { - scheduled.insert(from_node); + if (scheduled.add(from_node)) { op_node = from_node; } else { @@ -255,9 +243,8 @@ void deg_foreach_ancestor_ID(const Depsgraph *graph, Node *from = rel->from; if (from->get_class() == NodeClass::OPERATION) { OperationNode *from_node = (OperationNode *)from; - if (scheduled.find(from_node) == scheduled.end()) { + if (scheduled.add(from_node)) { queue.push_front(from_node); - scheduled.insert(from_node); } } } diff --git a/source/blender/depsgraph/intern/depsgraph_registry.cc b/source/blender/depsgraph/intern/depsgraph_registry.cc index ad60b1bc4cf..3b0a0b3ea19 100644 --- a/source/blender/depsgraph/intern/depsgraph_registry.cc +++ b/source/blender/depsgraph/intern/depsgraph_registry.cc @@ -29,46 +29,33 @@ namespace DEG { -typedef set<Depsgraph *> DepsgraphStorage; -typedef map<Main *, DepsgraphStorage> MainDepsgraphMap; - -static MainDepsgraphMap g_graph_registry; +static Map<Main *, VectorSet<Depsgraph *>> g_graph_registry; void register_graph(Depsgraph *depsgraph) { Main *bmain = depsgraph->bmain; - MainDepsgraphMap::iterator it = g_graph_registry.find(bmain); - if (it == g_graph_registry.end()) { - it = g_graph_registry.insert(make_pair(bmain, DepsgraphStorage())).first; - } - DepsgraphStorage &storage = it->second; - storage.insert(depsgraph); + g_graph_registry.lookup_or_add_default(bmain).add_new(depsgraph); } void unregister_graph(Depsgraph *depsgraph) { Main *bmain = depsgraph->bmain; - MainDepsgraphMap::iterator it = g_graph_registry.find(bmain); - BLI_assert(it != g_graph_registry.end()); - - // Remove dependency graph from storage. - DepsgraphStorage &storage = it->second; - storage.erase(depsgraph); + VectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain); + graphs.remove(depsgraph); // If this was the last depsgraph associated with the main, remove the main entry as well. - if (storage.empty()) { - g_graph_registry.erase(bmain); + if (graphs.is_empty()) { + g_graph_registry.remove(bmain); } } -const set<Depsgraph *> &get_all_registered_graphs(Main *bmain) +ArrayRef<Depsgraph *> get_all_registered_graphs(Main *bmain) { - MainDepsgraphMap::iterator it = g_graph_registry.find(bmain); - if (it == g_graph_registry.end()) { - static DepsgraphStorage empty_storage; - return empty_storage; + VectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain); + if (graphs != nullptr) { + return *graphs; } - return it->second; + return {}; } } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_registry.h b/source/blender/depsgraph/intern/depsgraph_registry.h index 7517b6a0b2a..f8e5b9543f2 100644 --- a/source/blender/depsgraph/intern/depsgraph_registry.h +++ b/source/blender/depsgraph/intern/depsgraph_registry.h @@ -33,6 +33,6 @@ struct Depsgraph; void register_graph(Depsgraph *depsgraph); void unregister_graph(Depsgraph *depsgraph); -const set<Depsgraph *> &get_all_registered_graphs(Main *bmain); +ArrayRef<Depsgraph *> get_all_registered_graphs(Main *bmain); } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_relation.cc b/source/blender/depsgraph/intern/depsgraph_relation.cc index cff62540ca8..a4ec48658f5 100644 --- a/source/blender/depsgraph/intern/depsgraph_relation.cc +++ b/source/blender/depsgraph/intern/depsgraph_relation.cc @@ -30,12 +30,6 @@ namespace DEG { -/* TODO(sergey): Find a better place for this. */ -template<typename T> static void remove_from_vector(vector<T> *vector, const T &value) -{ - vector->erase(std::remove(vector->begin(), vector->end(), value), vector->end()); -} - Relation::Relation(Node *from, Node *to, const char *description) : from(from), to(to), name(description), flag(0) { @@ -52,8 +46,8 @@ Relation::Relation(Node *from, Node *to, const char *description) * * - Un-registering relation is not a cheap operation, so better to have it * as an explicit call if we need this. */ - from->outlinks.push_back(this); - to->inlinks.push_back(this); + from->outlinks.append(this); + to->inlinks.append(this); } Relation::~Relation() @@ -66,8 +60,8 @@ void Relation::unlink() { /* Sanity check. */ BLI_assert(from != nullptr && to != nullptr); - remove_from_vector(&from->outlinks, this); - remove_from_vector(&to->inlinks, this); + from->outlinks.remove_first_occurrence_and_reorder(this); + to->inlinks.remove_first_occurrence_and_reorder(this); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 1c56808ea82..ff7d9ee0170 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -495,13 +495,13 @@ 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 |= deg_recalc_flags_for_legacy_zero(); - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + + for (ComponentNode *comp_node : id_node->components.values()) { if (comp_node->type == NodeType::ANIMATION) { continue; } comp_node->tag_update(graph, update_source); } - GHASH_FOREACH_END(); deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0, update_source); } diff --git a/source/blender/depsgraph/intern/depsgraph_type.cc b/source/blender/depsgraph/intern/depsgraph_type.cc index 559bf8dfdab..92d775b0ae4 100644 --- a/source/blender/depsgraph/intern/depsgraph_type.cc +++ b/source/blender/depsgraph/intern/depsgraph_type.cc @@ -25,7 +25,6 @@ #include <cstdlib> // for BLI_assert() -#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "DNA_customdata_types.h" diff --git a/source/blender/depsgraph/intern/depsgraph_type.h b/source/blender/depsgraph/intern/depsgraph_type.h index fbf5c2fd381..7016d07ae72 100644 --- a/source/blender/depsgraph/intern/depsgraph_type.h +++ b/source/blender/depsgraph/intern/depsgraph_type.h @@ -38,9 +38,14 @@ #include <map> #include <set> #include <string> -#include <unordered_map> #include <vector> +#include "BLI_map.hh" +#include "BLI_set.hh" +#include "BLI_string_ref.hh" +#include "BLI_vector.hh" +#include "BLI_vector_set.hh" + struct Depsgraph; struct CustomData_MeshMasks; @@ -48,12 +53,19 @@ struct CustomData_MeshMasks; namespace DEG { /* Commonly used types. */ +using BLI::ArrayRef; +using BLI::Map; +using BLI::Set; +using BLI::StringRef; +using BLI::StringRefNull; +using BLI::Vector; +using BLI::VectorSet; using std::deque; using std::map; using std::pair; using std::set; using std::string; -using std::unordered_map; +using std::unique_ptr; using std::vector; /* Commonly used functions. */ diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index c7f3c5cb2b6..189beb506b3 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -28,7 +28,6 @@ #include "PIL_time.h" #include "BLI_compiler_attrs.h" -#include "BLI_ghash.h" #include "BLI_gsqueue.h" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -61,18 +60,17 @@ namespace { struct DepsgraphEvalState; -void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id); +void deg_task_run_func(TaskPool *pool, void *taskdata); template<typename ScheduleFunction, typename... ScheduleFunctionArgs> void schedule_children(DepsgraphEvalState *state, OperationNode *node, - const int thread_id, ScheduleFunction *schedule_function, ScheduleFunctionArgs... schedule_function_args); -void schedule_node_to_pool(OperationNode *node, const int thread_id, TaskPool *pool) +void schedule_node_to_pool(OperationNode *node, const int UNUSED(thread_id), TaskPool *pool) { - BLI_task_pool_push_from_thread(pool, deg_task_run_func, node, false, NULL, thread_id); + BLI_task_pool_push(pool, deg_task_run_func, node, false, NULL); } /* Denotes which part of dependency graph is being evaluated. */ @@ -116,9 +114,9 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod } } -void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id) +void deg_task_run_func(TaskPool *pool, void *taskdata) { - void *userdata_v = BLI_task_pool_userdata(pool); + void *userdata_v = BLI_task_pool_user_data(pool); DepsgraphEvalState *state = (DepsgraphEvalState *)userdata_v; /* Evaluate node. */ @@ -126,9 +124,7 @@ void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id) evaluate_node(state, operation_node); /* Schedule children. */ - BLI_task_pool_delayed_push_begin(pool, thread_id); - schedule_children(state, operation_node, thread_id, schedule_node_to_pool, pool); - BLI_task_pool_delayed_push_end(pool, thread_id); + schedule_children(state, operation_node, schedule_node_to_pool, pool); } bool check_operation_node_visible(OperationNode *op_node) @@ -238,7 +234,6 @@ template<typename ScheduleFunction, typename... ScheduleFunctionArgs> void schedule_node(DepsgraphEvalState *state, OperationNode *node, bool dec_parents, - const int thread_id, ScheduleFunction *schedule_function, ScheduleFunctionArgs... schedule_function_args) { @@ -271,11 +266,11 @@ void schedule_node(DepsgraphEvalState *state, if (!is_scheduled) { if (node->is_noop()) { /* skip NOOP node, schedule children right away */ - schedule_children(state, node, thread_id, schedule_function, schedule_function_args...); + schedule_children(state, node, schedule_function, schedule_function_args...); } else { /* children are scheduled once this task is completed */ - schedule_function(node, thread_id, schedule_function_args...); + schedule_function(node, 0, schedule_function_args...); } } } @@ -286,14 +281,13 @@ void schedule_graph(DepsgraphEvalState *state, ScheduleFunctionArgs... schedule_function_args) { for (OperationNode *node : state->graph->operations) { - schedule_node(state, node, false, -1, schedule_function, schedule_function_args...); + schedule_node(state, node, false, schedule_function, schedule_function_args...); } } template<typename ScheduleFunction, typename... ScheduleFunctionArgs> void schedule_children(DepsgraphEvalState *state, OperationNode *node, - const int thread_id, ScheduleFunction *schedule_function, ScheduleFunctionArgs... schedule_function_args) { @@ -307,7 +301,6 @@ void schedule_children(DepsgraphEvalState *state, schedule_node(state, child, (rel->flag & RELATION_FLAG_CYCLIC) == 0, - thread_id, schedule_function, schedule_function_args...); } @@ -330,7 +323,7 @@ void evaluate_graph_single_threaded(DepsgraphEvalState *state) BLI_gsqueue_pop(evaluation_queue, &operation_node); evaluate_node(state, operation_node); - schedule_children(state, operation_node, 0, schedule_node_to_queue, evaluation_queue); + schedule_children(state, operation_node, schedule_node_to_queue, evaluation_queue); } BLI_gsqueue_free(evaluation_queue); @@ -354,6 +347,16 @@ void depsgraph_ensure_view_layer(Depsgraph *graph) } // namespace +static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state) +{ + if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) { + return BLI_task_pool_create_no_threads(state); + } + else { + return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH); + } +} + /** * Evaluate all nodes tagged for updating, * \warning This is usually done as part of main loop, but may also be @@ -364,7 +367,7 @@ void depsgraph_ensure_view_layer(Depsgraph *graph) void deg_evaluate_on_refresh(Depsgraph *graph) { /* Nothing to update, early out. */ - if (BLI_gset_len(graph->entry_tags) == 0) { + if (graph->entry_tags.is_empty()) { return; } @@ -377,30 +380,20 @@ void deg_evaluate_on_refresh(Depsgraph *graph) state.graph = graph; state.do_stats = graph->debug.do_time_debug(); state.need_single_thread_pass = false; - /* Set up task scheduler and pull for threaded evaluation. */ - TaskScheduler *task_scheduler; - bool need_free_scheduler; - if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) { - task_scheduler = BLI_task_scheduler_create(1); - need_free_scheduler = true; - } - else { - task_scheduler = BLI_task_scheduler_get(); - need_free_scheduler = false; - } - TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state, TASK_PRIORITY_HIGH); /* Prepare all nodes for evaluation. */ initialize_execution(&state, graph); /* Do actual evaluation now. */ - /* First, process all Copy-On-Write nodes. */ state.stage = EvaluationStage::COPY_ON_WRITE; + TaskPool *task_pool = deg_evaluate_task_pool_create(&state); schedule_graph(&state, schedule_node_to_pool, task_pool); - BLI_task_pool_work_wait_and_reset(task_pool); + BLI_task_pool_work_and_wait(task_pool); + BLI_task_pool_free(task_pool); /* After that, process all other nodes. */ state.stage = EvaluationStage::THREADED_EVALUATION; + task_pool = deg_evaluate_task_pool_create(&state); schedule_graph(&state, schedule_node_to_pool, task_pool); BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); @@ -418,9 +411,6 @@ void deg_evaluate_on_refresh(Depsgraph *graph) } /* Clear any uncleared tags - just in case. */ deg_graph_clear_tags(graph); - if (need_free_scheduler) { - BLI_task_scheduler_free(task_scheduler); - } graph->is_evaluating = false; graph->debug.end_graph_evaluation(); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 990002cf2e8..5ff1b31b07c 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -27,7 +27,6 @@ #include <cmath> -#include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math_vector.h" #include "BLI_task.h" @@ -94,9 +93,9 @@ void flush_init_id_node_func(void *__restrict data_v, Depsgraph *graph = (Depsgraph *)data_v; IDNode *id_node = graph->id_nodes[i]; id_node->custom_flags = ID_STATE_NONE; - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) + for (ComponentNode *comp_node : id_node->components.values()) { comp_node->custom_flags = COMPONENT_STATE_NONE; - GHASH_FOREACH_END(); + } } BLI_INLINE void flush_prepare(Depsgraph *graph) @@ -116,7 +115,7 @@ BLI_INLINE void flush_prepare(Depsgraph *graph) BLI_INLINE void flush_schedule_entrypoints(Depsgraph *graph, FlushQueue *queue) { - GSET_FOREACH_BEGIN (OperationNode *, op_node, graph->entry_tags) { + for (OperationNode *op_node : graph->entry_tags) { queue->push_back(op_node); op_node->scheduled = true; DEG_DEBUG_PRINTF((::Depsgraph *)graph, @@ -124,7 +123,6 @@ BLI_INLINE void flush_schedule_entrypoints(Depsgraph *graph, FlushQueue *queue) "Operation is entry point for update: %s\n", op_node->identifier().c_str()); } - GSET_FOREACH_END(); } BLI_INLINE void flush_handle_id_node(IDNode *id_node) @@ -231,7 +229,7 @@ void flush_editors_id_update(Depsgraph *graph, const DEGEditorUpdateContext *upd ID *id_orig = id_node->id_orig; ID *id_cow = id_node->id_cow; /* Gather recalc flags from all changed components. */ - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (DEG::ComponentNode *comp_node : id_node->components.values()) { if (comp_node->custom_flags != COMPONENT_STATE_DONE) { continue; } @@ -239,7 +237,6 @@ void flush_editors_id_update(Depsgraph *graph, const DEGEditorUpdateContext *upd BLI_assert(factory != nullptr); id_cow->recalc |= factory->id_recalc_tag(); } - GHASH_FOREACH_END(); DEG_DEBUG_PRINTF((::Depsgraph *)graph, EVAL, "Accumulated recalc bits for %s: %u\n", @@ -307,7 +304,7 @@ void invalidate_tagged_evaluated_data(Depsgraph *graph) if (!deg_copy_on_write_is_expanded(id_cow)) { continue; } - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (ComponentNode *comp_node : id_node->components.values()) { if (comp_node->custom_flags != COMPONENT_STATE_DONE) { continue; } @@ -322,7 +319,6 @@ void invalidate_tagged_evaluated_data(Depsgraph *graph) break; } } - GHASH_FOREACH_END(); } #else (void)graph; @@ -347,7 +343,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) graph->ctime = ctime; time_source->tag_update(graph, DEG::DEG_UPDATE_SOURCE_TIME); } - if (BLI_gset_len(graph->entry_tags) == 0) { + if (graph->entry_tags.is_empty()) { return; } /* Reset all flags, get ready for the flush. */ @@ -393,7 +389,7 @@ void deg_graph_clear_tags(Depsgraph *graph) DEPSOP_FLAG_USER_MODIFIED); } /* Clear any entry tags which haven't been flushed. */ - BLI_gset_clear(graph->entry_tags, nullptr); + graph->entry_tags.clear(); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_stats.cc b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc index f164560ac24..9d3b1356570 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_stats.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc @@ -23,7 +23,6 @@ #include "intern/eval/deg_eval_stats.h" -#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "intern/depsgraph.h" @@ -41,10 +40,9 @@ void deg_eval_stats_aggregate(Depsgraph *graph) * Those are not filled in by the evaluation engine. */ for (Node *node : graph->id_nodes) { IDNode *id_node = (IDNode *)node; - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (ComponentNode *comp_node : id_node->components.values()) { comp_node->stats.reset_current(); } - GHASH_FOREACH_END(); id_node->stats.reset_current(); } /* Now accumulate operation timings to components and IDs. */ diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h index ffa37341ea6..ad1eba2f7ba 100644 --- a/source/blender/depsgraph/intern/node/deg_node.h +++ b/source/blender/depsgraph/intern/node/deg_node.h @@ -163,7 +163,7 @@ struct Node { * The reason why all depsgraph nodes are descended from this type (apart * from basic serialization benefits - from the typeinfo) is that we can * have relationships between these nodes. */ - typedef vector<Relation *> Relations; + typedef Vector<Relation *> Relations; string name; /* Identifier - mainly for debugging purposes. */ NodeType type; /* Structural type of node. */ diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc index 54796b8965b..9c142cdc97b 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.cc +++ b/source/blender/depsgraph/intern/node/deg_node_component.cc @@ -26,7 +26,6 @@ #include <cstring> /* required for STREQ later on. */ #include <stdio.h> -#include "BLI_ghash.h" #include "BLI_utildefines.h" extern "C" { @@ -72,41 +71,10 @@ bool ComponentNode::OperationIDKey::operator==(const OperationIDKey &other) cons return (opcode == other.opcode) && (STREQ(name, other.name)) && (name_tag == other.name_tag); } -static unsigned int comp_node_hash_key(const void *key_v) -{ - const ComponentNode::OperationIDKey *key = - reinterpret_cast<const ComponentNode::OperationIDKey *>(key_v); - int opcode_as_int = static_cast<int>(key->opcode); - return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(opcode_as_int), - BLI_ghashutil_strhash_p(key->name)); -} - -static bool comp_node_hash_key_cmp(const void *a, const void *b) -{ - const ComponentNode::OperationIDKey *key_a = - reinterpret_cast<const ComponentNode::OperationIDKey *>(a); - const ComponentNode::OperationIDKey *key_b = - reinterpret_cast<const ComponentNode::OperationIDKey *>(b); - return !(*key_a == *key_b); -} - -static void comp_node_hash_key_free(void *key_v) -{ - typedef ComponentNode::OperationIDKey OperationIDKey; - OperationIDKey *key = reinterpret_cast<OperationIDKey *>(key_v); - OBJECT_GUARDED_DELETE(key, OperationIDKey); -} - -static void comp_node_hash_value_free(void *value_v) -{ - OperationNode *op_node = reinterpret_cast<OperationNode *>(value_v); - OBJECT_GUARDED_DELETE(op_node, OperationNode); -} - ComponentNode::ComponentNode() : entry_operation(nullptr), exit_operation(nullptr), affects_directly_visible(false) { - operations_map = BLI_ghash_new(comp_node_hash_key, comp_node_hash_key_cmp, "Depsgraph id hash"); + operations_map = new Map<ComponentNode::OperationIDKey, OperationNode *>(); } /* Initialize 'component' node - from pointer data given */ @@ -121,7 +89,7 @@ ComponentNode::~ComponentNode() { clear_operations(); if (operations_map != nullptr) { - BLI_ghash_free(operations_map, comp_node_hash_key_free, comp_node_hash_value_free); + delete operations_map; } } @@ -137,7 +105,7 @@ OperationNode *ComponentNode::find_operation(OperationIDKey key) const { OperationNode *node = nullptr; if (operations_map != nullptr) { - node = (OperationNode *)BLI_ghash_lookup(operations_map, &key); + node = operations_map->lookup_default(key, nullptr); } else { for (OperationNode *op_node : operations) { @@ -203,8 +171,8 @@ OperationNode *ComponentNode::add_operation(const DepsEvalOperationCb &op, op_node = (OperationNode *)factory->create_node(this->owner->id_orig, "", name); /* register opnode in this component's operation set */ - OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag); - BLI_ghash_insert(operations_map, key, op_node); + OperationIDKey key(opcode, name, name_tag); + operations_map->add(key, op_node); /* set backlink */ op_node->owner = this; @@ -242,7 +210,10 @@ void ComponentNode::set_exit_operation(OperationNode *op_node) void ComponentNode::clear_operations() { if (operations_map != nullptr) { - BLI_ghash_clear(operations_map, comp_node_hash_key_free, comp_node_hash_value_free); + for (OperationNode *op_node : operations_map->values()) { + OBJECT_GUARDED_DELETE(op_node, OperationNode); + } + operations_map->clear(); } for (OperationNode *op_node : operations) { OBJECT_GUARDED_DELETE(op_node, OperationNode); @@ -261,10 +232,9 @@ void ComponentNode::tag_update(Depsgraph *graph, eUpdateSource source) } // It is possible that tag happens before finalization. if (operations_map != nullptr) { - GHASH_FOREACH_BEGIN (OperationNode *, op_node, operations_map) { + for (OperationNode *op_node : operations_map->values()) { op_node->tag_update(graph, source); } - GHASH_FOREACH_END(); } } @@ -273,13 +243,12 @@ OperationNode *ComponentNode::get_entry_operation() if (entry_operation) { return entry_operation; } - else if (operations_map != nullptr && BLI_ghash_len(operations_map) == 1) { + else if (operations_map != nullptr && operations_map->size() == 1) { OperationNode *op_node = nullptr; /* TODO(sergey): This is somewhat slow. */ - GHASH_FOREACH_BEGIN (OperationNode *, tmp, operations_map) { + for (OperationNode *tmp : operations_map->values()) { op_node = tmp; } - GHASH_FOREACH_END(); /* Cache for the subsequent usage. */ entry_operation = op_node; return op_node; @@ -295,13 +264,12 @@ OperationNode *ComponentNode::get_exit_operation() if (exit_operation) { return exit_operation; } - else if (operations_map != nullptr && BLI_ghash_len(operations_map) == 1) { + else if (operations_map != nullptr && operations_map->size() == 1) { OperationNode *op_node = nullptr; /* TODO(sergey): This is somewhat slow. */ - GHASH_FOREACH_BEGIN (OperationNode *, tmp, operations_map) { + for (OperationNode *tmp : operations_map->values()) { op_node = tmp; } - GHASH_FOREACH_END(); /* Cache for the subsequent usage. */ exit_operation = op_node; return op_node; @@ -314,12 +282,11 @@ OperationNode *ComponentNode::get_exit_operation() void ComponentNode::finalize_build(Depsgraph * /*graph*/) { - operations.reserve(BLI_ghash_len(operations_map)); - GHASH_FOREACH_BEGIN (OperationNode *, op_node, operations_map) { + operations.reserve(operations_map->size()); + for (OperationNode *op_node : operations_map->values()) { operations.push_back(op_node); } - GHASH_FOREACH_END(); - BLI_ghash_free(operations_map, comp_node_hash_key_free, nullptr); + delete operations_map; operations_map = nullptr; } diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h index 38ea4005a72..41d5c130ffd 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.h +++ b/source/blender/depsgraph/intern/node/deg_node_component.h @@ -26,10 +26,11 @@ #include "intern/node/deg_node.h" #include "intern/node/deg_node_operation.h" +#include "BLI_ghash.h" +#include "BLI_hash.hh" #include "BLI_string.h" #include "BLI_utildefines.h" -struct GHash; struct ID; struct bPoseChannel; @@ -115,7 +116,7 @@ struct ComponentNode : public Node { /* Operations stored as a hash map, for faster build. * This hash map will be freed when graph is fully built. */ - GHash *operations_map; + Map<ComponentNode::OperationIDKey, OperationNode *> *operations_map; /* This is a "normal" list of operations, used by evaluation * and other routines after construction. */ @@ -203,3 +204,18 @@ struct BoneComponentNode : public ComponentNode { void deg_register_component_depsnodes(); } // namespace DEG + +namespace BLI { + +template<> struct DefaultHash<DEG::ComponentNode::OperationIDKey> { + uint32_t operator()(const DEG::ComponentNode::OperationIDKey &key) const + { + const int opcode_as_int = static_cast<int>(key.opcode); + return BLI_ghashutil_combine_hash( + key.name_tag, + BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(opcode_as_int), + BLI_ghashutil_strhash_p(key.name))); + } +}; + +} // namespace BLI diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 4b6120a6985..4e998fb095a 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -26,7 +26,6 @@ #include <cstring> /* required for STREQ later on. */ #include <stdio.h> -#include "BLI_ghash.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -69,34 +68,6 @@ bool IDNode::ComponentIDKey::operator==(const ComponentIDKey &other) const return type == other.type && STREQ(name, other.name); } -static unsigned int id_deps_node_hash_key(const void *key_v) -{ - const IDNode::ComponentIDKey *key = reinterpret_cast<const IDNode::ComponentIDKey *>(key_v); - const int type_as_int = static_cast<int>(key->type); - return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(type_as_int), - BLI_ghashutil_strhash_p(key->name)); -} - -static bool id_deps_node_hash_key_cmp(const void *a, const void *b) -{ - const IDNode::ComponentIDKey *key_a = reinterpret_cast<const IDNode::ComponentIDKey *>(a); - const IDNode::ComponentIDKey *key_b = reinterpret_cast<const IDNode::ComponentIDKey *>(b); - return !(*key_a == *key_b); -} - -static void id_deps_node_hash_key_free(void *key_v) -{ - typedef IDNode::ComponentIDKey ComponentIDKey; - ComponentIDKey *key = reinterpret_cast<ComponentIDKey *>(key_v); - OBJECT_GUARDED_DELETE(key, ComponentIDKey); -} - -static void id_deps_node_hash_value_free(void *value_v) -{ - ComponentNode *comp_node = reinterpret_cast<ComponentNode *>(value_v); - OBJECT_GUARDED_DELETE(comp_node, ComponentNode); -} - /* Initialize 'id' node - from pointer data given. */ void IDNode::init(const ID *id, const char *UNUSED(subdata)) { @@ -116,9 +87,6 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata)) visible_components_mask = 0; previously_visible_components_mask = 0; - - components = BLI_ghash_new( - id_deps_node_hash_key, id_deps_node_hash_key_cmp, "Depsgraph id components hash"); } void IDNode::init_copy_on_write(ID *id_cow_hint) @@ -158,7 +126,9 @@ void IDNode::destroy() return; } - BLI_ghash_free(components, id_deps_node_hash_key_free, id_deps_node_hash_value_free); + for (ComponentNode *comp_node : components.values()) { + OBJECT_GUARDED_DELETE(comp_node, ComponentNode); + } /* Free memory used by this CoW ID. */ if (id_cow != id_orig && id_cow != nullptr) { @@ -185,7 +155,7 @@ string IDNode::identifier() const ComponentNode *IDNode::find_component(NodeType type, const char *name) const { ComponentIDKey key(type, name); - return reinterpret_cast<ComponentNode *>(BLI_ghash_lookup(components, &key)); + return components.lookup_default(key, nullptr); } ComponentNode *IDNode::add_component(NodeType type, const char *name) @@ -196,8 +166,8 @@ ComponentNode *IDNode::add_component(NodeType type, const char *name) comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name); /* Register. */ - ComponentIDKey *key = OBJECT_GUARDED_NEW(ComponentIDKey, type, name); - BLI_ghash_insert(components, key, comp_node); + ComponentIDKey key(type, name); + components.add_new(key, comp_node); comp_node->owner = this; } return comp_node; @@ -205,7 +175,7 @@ ComponentNode *IDNode::add_component(NodeType type, const char *name) void IDNode::tag_update(Depsgraph *graph, eUpdateSource source) { - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, components) { + for (ComponentNode *comp_node : components.values()) { /* Relations update does explicit animation update when needed. Here we ignore animation * component to avoid loss of possible unkeyed changes. */ if (comp_node->type == NodeType::ANIMATION && source == DEG_UPDATE_SOURCE_RELATIONS) { @@ -213,30 +183,27 @@ void IDNode::tag_update(Depsgraph *graph, eUpdateSource source) } comp_node->tag_update(graph, source); } - GHASH_FOREACH_END(); } void IDNode::finalize_build(Depsgraph *graph) { /* Finalize build of all components. */ - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, components) { + for (ComponentNode *comp_node : components.values()) { comp_node->finalize_build(graph); } - GHASH_FOREACH_END(); visible_components_mask = get_visible_components_mask(); } IDComponentsMask IDNode::get_visible_components_mask() const { IDComponentsMask result = 0; - GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, components) { + for (ComponentNode *comp_node : components.values()) { if (comp_node->affects_directly_visible) { const int component_type_as_int = static_cast<int>(comp_node->type); BLI_assert(component_type_as_int < 64); result |= (1ULL << component_type_as_int); } } - GHASH_FOREACH_END(); return result; } diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h index 80bb67f182f..c7663b50c6f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.h +++ b/source/blender/depsgraph/intern/node/deg_node_id.h @@ -23,12 +23,11 @@ #pragma once +#include "BLI_ghash.h" #include "BLI_sys_types.h" #include "DNA_ID.h" #include "intern/node/deg_node.h" -struct GHash; - namespace DEG { struct ComponentNode; @@ -82,7 +81,7 @@ struct IDNode : public Node { ID *id_cow; /* Hash to make it faster to look up components. */ - GHash *components; + Map<ComponentIDKey, ComponentNode *> components; /* Additional flags needed for scene evaluation. * TODO(sergey): Only needed for until really granular updates @@ -116,3 +115,16 @@ struct IDNode : public Node { }; } // namespace DEG + +namespace BLI { + +template<> struct DefaultHash<DEG::IDNode::ComponentIDKey> { + uint32_t operator()(const DEG::IDNode::ComponentIDKey &key) const + { + const int type_as_int = static_cast<int>(key.type); + return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(type_as_int), + BLI_ghashutil_strhash_p(key.name)); + } +}; + +} // namespace BLI diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 1e03d51f557..d327e1da8a1 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -25,7 +25,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "intern/depsgraph.h" |