Loading...
Searching...
No Matches
score-plugin-gfx/Gfx/Graph/Node.hpp
1#pragma once
2#include <memory>
3#include <Gfx/Graph/CommonUBOs.hpp>
4#include <Gfx/Graph/Mesh.hpp>
5#include <Gfx/Graph/RenderState.hpp>
6#include <Gfx/Graph/Uniforms.hpp>
7#include <Gfx/Graph/Utils.hpp>
8
9#include <ossia/dataflow/geometry_port.hpp>
10#include <ossia/dataflow/nodes/media.hpp>
11#include <ossia/dataflow/texture_port.hpp>
12#include <ossia/dataflow/token_request.hpp>
13#include <ossia/detail/flat_map.hpp>
14#include <ossia/detail/variant.hpp>
15#include <ossia/network/value/value.hpp>
16
17#include <score_plugin_gfx_export.h>
18
19#include <boost/version.hpp>
20
21#include <algorithm>
22#include <vector>
23
24namespace score::gfx
25{
26struct PreviewTap;
27}
28
29namespace score::gfx
30{
31class RenderList;
32struct Graph;
33class GenericNodeRenderer;
34class NodeRenderer;
35using FunctionMessage = std::function<void(score::gfx::Node&)>;
36#if BOOST_VERSION < 107900
37#define a <::BOOST_VERSION>
38#include a
39#error Boost version not supported anymore
40#endif
41using gfx_input = ossia::variant<
42 ossia::monostate, ossia::value, ossia::audio_vector, ossia::render_target_spec,
43 ossia::transform3d, FunctionMessage, ossia::buffer_spec>;
44
50struct Timings
51{
52 ossia::time_value date{};
53 ossia::time_value parent_duration{};
56 double sample_rate{};
57};
58
59struct Message
60{
61 int32_t node_id{};
62 Timings token{};
63 std::vector<gfx_input> input;
67 uint64_t tick{};
68};
69
71{
72 QSize size;
73
74 QRhiTexture::Format format = QRhiTexture::Format ::RGBA8;
75
76 QRhiSampler::Filter mag_filter = QRhiSampler::Linear;
77 QRhiSampler::Filter min_filter = QRhiSampler::Linear;
78 QRhiSampler::Filter mipmap_mode = QRhiSampler::None;
79
80 QRhiSampler::AddressMode address_u = QRhiSampler::Repeat;
81 QRhiSampler::AddressMode address_v = QRhiSampler::Repeat;
82 QRhiSampler::AddressMode address_w = QRhiSampler::Repeat;
83
84 // Whether the inlet set the filters, the address modes, the mipmap mode.
85 // A field it did not set is the shader's, when its JSON declares one
86 // (resolveSamplerFields, shader board U34).
87 bool filter_set{};
88 bool address_set{};
89 bool mipmap_set{};
90};
91
95inline constexpr int unsetSamplerField = 3;
96inline bool isUnsetSamplerField(auto v) noexcept
97{
98 return (unsigned(v) & 3u) == unsigned(unsetSamplerField);
99}
100
103SCORE_PLUGIN_GFX_EXPORT
104RenderTargetSpecs toRenderTargetSpecs(const ossia::render_target_spec& in) noexcept;
105
108SCORE_PLUGIN_GFX_EXPORT
109void resolveSamplerFields(RenderTargetSpecs& spec, const isf::sampler_config& cfg) noexcept;
110
114class SCORE_PLUGIN_GFX_EXPORT Node : public QObject
115{
116public:
117 explicit Node();
118 virtual ~Node();
119
120 Node(const Node&) = delete;
121 Node(Node&&) = delete;
122 Node& operator=(const Node&) = delete;
123 Node& operator=(Node&&) = delete;
124
128 virtual NodeRenderer* createRenderer(RenderList& r) const noexcept = 0;
129
133 virtual void renderedNodesChanged();
134
138 virtual void process(Message&& msg);
139 virtual void update();
140
144 std::vector<Port*> input;
150 ossia::small_pod_vector<Port*, 1> output;
151
155 ossia::flat_map<RenderList*, score::gfx::NodeRenderer*> renderedNodes;
156
161 std::vector<std::shared_ptr<PreviewTap>> previewTaps;
162
168 ossia::flat_map<int32_t, ossia::render_target_spec> renderTargetSpecs;
169
173 void materialChange() noexcept
174 {
175 materialChanged.fetch_add(1, std::memory_order_release);
176 }
177 bool hasMaterialChanged(int64_t& renderer) const noexcept
178 {
179 int64_t res = materialChanged.load(std::memory_order_acquire);
180 if(renderer != res)
181 {
182 renderer = res;
183 return true;
184 }
185 return false;
186 }
187 std::atomic_int64_t materialChanged{0};
188
192 void renderTargetChange() noexcept
193 {
194 renderTargetSpecChanged.fetch_add(1, std::memory_order_release);
195 }
196 bool hasRenderTargetChanged(int64_t& renderer) const noexcept
197 {
198 int64_t res = renderTargetSpecChanged.load(std::memory_order_acquire);
199 if(renderer != res)
200 {
201 renderer = res;
202 return true;
203 }
204 return false;
205 }
206 std::atomic_int64_t renderTargetSpecChanged{-1};
207
208 int32_t nodeId = score::gfx::invalid_node_index;
209 bool requiresDepth{};
210
218 bool hasExplicitRenderTargetSize(int32_t port) const noexcept
219 {
220 auto it = renderTargetSpecs.find(port);
221 return it != renderTargetSpecs.end() && it->second.size.has_value();
222 }
223
229 bool hasExplicitRenderTargetSpecs(int32_t port) const noexcept
230 {
231 auto it = renderTargetSpecs.find(port);
232 return it != renderTargetSpecs.end()
233 && (it->second.size.has_value() || it->second.format_set
234 || it->second.format != ossia::texture_format::RGBA8);
235 }
236
237 QSize resolveRenderTargetSize(int32_t port, RenderList& renderer) const noexcept;
239 resolveRenderTargetSpecs(int32_t port, RenderList& renderer) const noexcept;
240
244 virtual void adjustRenderTargetSpecs(int32_t port, RenderTargetSpecs& spec) const noexcept;
245
257 std::optional<RenderTargetSpecs> firstInputRenderTargetSpecs() const noexcept;
258
259 void process(int32_t port, const ossia::render_target_spec& v);
260};
261
265class SCORE_PLUGIN_GFX_EXPORT ProcessNode : public Node
266{
267public:
268 using Node::Node;
269
275 ProcessUBO standardUBO{};
276
277 void process(Message&& msg) override;
278 virtual void process(Timings tk);
279 virtual void process(int32_t port, const ossia::value& v);
280 virtual void process(int32_t port, const ossia::audio_vector& v);
281 // virtual void process(int32_t port, const ossia::geometry_spec& v);
282 virtual void process(int32_t port, const ossia::transform3d& v);
283 void process(int32_t port, ossia::monostate) const noexcept { }
284 virtual void process(int32_t port, const FunctionMessage&);
285 virtual void process(int32_t port, const ossia::buffer_spec&);
286 using Node::process;
287
289 std::vector<int*> m_event_ports;
290
294 [[nodiscard]] bool resetEventPortsAfterFrame() noexcept
295 {
296 bool fired = false;
297 for(int* p : m_event_ports)
298 {
299 if(p && *p != 0)
300 {
301 *p = 0;
302 fired = true;
303 }
304 }
305 return fired;
306 }
307
308protected:
311 bool fireEventPort(int32_t port, const ossia::value& v) noexcept
312 {
313 if(!v.target<ossia::impulse>() || port < 0 || port >= int(this->input.size()))
314 return false;
315 auto* data = static_cast<int*>(this->input[port]->value);
316 if(std::find(m_event_ports.begin(), m_event_ports.end(), data)
317 == m_event_ports.end())
318 return false;
319 *data = 1;
320 this->materialChange();
321 return true;
322 }
323};
324
328class SCORE_PLUGIN_GFX_EXPORT NodeModel : public score::gfx::ProcessNode
329{
330public:
331 explicit NodeModel();
332 virtual ~NodeModel();
333
335 createRenderer(RenderList& r) const noexcept override;
336
337protected:
338 std::unique_ptr<char[]> m_materialData;
339
340 friend class GenericNodeRenderer;
341};
342}
343
344// QDebug operator<<(QDebug, const score::gfx::gfx_input&);
345QDebug operator<<(QDebug, const std::vector<score::gfx::gfx_input>&);
Generic renderer.
Definition NodeRenderer.hpp:337
Root data model for visual nodes.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:115
bool hasExplicitRenderTargetSize(int32_t port) const noexcept
Whether a given port has a user-specified render target size.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:218
ossia::flat_map< int32_t, ossia::render_target_spec > renderTargetSpecs
Render target info.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:168
std::vector< Port * > input
Input ports of that node.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:144
bool hasExplicitRenderTargetSpecs(int32_t port) const noexcept
Whether the user set a size or a format on a texture inlet.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:229
void renderTargetChange() noexcept
Used to notify a render target (texture inlet) change from the model to the renderers.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:192
void materialChange() noexcept
Used to notify a material change from the model to the renderers.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:173
std::vector< std::shared_ptr< PreviewTap > > previewTaps
Previews of the outputs of this node, read back by a render list of the patch that renders it....
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:161
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:155
virtual NodeRenderer * createRenderer(RenderList &r) const noexcept=0
Create a renderer in a given context for this node.
ossia::small_pod_vector< Port *, 1 > output
Output ports of that node.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:150
Common base class for most single-pass, simple nodes.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:329
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:266
bool fireEventPort(int32_t port, const ossia::value &v) noexcept
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:311
std::vector< int * > m_event_ports
Values of the EVENT inputs: 1 for the frame they fire in, else 0.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:289
bool resetEventPortsAfterFrame() noexcept
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:294
List of nodes to be rendered to an output.
Definition RenderList.hpp:36
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
RenderTargetSpecs toRenderTargetSpecs(const ossia::render_target_spec &in) noexcept
Definition score-plugin-gfx/Gfx/Graph/Node.cpp:445
void resolveSamplerFields(RenderTargetSpecs &spec, const isf::sampler_config &cfg) noexcept
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:2839
constexpr int unsetSamplerField
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:95
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:60
uint64_t tick
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:67
UBO specific to individual processes / nodes.
Definition CommonUBOs.hpp:23
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:71
Messages sent from the execution thread to the rendering thread.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:51
double sample_rate
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:56