Changeset View
Changeset View
Standalone View
Standalone View
source/blender/depsgraph/intern/depsgraph_tag.cc
| Show First 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | case ID_RECALC_PSYS_ALL: | ||||
| BLI_assert_msg(0, "Should not happen"); | BLI_assert_msg(0, "Should not happen"); | ||||
| break; | break; | ||||
| case ID_RECALC_TAG_FOR_UNDO: | case ID_RECALC_TAG_FOR_UNDO: | ||||
| break; /* Must be ignored by depsgraph. */ | break; /* Must be ignored by depsgraph. */ | ||||
| case ID_RECALC_NTREE_OUTPUT: | case ID_RECALC_NTREE_OUTPUT: | ||||
| *component_type = NodeType::NTREE_OUTPUT; | *component_type = NodeType::NTREE_OUTPUT; | ||||
| *operation_code = OperationCode::NTREE_OUTPUT; | *operation_code = OperationCode::NTREE_OUTPUT; | ||||
| break; | break; | ||||
| case ID_RECALC_PROVISION_26: | |||||
| case ID_RECALC_PROVISION_27: | |||||
| case ID_RECALC_PROVISION_28: | |||||
| case ID_RECALC_PROVISION_29: | |||||
| case ID_RECALC_PROVISION_30: | |||||
| case ID_RECALC_PROVISION_31: | |||||
| BLI_assert_msg(0, "Should not happen"); | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| void id_tag_update_ntree_special( | void id_tag_update_ntree_special( | ||||
| Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source) | Main *bmain, Depsgraph *graph, ID *id, unsigned int flags, eUpdateSource update_source) | ||||
| { | { | ||||
| bNodeTree *ntree = ntreeFromID(id); | bNodeTree *ntree = ntreeFromID(id); | ||||
| if (ntree == nullptr) { | if (ntree == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| graph_id_tag_update(bmain, graph, &ntree->id, flag, update_source); | graph_id_tag_update(bmain, graph, &ntree->id, flags, update_source); | ||||
| } | } | ||||
| void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id) | void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id) | ||||
| { | { | ||||
| /* NOTE: We handle this immediately, without delaying anything, to be | /* NOTE: We handle this immediately, without delaying anything, to be | ||||
| * sure we don't cause threading issues with OpenGL. */ | * sure we don't cause threading issues with OpenGL. */ | ||||
| /* TODO(sergey): Make sure this works for CoW-ed data-blocks as well. */ | /* TODO(sergey): Make sure this works for CoW-ed data-blocks as well. */ | ||||
| DEGEditorUpdateContext update_ctx = {nullptr}; | DEGEditorUpdateContext update_ctx = {nullptr}; | ||||
| ▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | string stringify_append_bit(const string &str, IDRecalcFlag tag) | ||||
| string result = str; | string result = str; | ||||
| if (!result.empty()) { | if (!result.empty()) { | ||||
| result += ", "; | result += ", "; | ||||
| } | } | ||||
| result += tag_name; | result += tag_name; | ||||
| return result; | return result; | ||||
| } | } | ||||
| string stringify_update_bitfield(int flag) | string stringify_update_bitfield(unsigned int flags) | ||||
| { | { | ||||
| if (flag == 0) { | if (flags == 0) { | ||||
| return "LEGACY_0"; | return "LEGACY_0"; | ||||
| } | } | ||||
| string result; | string result; | ||||
| int current_flag = flag; | unsigned int current_flag = flags; | ||||
| /* Special cases to avoid ALL flags form being split into | /* Special cases to avoid ALL flags form being split into | ||||
| * individual bits. */ | * individual bits. */ | ||||
| if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) { | if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) { | ||||
| result = stringify_append_bit(result, ID_RECALC_PSYS_ALL); | result = stringify_append_bit(result, ID_RECALC_PSYS_ALL); | ||||
| } | } | ||||
| /* Handle all the rest of the flags. */ | /* Handle all the rest of the flags. */ | ||||
| while (current_flag != 0) { | while (current_flag != 0) { | ||||
| IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(¤t_flag)); | IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(¤t_flag)); | ||||
| result = stringify_append_bit(result, tag); | result = stringify_append_bit(result, tag); | ||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| const char *update_source_as_string(eUpdateSource source) | const char *update_source_as_string(eUpdateSource source) | ||||
| { | { | ||||
| switch (source) { | switch (source) { | ||||
| Show All 11 Lines | |||||
| } | } | ||||
| int deg_recalc_flags_for_legacy_zero() | int deg_recalc_flags_for_legacy_zero() | ||||
| { | { | ||||
| return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_FRAME_CHANGE | | return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_FRAME_CHANGE | | ||||
| ID_RECALC_SOURCE | ID_RECALC_EDITORS); | ID_RECALC_SOURCE | ID_RECALC_EDITORS); | ||||
| } | } | ||||
| int deg_recalc_flags_effective(Depsgraph *graph, int flags) | int deg_recalc_flags_effective(Depsgraph *graph, unsigned int flags) | ||||
| { | { | ||||
| if (graph != nullptr) { | if (graph != nullptr) { | ||||
| if (!graph->is_active) { | if (!graph->is_active) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| if (flags == 0) { | if (flags == 0) { | ||||
| return deg_recalc_flags_for_legacy_zero(); | return deg_recalc_flags_for_legacy_zero(); | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | void graph_tag_ids_for_visible_update(Depsgraph *graph) | ||||
| for (deg::IDNode *id_node : graph->id_nodes) { | for (deg::IDNode *id_node : graph->id_nodes) { | ||||
| const ID_Type id_type = GS(id_node->id_orig->name); | const ID_Type id_type = GS(id_node->id_orig->name); | ||||
| if (!id_node->visible_components_mask) { | if (!id_node->visible_components_mask) { | ||||
| /* ID has no components which affects anything visible. | /* ID has no components which affects anything visible. | ||||
| * No need bother with it to tag or anything. */ | * No need bother with it to tag or anything. */ | ||||
| continue; | continue; | ||||
| } | } | ||||
| int flag = 0; | unsigned int flags = 0; | ||||
| if (!deg::deg_copy_on_write_is_expanded(id_node->id_cow)) { | if (!deg::deg_copy_on_write_is_expanded(id_node->id_cow)) { | ||||
| flag |= ID_RECALC_COPY_ON_WRITE; | flags |= ID_RECALC_COPY_ON_WRITE; | ||||
| if (do_time) { | if (do_time) { | ||||
| if (BKE_animdata_from_id(id_node->id_orig) != nullptr) { | if (BKE_animdata_from_id(id_node->id_orig) != nullptr) { | ||||
| flag |= ID_RECALC_ANIMATION; | flags |= ID_RECALC_ANIMATION; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (id_node->visible_components_mask == id_node->previously_visible_components_mask) { | if (id_node->visible_components_mask == id_node->previously_visible_components_mask) { | ||||
| /* The ID was already visible and evaluated, all the subsequent | /* The ID was already visible and evaluated, all the subsequent | ||||
| * updates and tags are to be done explicitly. */ | * updates and tags are to be done explicitly. */ | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| /* We only tag components which needs an update. Tagging everything is | /* We only tag components which needs an update. Tagging everything is | ||||
| * not a good idea because that might reset particles cache (or any | * not a good idea because that might reset particles cache (or any | ||||
| * other type of cache). | * other type of cache). | ||||
| * | * | ||||
| * TODO(sergey): Need to generalize this somehow. */ | * TODO(sergey): Need to generalize this somehow. */ | ||||
| if (id_type == ID_OB) { | if (id_type == ID_OB) { | ||||
| flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY; | flags |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY; | ||||
| } | } | ||||
| graph_id_tag_update(bmain, graph, id_node->id_orig, flag, DEG_UPDATE_SOURCE_VISIBILITY); | graph_id_tag_update(bmain, graph, id_node->id_orig, flags, DEG_UPDATE_SOURCE_VISIBILITY); | ||||
| if (id_type == ID_SCE) { | if (id_type == ID_SCE) { | ||||
| /* Make sure collection properties are up to date. */ | /* Make sure collection properties are up to date. */ | ||||
| id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY); | id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY); | ||||
| } | } | ||||
| /* Now when ID is updated to the new visibility state, prevent it from | /* Now when ID is updated to the new visibility state, prevent it from | ||||
| * being re-tagged again. Simplest way to do so is to pretend that it | * being re-tagged again. Simplest way to do so is to pretend that it | ||||
| * was already updated by the "previous" dependency graph. | * was already updated by the "previous" dependency graph. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | switch (id_type) { | ||||
| case ID_MSK: | case ID_MSK: | ||||
| return NodeType::PARAMETERS; | return NodeType::PARAMETERS; | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| return NodeType::UNDEFINED; | return NodeType::UNDEFINED; | ||||
| } | } | ||||
| void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source) | void id_tag_update(Main *bmain, ID *id, unsigned int flags, eUpdateSource update_source) | ||||
| { | { | ||||
| graph_id_tag_update(bmain, nullptr, id, flag, update_source); | graph_id_tag_update(bmain, nullptr, id, flags, update_source); | ||||
| for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) { | for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) { | ||||
| graph_id_tag_update(bmain, depsgraph, id, flag, update_source); | graph_id_tag_update(bmain, depsgraph, id, flags, update_source); | ||||
| } | } | ||||
| /* Accumulate all tags for an ID between two undo steps, so they can be | /* Accumulate all tags for an ID between two undo steps, so they can be | ||||
| * replayed for undo. */ | * replayed for undo. */ | ||||
| id->recalc_after_undo_push |= deg_recalc_flags_effective(nullptr, flag); | id->recalc_after_undo_push |= deg_recalc_flags_effective(nullptr, flags); | ||||
| } | } | ||||
| void graph_id_tag_update( | void graph_id_tag_update( | ||||
| Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source) | Main *bmain, Depsgraph *graph, ID *id, unsigned int flags, eUpdateSource update_source) | ||||
| { | { | ||||
| const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug; | const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug; | ||||
| if (graph != nullptr && graph->is_evaluating) { | if (graph != nullptr && graph->is_evaluating) { | ||||
| if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) { | if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) { | ||||
| printf("ID tagged for update during dependency graph evaluation.\n"); | printf("ID tagged for update during dependency graph evaluation.\n"); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) { | if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) { | ||||
| printf("%s: id=%s flags=%s source=%s\n", | printf("%s: id=%s flags=%s source=%s\n", | ||||
| __func__, | __func__, | ||||
| id->name, | id->name, | ||||
| stringify_update_bitfield(flag).c_str(), | stringify_update_bitfield(flags).c_str(), | ||||
| update_source_as_string(update_source)); | update_source_as_string(update_source)); | ||||
| } | } | ||||
| IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr; | IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr; | ||||
| if (graph != nullptr) { | if (graph != nullptr) { | ||||
| DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name)); | DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name)); | ||||
| } | } | ||||
| if (flag == 0) { | if (flags == 0) { | ||||
| deg_graph_node_tag_zero(bmain, graph, id_node, update_source); | deg_graph_node_tag_zero(bmain, graph, id_node, update_source); | ||||
| } | } | ||||
| /* Store original flag in the ID. | /* Store original flag in the ID. | ||||
| * Allows to have more granularity than a node-factory based flags. */ | * Allows to have more granularity than a node-factory based flags. */ | ||||
| if (id_node != nullptr) { | if (id_node != nullptr) { | ||||
| id_node->id_cow->recalc |= flag; | id_node->id_cow->recalc |= flags; | ||||
| } | } | ||||
| /* When ID is tagged for update based on an user edits store the recalc flags in the original ID. | /* 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 | * 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. | * 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.) | * This is the only way to ensure modifications to animation data (such as keyframes i.e.) | ||||
| * properly triggers animation update for the newly constructed dependency graph on redo (while | * properly triggers animation update for the newly constructed dependency graph on redo (while | ||||
| * usually newly created dependency graph skips animation update to avoid loss of unkeyed | * usually newly created dependency graph skips animation update to avoid loss of unkeyed | ||||
| * changes). */ | * changes). */ | ||||
| if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) { | if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) { | ||||
| id->recalc |= deg_recalc_flags_effective(graph, flag); | id->recalc |= deg_recalc_flags_effective(graph, flags); | ||||
| } | } | ||||
| int current_flag = flag; | unsigned int current_flag = flags; | ||||
| while (current_flag != 0) { | while (current_flag != 0) { | ||||
| IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_i(¤t_flag)); | IDRecalcFlag tag = (IDRecalcFlag)(1 << bitscan_forward_clear_uint(¤t_flag)); | ||||
| graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source); | graph_id_tag_update_single_flag(bmain, graph, id, id_node, tag, update_source); | ||||
| } | } | ||||
| /* Special case for nested node tree data-blocks. */ | /* Special case for nested node tree data-blocks. */ | ||||
| id_tag_update_ntree_special(bmain, graph, id, flag, update_source); | id_tag_update_ntree_special(bmain, graph, id, flags, update_source); | ||||
| /* Direct update tags means that something outside of simulated/cached | /* Direct update tags means that something outside of simulated/cached | ||||
| * physics did change and that cache is to be invalidated. | * physics did change and that cache is to be invalidated. | ||||
| * This is only needed if data changes. If it's just a drawing, we keep the | * This is only needed if data changes. If it's just a drawing, we keep the | ||||
| * point cache. */ | * point cache. */ | ||||
| if (update_source == DEG_UPDATE_SOURCE_USER_EDIT && flag != ID_RECALC_SHADING) { | if (update_source == DEG_UPDATE_SOURCE_USER_EDIT && flags != ID_RECALC_SHADING) { | ||||
| graph_id_tag_update_single_flag( | graph_id_tag_update_single_flag( | ||||
| bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source); | bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source); | ||||
| } | } | ||||
| } | } | ||||
| } // namespace blender::deg | } // namespace blender::deg | ||||
| const char *DEG_update_tag_as_string(IDRecalcFlag flag) | const char *DEG_update_tag_as_string(IDRecalcFlag flag) | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | switch (flag) { | ||||
| case ID_RECALC_SOURCE: | case ID_RECALC_SOURCE: | ||||
| return "SOURCE"; | return "SOURCE"; | ||||
| case ID_RECALC_ALL: | case ID_RECALC_ALL: | ||||
| return "ALL"; | return "ALL"; | ||||
| case ID_RECALC_TAG_FOR_UNDO: | case ID_RECALC_TAG_FOR_UNDO: | ||||
| return "TAG_FOR_UNDO"; | return "TAG_FOR_UNDO"; | ||||
| case ID_RECALC_NTREE_OUTPUT: | case ID_RECALC_NTREE_OUTPUT: | ||||
| return "ID_RECALC_NTREE_OUTPUT"; | return "ID_RECALC_NTREE_OUTPUT"; | ||||
| case ID_RECALC_PROVISION_26: | |||||
| case ID_RECALC_PROVISION_27: | |||||
| case ID_RECALC_PROVISION_28: | |||||
| case ID_RECALC_PROVISION_29: | |||||
| case ID_RECALC_PROVISION_30: | |||||
| case ID_RECALC_PROVISION_31: | |||||
| BLI_assert_msg(0, "Should not happen"); | |||||
| return nullptr; | |||||
| } | } | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| /* Data-Based Tagging. */ | /* Data-Based Tagging. */ | ||||
| void DEG_id_tag_update(ID *id, int flag) | void DEG_id_tag_update(ID *id, unsigned int flags) | ||||
| { | { | ||||
| DEG_id_tag_update_ex(G.main, id, flag); | DEG_id_tag_update_ex(G.main, id, flags); | ||||
| } | } | ||||
| void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag) | void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags) | ||||
| { | { | ||||
| if (id == nullptr) { | if (id == nullptr) { | ||||
| /* Ideally should not happen, but old depsgraph allowed this. */ | /* Ideally should not happen, but old depsgraph allowed this. */ | ||||
| return; | return; | ||||
| } | } | ||||
| deg::id_tag_update(bmain, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT); | deg::id_tag_update(bmain, id, flags, deg::DEG_UPDATE_SOURCE_USER_EDIT); | ||||
| } | } | ||||
| void DEG_graph_id_tag_update(struct Main *bmain, | void DEG_graph_id_tag_update(struct Main *bmain, | ||||
| struct Depsgraph *depsgraph, | struct Depsgraph *depsgraph, | ||||
| struct ID *id, | struct ID *id, | ||||
| int flag) | unsigned int flags) | ||||
| { | { | ||||
| deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph; | deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph; | ||||
| deg::graph_id_tag_update(bmain, graph, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT); | deg::graph_id_tag_update(bmain, graph, id, flags, deg::DEG_UPDATE_SOURCE_USER_EDIT); | ||||
| } | } | ||||
| void DEG_time_tag_update(struct Main *bmain) | void DEG_time_tag_update(struct Main *bmain) | ||||
| { | { | ||||
| for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) { | for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) { | ||||
| DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph)); | DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph)); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines | |||||