score-plugin-gfx/Gfx/Graph/Node.hpp
1 #pragma once
2 #include <Gfx/Graph/CommonUBOs.hpp>
3 #include <Gfx/Graph/Mesh.hpp>
4 #include <Gfx/Graph/RenderState.hpp>
5 #include <Gfx/Graph/Uniforms.hpp>
6 #include <Gfx/Graph/Utils.hpp>
7 
8 #include <ossia/dataflow/geometry_port.hpp>
9 #include <ossia/dataflow/nodes/media.hpp>
10 #include <ossia/dataflow/token_request.hpp>
11 #include <ossia/detail/flat_map.hpp>
12 #include <ossia/detail/variant.hpp>
13 #include <ossia/network/value/value.hpp>
14 
15 #include <score_plugin_gfx_export.h>
16 
17 #include <algorithm>
18 #include <optional>
19 #include <vector>
20 
21 namespace score::gfx
22 {
23 class RenderList;
24 struct Graph;
25 class GenericNodeRenderer;
26 class NodeRenderer;
27 using FunctionMessage = std::function<void(score::gfx::Node&)>;
28 #if BOOST_VERSION < 107900
29 // Old boost: small_vector was not nothrow-move-constructible so we remove the check there.
30 using gfx_input = ossia::slow_variant<
31  ossia::monostate, ossia::value, ossia::audio_vector, ossia::mesh_list_ptr,
32  ossia::transform3d, FunctionMessage>;
33 #else
34 using gfx_input = ossia::variant<
35  ossia::monostate, ossia::value, ossia::audio_vector, ossia::mesh_list_ptr,
36  ossia::transform3d, FunctionMessage>;
37 #endif
38 
44 struct Timings
45 {
46  ossia::time_value date{};
47  ossia::time_value parent_duration{};
48 };
49 
50 struct Message
51 {
52  int32_t node_id{};
53  Timings token{};
54  std::vector<gfx_input> input;
55 };
59 class SCORE_PLUGIN_GFX_EXPORT Node
60 {
61 public:
62  explicit Node();
63  virtual ~Node();
64 
65  Node(const Node&) = delete;
66  Node(Node&&) = delete;
67  Node& operator=(const Node&) = delete;
68  Node& operator=(Node&&) = delete;
69 
73  virtual NodeRenderer* createRenderer(RenderList& r) const noexcept = 0;
74 
78  virtual void renderedNodesChanged();
79 
83  virtual void process(Message&& msg);
84  virtual void update();
85 
89  std::vector<Port*> input;
95  ossia::small_pod_vector<Port*, 1> output;
96 
100  ossia::flat_map<RenderList*, score::gfx::NodeRenderer*> renderedNodes;
101 
102  bool addedToGraph{};
103 };
104 
108 class SCORE_PLUGIN_GFX_EXPORT ProcessNode : public Node
109 {
110 public:
111  using Node::Node;
112 
116  void materialChange() noexcept
117  {
118  materialChanged.fetch_add(1, std::memory_order_release);
119  }
120  bool hasMaterialChanged(int64_t& renderer) const noexcept
121  {
122  int64_t res = materialChanged.load(std::memory_order_acquire);
123  if(renderer != res)
124  {
125  renderer = res;
126  return true;
127  }
128  return false;
129  }
130  std::atomic_int64_t materialChanged{0};
131 
135  void geometryChange() noexcept
136  {
137  geometryChanged.fetch_add(1, std::memory_order_release);
138  }
139  bool hasGeometryChanged(int64_t& renderer) const noexcept
140  {
141  int64_t res = geometryChanged.load(std::memory_order_acquire);
142  if(renderer != res)
143  {
144  renderer = res;
145  return true;
146  }
147  return false;
148  }
149  std::atomic_int64_t geometryChanged{-1};
150 
156  ProcessUBO standardUBO{};
157 
164  std::shared_ptr<ossia::mesh_list> geometry;
165 
166  void process(Message&& msg) override;
167  void process(Timings tk);
168  void process(int32_t port, const ossia::value& v);
169  void process(int32_t port, const ossia::audio_vector& v);
170  void process(int32_t port, const ossia::mesh_list_ptr& v);
171  void process(int32_t port, const ossia::transform3d& v);
172  void process(int32_t port, ossia::monostate) const noexcept { }
173  void process(int32_t port, const FunctionMessage&);
174 };
175 
179 class SCORE_PLUGIN_GFX_EXPORT NodeModel : public score::gfx::ProcessNode
180 {
181 public:
182  explicit NodeModel();
183  virtual ~NodeModel();
184 
185  virtual score::gfx::NodeRenderer*
186  createRenderer(RenderList& r) const noexcept override;
187 
188 protected:
189  std::unique_ptr<char[]> m_materialData;
190 
191  friend class GenericNodeRenderer;
192 };
193 }
194 
195 // QDebug operator<<(QDebug, const score::gfx::gfx_input&);
196 QDebug operator<<(QDebug, const std::vector<score::gfx::gfx_input>&);
Generic renderer.
Definition: NodeRenderer.hpp:59
Root data model for visual nodes.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:60
std::vector< Port * > input
Input ports of that node.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:89
virtual NodeRenderer * createRenderer(RenderList &r) const noexcept=0
Create a renderer in a given context for this node.
ossia::flat_map< RenderList *, score::gfx::NodeRenderer * > renderedNodes
Map associating each RenderList to a Renderer for this model.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:100
ossia::small_pod_vector< Port *, 1 > output
Output ports of that node.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:95
Common base class for most single-pass, simple nodes.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:180
Renderer for a given node.
Definition: NodeRenderer.hpp:11
Common base class for nodes that map to score processes.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:109
void geometryChange() noexcept
Used to notify a geometry change from the model to the renderers.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:135
std::shared_ptr< ossia::mesh_list > geometry
The geometry to use.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:164
void materialChange() noexcept
Used to notify a material change from the model to the renderers.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:116
List of nodes to be rendered to an output.
Definition: RenderList.hpp:19
Graphics rendering pipeline for ossia score.
Definition: PreviewWidget.hpp:12
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:51
UBO specific to individual processes / nodes.
Definition: CommonUBOs.hpp:12
Messages sent from the execution thread to the rendering thread.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:45