[Bf-blender-cvs] [27da305a404] master: Depsgraph: support flushing parameters without a full COW update

Campbell Barton noreply at git.blender.org
Thu Jun 24 12:25:13 CEST 2021


Commit: 27da305a404f72a75a37892e1ac080c6531d059b
Author: Campbell Barton
Date:   Thu Jun 24 19:13:52 2021 +1000
Branches: master
https://developer.blender.org/rB27da305a404f72a75a37892e1ac080c6531d059b

Depsgraph: support flushing parameters without a full COW update

Avoid computationally expensive copying operations
when only some settings have been modified.

This is done by adding support for updating parameters
without tagging for copy-on-write.

Currently only mesh data blocks are supported,
other data-blocks can be added individually.

This prepares for changing values such as edit-mesh auto-smooth angle
in edit-mode without duplicating all mesh-data.
The benefit will only be seen when the user interface no longer tags
all ID's for copy on write updates.

ID_RECALC_GEOMETRY_ALL_MODES has been added to support situations
where non edit-mode geometry is modified in edit-mode.
While this isn't something user are likely to do,
Python scripts may change the underlying mesh.

Reviewed By: sergey

Ref D11377

===================================================================

M	source/blender/blenkernel/BKE_lib_id.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/lib_id_eval.c
M	source/blender/blenkernel/intern/mesh_validate.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/depsgraph/intern/node/deg_node_component.h
M	source/blender/editors/mesh/editmesh_tools.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_mesh.c
M	source/blender/makesrna/intern/rna_mesh_api.c
M	source/blender/python/bmesh/bmesh_py_types.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index e16507bf3cc..fac5dc8c010 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -315,6 +315,9 @@ void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id);
 
 #define IS_TAGGED(_id) ((_id) && (((ID *)_id)->tag & LIB_TAG_DOIT))
 
+/* lib_id_eval.c */
+void BKE_id_eval_properties_copy(struct ID *id_cow, struct ID *id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0f36887b234..20663f0a790 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -165,6 +165,7 @@ set(SRC
   intern/layer_utils.c
   intern/lib_id.c
   intern/lib_id_delete.c
+  intern/lib_id_eval.c
   intern/lib_override.c
   intern/lib_query.c
   intern/lib_remap.c
diff --git a/source/blender/blenkernel/intern/lib_id_eval.c b/source/blender/blenkernel/intern/lib_id_eval.c
new file mode 100644
index 00000000000..140fe403ac3
--- /dev/null
+++ b/source/blender/blenkernel/intern/lib_id_eval.c
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ *
+ * Contains management of ID's and libraries
+ * allocate and free of all library data
+ */
+
+#include "DNA_ID.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_lib_id.h"
+#include "BKE_mesh.h"
+
+/**
+ * Copy relatives parameters, from `id` to `id_cow`.
+ * Use handle the #ID_RECALC_PARAMETERS tag.
+ * \note Keep in sync with #ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW.
+ */
+void BKE_id_eval_properties_copy(ID *id_cow, ID *id)
+{
+  const ID_Type id_type = GS(id->name);
+  BLI_assert((id_cow->tag & LIB_TAG_COPIED_ON_WRITE) && !(id->tag & LIB_TAG_COPIED_ON_WRITE));
+  BLI_assert(ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type));
+  if (id_type == ID_ME) {
+    BKE_mesh_copy_parameters((Mesh *)id_cow, (const Mesh *)id);
+  }
+  else {
+    BLI_assert_unreachable();
+  }
+}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index df84cf6607f..bfdbf844a26 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -1105,7 +1105,7 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
                                        &changed);
 
   if (changed) {
-    DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+    DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
     return true;
   }
 
@@ -1183,7 +1183,7 @@ bool BKE_mesh_validate_material_indices(Mesh *me)
   }
 
   if (!is_valid) {
-    DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+    DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
     return true;
   }
 
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 3494630e1fa..a7c6dc2deb9 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1810,7 +1810,7 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
 
   CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
   BKE_mesh_update_customdata_pointers(orig_me, true);
-  DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
+  DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
 }
 
 /** \warning Expects a fully evaluated depsgraph. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 20169f0a961..56168739fae 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1215,7 +1215,19 @@ void DepsgraphNodeBuilder::build_parameters(ID *id)
   op_node = add_operation_node(id, NodeType::PARAMETERS, OperationCode::PARAMETERS_ENTRY);
   op_node->set_as_entry();
   /* Generic evaluation node. */
