[Bf-blender-cvs] [f12f7800c29] master: Depsgraph: Optimize evaluation of dependencies of disabled modifiers

Sergey Sharybin noreply at git.blender.org
Wed Aug 10 11:02:42 CEST 2022


Commit: f12f7800c2965c721a4eb4baeb6b1ab129bfa375
Author: Sergey Sharybin
Date:   Thu Aug 4 15:04:25 2022 +0200
Branches: master
https://developer.blender.org/rBf12f7800c2965c721a4eb4baeb6b1ab129bfa375

Depsgraph: Optimize evaluation of dependencies of disabled modifiers

Solves long-standing issue when dependencies of disabled modifiers are
evaluated.

Simple test case: no drivers or animation. Manually enabling modifier
is expected to bring FPS up, enabling modifier will bring FPS (sine
evaluation can not be avoided)

F13336690

More complex test case: modifier visibility is driven by an animated
property. In am ideal world FPS during property being zero is fast
and when property is 1 the FPS is low.

F13336691.

Differential Revision: https://developer.blender.org/D15625

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

M	source/blender/depsgraph/intern/builder/deg_builder.cc
M	source/blender/depsgraph/intern/builder/deg_builder.h
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/builder/deg_builder_rna.cc
M	source/blender/depsgraph/intern/depsgraph_relation.h
M	source/blender/depsgraph/intern/eval/deg_eval.cc
M	source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
M	source/blender/depsgraph/intern/eval/deg_eval_visibility.h
M	source/blender/depsgraph/intern/node/deg_node_operation.cc
M	source/blender/depsgraph/intern/node/deg_node_operation.h

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 5353f71685c..097c377ece4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -13,6 +13,7 @@
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_layer_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 
 #include "BLI_stack.h"
@@ -95,6 +96,24 @@ bool DepsgraphBuilder::is_object_visibility_animated(const Object *object)
   return cache_->isPropertyAnimated(&object->id, property_id);
 }
 
+bool DepsgraphBuilder::is_modifier_visibility_animated(const Object *object,
+                                                       const ModifierData *modifier)
+{
+  AnimatedPropertyID property_id;
+  if (graph_->mode == DAG_EVAL_VIEWPORT) {
+    property_id = AnimatedPropertyID(
+        &object->id, &RNA_Modifier, (void *)modifier, "show_viewport");
+  }
+  else if (graph_->mode == DAG_EVAL_RENDER) {
+    property_id = AnimatedPropertyID(&object->id, &RNA_Modifier, (void *)modifier, "show_render");
+  }
+  else {
+    BLI_assert_msg(0, "Unknown evaluation mode.");
+    return false;
+  }
+  return cache_->isPropertyAnimated(&object->id, property_id);
+}
+
 bool DepsgraphBuilder::check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan)
 {
   BLI_assert(object->type == OB_ARMATURE);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index c44e5fd5f4d..5d043f1fd3a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -10,6 +10,7 @@
 struct Base;
 struct ID;
 struct Main;
+struct ModifierData;
 struct Object;
 struct bPoseChannel;
 
@@ -25,6 +26,7 @@ class DepsgraphBuilder {
   virtual bool need_pull_base_into_graph(const Base *base);
 
   virtual bool is_object_visibility_animated(const Object *object);
+  virtual bool is_modifier_visibility_animated(const Object *object, const ModifierData *modifier);
 
   virtual bool check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan);
   virtual bool check_pchan_has_bbone_segments(const Object *object, const bPoseChannel *pchan);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 025b2cf21a8..dd62a6cdea2 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -879,9 +879,31 @@ void DepsgraphNodeBuilder::build_object_modifiers(Object *object)
     return;
   }
 
+  const ModifierMode modifier_mode = (graph_->mode == DAG_EVAL_VIEWPORT) ? eModifierMode_Realtime :
+                                                                           eModifierMode_Render;
+
+  IDNode *id_node = find_id_node(&object->id);
+
+  add_operation_node(&object->id,
+                     NodeType::GEOMETRY,
+                     OperationCode::VISIBILITY,
+                     [id_node](::Depsgraph *depsgraph) {
+                       deg_evaluate_object_modifiers_mode_node_visibility(depsgraph, id_node);
+                     });
+
   LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
-    add_operation_node(
+    OperationNode *modifier_node = add_operation_node(
         &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name);
+
+    /* Mute modifier mode if the modifier is not enabled for the dependency graph mode.
+     * This handles static (non-animated) mode of the modifier. */
+    if ((modifier->mode & modifier_mode) == 0) {
+      modifier_node->flag |= DEPSOP_FLAG_MUTE;
+    }
+
+    if (is_modifier_visibility_animated(object, modifier)) {
+      graph_->has_animated_visibility = true;
+    }
   }
 
   BuilderWalkUserData data;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 8b51ed214a2..d6ee1286fc4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -877,6 +877,16 @@ void DepsgraphRelationBuilder::build_object_modifiers(Object *object)
       &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
   const OperationKey eval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
 
