From e5633114cd2c8d4aff8cea061d1fa5f144fb2a69 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 25 Apr 2018 15:04:25 +0200 Subject: [PATCH] Depsgraph: Preserve CoW ID recalc flags Previously they would have been replaced with flag from original datablock, which is not what we want. --- .../intern/eval/deg_eval_copy_on_write.cc | 2 + .../depsgraph/intern/eval/deg_eval_flush.cc | 41 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index f6a37c49d32..17d98e5e57a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -490,6 +490,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, { const ID *id_orig = id_node->id_orig; ID *id_cow = id_node->id_cow; + const int id_cow_recalc = id_cow->recalc; /* No need to expand such datablocks, their copied ID is same as original * one already. */ @@ -582,6 +583,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, if (newid != NULL) { MEM_freeN(newid); } + id_cow->recalc = id_orig->recalc | id_cow_recalc; return id_cow; } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 864d9d9e1ff..2778dadcb6e 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -301,7 +301,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) flush_editors_id_update(bmain, graph, &update_ctx); } -static void graph_clear_func( +static void graph_clear_operation_func( void *__restrict data_v, const int i, const ParallelRangeTLS *__restrict /*tls*/) @@ -312,18 +312,41 @@ static void graph_clear_func( node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE); } +static void graph_clear_id_node_func( + void *__restrict data_v, + const int i, + const ParallelRangeTLS *__restrict /*tls*/) +{ + Depsgraph *graph = (Depsgraph *)data_v; + IDDepsNode *id_node = graph->id_nodes[i]; + id_node->id_cow->recalc &= ~ID_RECALC_ALL; +} + /* Clear tags from all operation nodes. */ void deg_graph_clear_tags(Depsgraph *graph) { /* Go over all operation nodes, clearing tags. */ - const int num_operations = graph->operations.size(); - ParallelRangeSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.min_iter_per_thread = 1024; - BLI_task_parallel_range(0, num_operations, - graph, - graph_clear_func, - &settings); + { + const int num_operations = graph->operations.size(); + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.min_iter_per_thread = 1024; + BLI_task_parallel_range(0, num_operations, + graph, + graph_clear_operation_func, + &settings); + } + /* Go over all ID nodes nodes, clearing tags. */ + { + const int num_id_nodes = graph->id_nodes.size(); + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.min_iter_per_thread = 1024; + BLI_task_parallel_range(0, num_id_nodes, + graph, + graph_clear_id_node_func, + &settings); + } /* Clear any entry tags which haven't been flushed. */ BLI_gset_clear(graph->entry_tags, NULL); }