-  add_operation_node(id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL);
+
+  if (ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(GS(id->name))) {
+    ID *id_cow = get_cow_id(id);
+    add_operation_node(
+        id,
+        NodeType::PARAMETERS,
+        OperationCode::PARAMETERS_EVAL,
+        [id_cow, id](::Depsgraph * /*depsgraph*/) { BKE_id_eval_properties_copy(id_cow, id); });
+  }
+  else {
+    add_operation_node(id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL);
+  }
+
   /* Explicit exit operation. */
   op_node = add_operation_node(id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EXIT);
   op_node->set_as_exit();
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 21a6728c364..b00cae87311 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -230,6 +230,7 @@ void depsgraph_tag_to_component_opcode(const ID *id,
     case ID_RECALC_SOURCE:
       *component_type = NodeType::PARAMETERS;
       break;
+    case ID_RECALC_GEOMETRY_ALL_MODES:
     case ID_RECALC_ALL:
     case ID_RECALC_PSYS_ALL:
       BLI_assert(!"Should not happen");
@@ -705,6 +706,8 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
       return "TRANSFORM";
     case ID_RECALC_GEOMETRY:
       return "GEOMETRY";
+    case ID_RECALC_GEOMETRY_ALL_MODES:
+      return "GEOMETRY_ALL_MODES";
     case ID_RECALC_ANIMATION:
       return "ANIMATION";
     case ID_RECALC_PSYS_REDO:
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index 06582c88d8b..a7c69b27654 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -23,7 +23,9 @@
 
 #pragma once
 
+#include "intern/eval/deg_eval_copy_on_write.h"
 #include "intern/node/deg_node.h"
+#include "intern/node/deg_node_id.h"
 #include "intern/node/deg_node_operation.h"
 
 #include "BLI_string.h"
@@ -172,7 +174,6 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(CopyOnWrite);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Geometry);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(ImageAnimation);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(LayerCollections);
-DEG_COMPONENT_NODE_DECLARE_GENERIC(Parameters);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Particles);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(ParticleSettings);
 DEG_COMPONENT_NODE_DECLARE_GENERIC(Pose);
@@ -199,6 +200,21 @@ struct BoneComponentNode : public ComponentNode {
   DEG_COMPONENT_NODE_DECLARE;
 };
 
+/* Eventually we would not tag parameters in all cases.
+ * Support for this each ID needs to be added on an individual basis. */
+struct ParametersComponentNode : public ComponentNode {
+  virtual bool need_tag_cow_before_update() override
+  {
+    if (ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(owner->id_type)) {
+      BLI_assert(deg_copy_on_write_is_expanded(owner->id_cow));
+      return false;
+    }
+    return true;
+  }
+
+  DEG_COMPONENT_NODE_DECLARE;
+};
+
 void deg_register_component_depsnodes();
 
 }  // namespace deg
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index ea4bdc551a2..ee520753478 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4753,7 +4753,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
                                  .calc_object_remap = true,
                              }));
 
-            DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+            DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
             WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
           }
 
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 16f5f0b4ae8..15a4f8817fd 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -454,6 +454,10 @@ typedef struct PreviewImage {
 #define ID_TYPE_IS_COW(_id_type) \
   (!ELEM(_id_type, ID_LI, ID_IP, ID_SCR, ID_VF, ID_BR, ID_WM, ID_PAL, ID_PC, ID_WS, ID_IM))
 
+/* Check whether data-block type requires copy-on-write from #ID_RECALC_PARAMETERS.
+ * Keep in sync with #BKE_id_eval_properties_copy. */
+#define ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type) ELEM(id_type, ID_ME)
+
 #ifdef GS
 #  undef GS
 #endif
@@ -602,10 +606,18 @@ typedef enum IDRecalcFlag {
    *
    * When object of armature type gets tagged with this flag, its pose is
    * re-evaluated.
+   *
    * When object of other type is tagged with this flag it makes the modifier
    * stack to be re-evaluated.
+   *
    * When object data type (mesh, curve, ...) gets tagged with this flag it
    * makes all objects which shares this data-block to be updated.
+   *
+   * Note that the evaluation depends on the object-mode.
+   * So edit-mesh data for example only reevaluate with the updated edit-mesh.
+   * When geometry in the original ID has been modified #ID_RECALC_GEOMETRY_ALL_MODES
+   * must be used instead.
+   *
    * When a collection gets tagged with this flag, all objects depending on the geometry and
    * transforms on any of the objects in the collection are updated. */
   ID_RECALC_GEOMETRY = (1 << 1),
@@ -665,6 +677,10 @@ typedef enum IDRecalcFlag {
 
   ID_RECALC_AUDIO = (1 << 20),
 
+  /* NOTE: This triggers copy on write for types that require it.
+   * Exceptions to this can be added using #ID_TYPE_SUPPORTS_PARAMS_WITHOUT_C

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list