+  const ComponentKey object_visibility_key(&object->id, NodeType::VISIBILITY);
+  const OperationKey modifier_visibility_key(
+      &object->id, NodeType::GEOMETRY, OperationCode::VISIBILITY);
+  add_relation(modifier_visibility_key,
+               object_visibility_key,
+               "modifier -> object visibility",
+               RELATION_NO_VISIBILITY_CHANGE);
+
+  add_relation(modifier_visibility_key, eval_key, "modifier visibility -> geometry eval");
+
   ModifierUpdateDepsgraphContext ctx = {};
   ctx.scene = scene_;
   ctx.object = object;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 5202ada5408..d94746fb7fa 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -225,6 +225,10 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
     }
     return node_identifier;
   }
+
+  const char *prop_identifier = prop != nullptr ? RNA_property_identifier((PropertyRNA *)prop) :
+                                                  "";
+
   if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
     const Object *object = reinterpret_cast<const Object *>(ptr->owner_id);
     const bConstraint *constraint = static_cast<const bConstraint *>(ptr->data);
@@ -264,6 +268,13 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
       return node_identifier;
     }
   }
+  else if (RNA_struct_is_a(ptr->type, &RNA_Modifier) &&
+           (contains(prop_identifier, "show_viewport") ||
+            contains(prop_identifier, "show_render"))) {
+    node_identifier.type = NodeType::GEOMETRY;
+    node_identifier.operation_code = OperationCode::VISIBILITY;
+    return node_identifier;
+  }
   else if (RNA_struct_is_a(ptr->type, &RNA_Mesh) || RNA_struct_is_a(ptr->type, &RNA_Modifier) ||
            RNA_struct_is_a(ptr->type, &RNA_GpencilModifier) ||
            RNA_struct_is_a(ptr->type, &RNA_Spline) || RNA_struct_is_a(ptr->type, &RNA_TextBox) ||
@@ -290,7 +301,6 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
   else if (ptr->type == &RNA_Object) {
     /* Transforms props? */
     if (prop != nullptr) {
-      const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
       /* TODO(sergey): How to optimize this? */
       if (contains(prop_identifier, "location") || contains(prop_identifier, "matrix_basis") ||
           contains(prop_identifier, "matrix_channel") ||
diff --git a/source/blender/depsgraph/intern/depsgraph_relation.h b/source/blender/depsgraph/intern/depsgraph_relation.h
index 1bacb9abfa6..3f316fa84e8 100644
--- a/source/blender/depsgraph/intern/depsgraph_relation.h
+++ b/source/blender/depsgraph/intern/depsgraph_relation.h
@@ -28,6 +28,8 @@ enum RelationFlag {
   RELATION_FLAG_GODMODE = (1 << 4),
   /* Relation will check existence before being added. */
   RELATION_CHECK_BEFORE_ADD = (1 << 5),
+  /* The relation does not participate in visibility checks. */
+  RELATION_NO_VISIBILITY_CHANGE = (1 << 6),
 };
 
 /* B depends on A (A -> B) */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 9b2ce2bb707..cd0015ff717 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -437,7 +437,7 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
 
   evaluate_graph_threaded_stage(&state, task_pool, EvaluationStage::COPY_ON_WRITE);
 
-  if (graph->has_animated_visibility) {
+  if (graph->has_animated_visibility || graph->need_update_nodes_visibility) {
     /* Update pending parents including only the ones which are affecting operations which are
      * affecting visibility. */
     state.need_update_pending_parents = true;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
index 05f7631b0d4..7b6aec0a73c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
@@ -8,6 +8,7 @@
 #include "intern/eval/deg_eval_visibility.h"
 
 #include "DNA_layer_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 
 #include "BLI_assert.h"
@@ -47,6 +48,38 @@ void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node
   }
 }
 
+void deg_evaluate_object_modifiers_mode_node_visibility(::Depsgraph *depsgraph, IDNode *id_node)
+{
+  BLI_assert(GS(id_node->id_cow->name) == ID_OB);
+
+  Depsgraph *graph = reinterpret_cast<Depsgraph *>(depsgraph);
+  const Object *object = reinterpret_cast<const Object *>(id_node->id_cow);
+
+  DEG_debug_print_eval(depsgraph, __func__, object->id.name, &object->id);
+
+  if (BLI_listbase_is_empty(&object->modifiers)) {
+    return;
+  }
+
+  const ModifierMode modifier_mode = (graph->mode == DAG_EVAL_VIEWPORT) ? eModifierMode_Realtime :
+                                                                          eModifierMode_Render;
+
+  const ComponentNode *geometry_component = id_node->find_component(NodeType::GEOMETRY);
+  LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
+    OperationNode *modifier_node = geometry_component->find_operation(OperationCode::MODIFIER,
+                                                                      modifier->name);
+
+    const bool modifier_enabled = modifier->mode & modifier_mode;
+    const int mute_flag = modifier_enabled ? 0 : DEPSOP_FLAG_MUTE;
+    if ((modifier_node->flag & DEPSOP_FLAG_MUTE) != mute_flag) {
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list