[Bf-blender-cvs] [580675b0b41] temp-viewport-compositor-merge: Realtime Compositor: Validate node tree

Omar Emara noreply at git.blender.org
Wed Jun 15 11:51:35 CEST 2022


Commit: 580675b0b41289a0d42eaf8b765d17cb6516dade
Author: Omar Emara
Date:   Wed Jun 15 10:48:48 2022 +0200
Branches: temp-viewport-compositor-merge
https://developer.blender.org/rB580675b0b41289a0d42eaf8b765d17cb6516dade

Realtime Compositor: Validate node tree

Check if the node tree is valid and display an error message if it
isn't. This also removes unsupported nodes and simply displays an error
if the node tree contains one of them.

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

M	source/blender/compositor/realtime_compositor/CMakeLists.txt
M	source/blender/compositor/realtime_compositor/COM_context.hh
M	source/blender/compositor/realtime_compositor/COM_evaluator.hh
D	source/blender/compositor/realtime_compositor/COM_unsupported_node_operation.hh
M	source/blender/compositor/realtime_compositor/COM_utilities.hh
M	source/blender/compositor/realtime_compositor/intern/evaluator.cc
D	source/blender/compositor/realtime_compositor/intern/unsupported_node_operation.cc
M	source/blender/compositor/realtime_compositor/intern/utilities.cc
M	source/blender/draw/engines/compositor/compositor_engine.cc
M	source/blender/nodes/composite/nodes/node_composite_antialiasing.cc
M	source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
M	source/blender/nodes/composite/nodes/node_composite_bokehblur.cc
M	source/blender/nodes/composite/nodes/node_composite_bokehimage.cc
M	source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
M	source/blender/nodes/composite/nodes/node_composite_cornerpin.cc
M	source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
M	source/blender/nodes/composite/nodes/node_composite_defocus.cc
M	source/blender/nodes/composite/nodes/node_composite_denoise.cc
M	source/blender/nodes/composite/nodes/node_composite_despeckle.cc
M	source/blender/nodes/composite/nodes/node_composite_dilate.cc
M	source/blender/nodes/composite/nodes/node_composite_directionalblur.cc
M	source/blender/nodes/composite/nodes/node_composite_displace.cc
M	source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc
M	source/blender/nodes/composite/nodes/node_composite_glare.cc
M	source/blender/nodes/composite/nodes/node_composite_id_mask.cc
M	source/blender/nodes/composite/nodes/node_composite_inpaint.cc
M	source/blender/nodes/composite/nodes/node_composite_keying.cc
M	source/blender/nodes/composite/nodes/node_composite_keyingscreen.cc
M	source/blender/nodes/composite/nodes/node_composite_levels.cc
M	source/blender/nodes/composite/nodes/node_composite_map_uv.cc
M	source/blender/nodes/composite/nodes/node_composite_mask.cc
M	source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc
M	source/blender/nodes/composite/nodes/node_composite_normalize.cc
M	source/blender/nodes/composite/nodes/node_composite_output_file.cc
M	source/blender/nodes/composite/nodes/node_composite_pixelate.cc
M	source/blender/nodes/composite/nodes/node_composite_planetrackdeform.cc
M	source/blender/nodes/composite/nodes/node_composite_scale.cc
M	source/blender/nodes/composite/nodes/node_composite_stabilize2d.cc
M	source/blender/nodes/composite/nodes/node_composite_sunbeams.cc
M	source/blender/nodes/composite/nodes/node_composite_texture.cc
M	source/blender/nodes/composite/nodes/node_composite_tonemap.cc
M	source/blender/nodes/composite/nodes/node_composite_trackpos.cc
M	source/blender/nodes/composite/nodes/node_composite_vec_blur.cc
M	source/blender/nodes/composite/nodes/node_composite_zcombine.cc

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

diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt
index 7867da9951e..e4b48a6621e 100644
--- a/source/blender/compositor/realtime_compositor/CMakeLists.txt
+++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt
@@ -32,7 +32,6 @@ set(SRC
   intern/shader_pool.cc
   intern/simple_operation.cc
   intern/texture_pool.cc
-  intern/unsupported_node_operation.cc
   intern/utilities.cc
 
   COM_compile_state.hh
@@ -53,7 +52,6 @@ set(SRC
   COM_shader_pool.hh
   COM_simple_operation.hh
   COM_texture_pool.hh
-  COM_unsupported_node_operation.hh
   COM_utilities.hh
 )
 
diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh
index 08cb4008c8f..3772254412a 100644
--- a/source/blender/compositor/realtime_compositor/COM_context.hh
+++ b/source/blender/compositor/realtime_compositor/COM_context.hh
@@ -50,6 +50,11 @@ class Context {
   /* Get the name of the view currently being rendered. */
   virtual StringRef get_view_name() = 0;
 
+  /* Set an info message. This is called by the compositor evaluator to inform or warn the user
+   * about something, typically an error. The implementation should display the message in an
+   * appropriate place, which can be directly in the UI or just logged to the output stream. */
+  virtual void set_info_message(StringRef message) const = 0;
+
   /* Get the current frame number of the active scene. */
   int get_frame_number() const;
 
diff --git a/source/blender/compositor/realtime_compositor/COM_evaluator.hh b/source/blender/compositor/realtime_compositor/COM_evaluator.hh
index e5012482a55..fd6feb0948b 100644
--- a/source/blender/compositor/realtime_compositor/COM_evaluator.hh
+++ b/source/blender/compositor/realtime_compositor/COM_evaluator.hh
@@ -134,7 +134,15 @@ class Evaluator {
   void reset();
 
  private:
-  /* Compile the given node tree into an operations stream and evaluate it. */
+  /* Check if the compositor node tree is valid by checking if it has:
+   * - Cyclic links.
+   * - Undefined nodes or sockets.
+   * - Unsupported nodes.
+   * If the node tree is valid, true is returned. Otherwise, false is returned, and an appropriate
+   * error message is set by calling the context's set_info_message method. */
+  bool validate_node_tree();
+
+  /* Compile the node tree into an operations stream and evaluate it. */
   void compile_and_evaluate();
 
   /* Compile the given node into a node operation, map each input to the result of the output
diff --git a/source/blender/compositor/realtime_compositor/COM_unsupported_node_operation.hh b/source/blender/compositor/realtime_compositor/COM_unsupported_node_operation.hh
deleted file mode 100644
index e796cefe8ad..00000000000
--- a/source/blender/compositor/realtime_compositor/COM_unsupported_node_operation.hh
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-#include "COM_node_operation.hh"
-
-namespace blender::realtime_compositor {
-
-/* ------------------------------------------------------------------------------------------------
- * Unsupported Node Operation
- *
- * A node operation that sets all of its outputs to zero. This is used as a stub for nodes that are
- * not implemented yet.  */
-class UnsupportedNodeOperation : public NodeOperation {
- public:
-  using NodeOperation::NodeOperation;
-
-  void execute() override;
-};
-
-}  // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_utilities.hh b/source/blender/compositor/realtime_compositor/COM_utilities.hh
index f73f8db8e7c..0e359c2090a 100644
--- a/source/blender/compositor/realtime_compositor/COM_utilities.hh
+++ b/source/blender/compositor/realtime_compositor/COM_utilities.hh
@@ -41,6 +41,10 @@ int number_of_inputs_linked_to_output_conditioned(DOutputSocket output,
 /* A node is a shader node if it defines a method to get a shader node operation. */
 bool is_shader_node(DNode node);
 
+/* Returns true if the given node is supported, that is, have an implementation. Returns false
+ * otherwise. */
+bool is_node_supported(DNode node);
+
 /* Get the input descriptor of the given input socket. */
 InputDescriptor input_descriptor_from_input_socket(const InputSocketRef *socket);
 
diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
index f43ec372063..af27b89ca26 100644
--- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc
+++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#include <string>
+
 #include "DNA_node_types.h"
 
 #include "NOD_derived_node_tree.hh"
@@ -54,11 +56,47 @@ void Evaluator::reset()
   is_compiled_ = false;
 }
 
+bool Evaluator::validate_node_tree()
+{
+  if (derived_node_tree_->has_link_cycles()) {
+    context_.set_info_message("Compositor node tree has cyclic links!");
+    return false;
+  }
+
+  if (derived_node_tree_->has_undefined_nodes_or_sockets()) {
+    context_.set_info_message("Compositor node tree has undefined nodes or sockets!");
+    return false;
+  }
+
+  /* Find any of the unsupported nodes in the node tree. We only track one of them because we
+   * display a message for only one at a time to avoid long messages. */
+  DNode unsupported_node;
+  derived_node_tree_->foreach_node([&](DNode node) {
+    if (!is_node_supported(node)) {
+      unsupported_node = node;
+    }
+  });
+
+  /* unsupported_node is null if no unsupported node was found. */
+  if (unsupported_node) {
+    std::string message = "Compositor node tree has an unsupported node: ";
+    context_.set_info_message(message + unsupported_node->idname());
+    return false;
+  }
+
+  return true;
+}
+
 void Evaluator::compile_and_evaluate()
 {
   /* Construct and initialize a derived node tree from the compositor node tree. */
   derived_node_tree_.reset(new DerivedNodeTree(node_tree_, node_tree_reference_map_));
 
+  /* Validate the node tree and do nothing if it is invalid. */
+  if (!validate_node_tree()) {
+    return;
+  }
+
   /* Compute the node execution schedule. */
   const Schedule schedule = compute_schedule(*derived_node_tree_);
 
diff --git a/source/blender/compositor/realtime_compositor/intern/unsupported_node_operation.cc b/source/blender/compositor/realtime_compositor/intern/unsupported_node_operation.cc
deleted file mode 100644
index 85c826fc60f..00000000000
--- a/source/blender/compositor/realtime_compositor/intern/unsupported_node_operation.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "COM_result.hh"
-#include "COM_unsupported_node_operation.hh"
-
-namespace blender::realtime_compositor {
-
-using namespace nodes::derived_node_tree_types;
-
-void UnsupportedNodeOperation::execute()
-{
-  for (const OutputSocketRef *output : node()->outputs()) {
-    if (!should_compute_output(output->identifier())) {
-      continue;
-    }
-    Result &result = get_result(output->identifier());
-    result.allocate_invalid();
-  }
-}
-
-}  // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc
index 39b366af9a6..06e82bba52b 100644
--- a/source/blender/compositor/realtime_compositor/intern/utilities.cc
+++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc
@@ -97,6 +97,12 @@ bool is_shader_node(DNode node)
   return node->typeinfo()->get_compositor_shader_node;
 }
 
+bool is_node_supported(DNode node)
+{
+  return node->typeinfo()->get_compositor_operation ||
+         node->typeinfo()->get_compositor_shader_node;
+}
+
 InputDescriptor input_descriptor_from_input_socket(const InputSocketRef *socket)
 {
   using namespace nodes;
diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc
index 18e5a9d94e5..d7feb62cb18 100644
--- a/source/blender/draw/engines/compositor/compositor_engine.cc
+++ b/source/blender/draw/engines/compositor/compositor_engine.cc
@@ -34,8 +34,16 @@ class DRWTexturePool : public TexturePool {
 };
 
 class DRWContext : public Context {
+ private:
+  /* A pointer to the info message of the compositor engine. This is a char array of size
+   * GPU_INFO_SIZE. The message is cleared prior to updating or evaluating the compositor. */
+  char *info_message_;
+
  public:
-  using Context::Context;
+  DRWContext(TexturePool &texture_pool, char *info_message)
+      : Context(texture_pool), info_message_(info_message)
+  {
+  }
 
   const Scene *get_scene() const override
   {
@@ -63,6 +71,11 @@ class DRWContext : public Context {
         BLI_findlink(&get_scene()->r.views, DRW_context_state_get()->v3d->multiview_eye));
     return view->name;
   }
+
+  void set_info_message(StringRef message) const override
+  {
+    message.copy(info_message_, GPU_INFO_SIZE);
+  }
 };
 
 class Engine {
@@ -75,8 +88,8 @@ class Engine {
   int2 last_viewport_size_;
 
  public:
-  Engine()
-      : context_(texture_pool_),
+  Engine(char *info_message)
+      : context_(texture_pool_, info_message),
         evaluator_(context_, node_tree()),
         last_viewport_size_(context_.get_viewport_size())
   {
@@ -130,6 +143,7 @@ typedef struct CompositorData {
   DRWViewportEmptyList *psl;
   DRWViewportEmptyList *stl;
   Engine *instance_data;
+  char info[GPU_INFO_SIZE];
 } CompositorData;
 
 static void compositor_engine_init(void *data)
@@ -137,7 +151,7 @@ static void compositor_engine_init(void *data)
   CompositorData *compositor_data = static_cast<CompositorData *>(data);
 
   if (!compositor_data->instance_data) {
-    compositor_data->instance_data = new Engine();
+    compositor_data->instance_data = new Engine(compositor_data->info);
   }
 }
 
@@ -155,7 +169,11 @@ static void compositor_engine_draw(void *data)
 
 static void compositor_engine_update(void *data)
 {
-  const CompositorData *compositor_data = static_cast<CompositorData *>(data);
+  CompositorD

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list