Loading...
Searching...
No Matches
CpuAnalysisNode.hpp
1#pragma once
2
3#if SCORE_PLUGIN_GFX
4#include <Crousti/GfxNode.hpp>
5
6namespace oscr
7{
8
9template <typename Node_T>
10 requires(
11 (avnd::texture_output_introspection<Node_T>::size + avnd::buffer_output_introspection<Node_T>::size + avnd::geometry_output_introspection<Node_T>::size) == 0
12 )
13struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
14{
15 std::shared_ptr<Node_T> state;
16 score::gfx::Message m_last_message{};
17 ossia::time_value m_last_time{-1};
18
19 AVND_NO_UNIQUE_ADDRESS texture_inputs_storage<Node_T> texture_ins;
20 AVND_NO_UNIQUE_ADDRESS buffer_inputs_storage<Node_T> buffer_ins;
21 AVND_NO_UNIQUE_ADDRESS geometry_inputs_storage<Node_T> geometry_ins;
22
23 const GfxNode<Node_T>& node() const noexcept
24 {
25 return static_cast<const GfxNode<Node_T>&>(score::gfx::NodeRenderer::node);
26 }
27
28 GfxRenderer(const GfxNode<Node_T>& p)
29 : score::gfx::OutputNodeRenderer{p}
30 , state{std::make_shared<Node_T>()}
31 {
32 prepareNewState<Node_T>(state, p);
33 }
34
36 renderTargetForInput(const score::gfx::Port& p) override
37 {
38 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
39 {
40 auto it = texture_ins.m_rts.find(&p);
41 SCORE_ASSERT(it != texture_ins.m_rts.end());
42 return it->second;
43 }
44 return {};
45 }
46
47 void init(score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res) override
48 {
49 auto& parent = node();
50 if constexpr(requires { state->prepare(); })
51 {
52 this->node().processControlIn(
53 *this, *state, m_last_message, this->node().last_message, this->node().m_ctx);
54 state->prepare();
55 }
56
57 // Init input render targets
58 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
59 texture_ins.init(*this, renderer);
60
61 if_possible(state->init(renderer, res));
62 }
63
64 void update(
65 score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res,
66 score::gfx::Edge* e) override
67 {
68 auto& parent = node();
69 parent.processControlIn(
70 *this, *state, m_last_message, parent.last_message, parent.m_ctx);
71
72 bool updated = false;
73 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
74 {
75 updated |= texture_ins.update(*this, renderer, res);
76 }
77 if_possible(state->update(renderer, res, e));
78
79 if(updated)
80 {
81 // We must notify the graph that the previous nodes have to be recomputed
82 }
83 }
84
85 void release(score::gfx::RenderList& r) override
86 {
87 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
88 texture_ins.release();
89
90 if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
91 geometry_ins.release(r);
92
93 if constexpr(
94 avnd::texture_input_introspection<Node_T>::size > 0
95 || avnd::texture_output_introspection<Node_T>::size > 0)
96 {
97 // FIXME this->defaultRelease(r);
98 }
99
100 if_possible(state->release(r));
101 }
102
103 void inputAboutToFinish(
104 score::gfx::RenderList& renderer, const score::gfx::Port& p,
105 QRhiResourceUpdateBatch*& res) override
106 {
107 if constexpr(
108 avnd::texture_input_introspection<Node_T>::size > 0
109 || avnd::buffer_input_introspection<Node_T>::size > 0
110 || avnd::geometry_input_introspection<Node_T>::size > 0)
111 {
112 res = renderer.state.rhi->nextResourceUpdateBatch();
113
114 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
115 texture_ins.inputAboutToFinish(this->node(), p, res);
116 if constexpr(avnd::buffer_input_introspection<Node_T>::size > 0)
117 buffer_ins.inputAboutToFinish(renderer, res, *state, this->node());
118 if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
119 geometry_ins.inputAboutToFinish(
120 renderer, res, this->geometry, *state, this->node());
121 }
122
123 if_possible(state->inputAboutToFinish(renderer, p, res));
124 }
125
126 void runInitialPasses(
127 score::gfx::RenderList& renderer, QRhiCommandBuffer& commands,
128 QRhiResourceUpdateBatch*& res, score::gfx::Edge& edge) override
129 {
130 auto& parent = this->node();
131 auto& rhi = *renderer.state.rhi;
132
133 // Insert a synchronisation point to allow readbacks to complete
134 rhi.finish();
135
136 // If we are paused, we don't run the processor implementation.
137 if(parent.last_message.token.date == m_last_time)
138 return;
139 m_last_time = parent.last_message.token.date;
140
141 if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
142 texture_ins.runInitialPasses(*this, rhi);
143 if constexpr(avnd::buffer_input_introspection<Node_T>::size > 0)
144 buffer_ins.readInputBuffers(renderer, parent, *state);
145 if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
146 geometry_ins.readInputGeometries(renderer, this->geometry, parent, *state);
147
148 parent.processControlIn(
149 *this, *state, m_last_message, parent.last_message, parent.m_ctx);
150
151 // Run the processor
152 if_possible(state->runInitialPasses(renderer, commands, res, edge));
153 if_possible((*state)());
154
155 // Copy the data to the model node
156 parent.processControlOut(*this->state);
157 }
158};
159
160template <typename Node_T>
161 requires(
162 (avnd::texture_output_introspection<Node_T>::size + avnd::buffer_output_introspection<Node_T>::size + avnd::geometry_output_introspection<Node_T>::size) == 0
163 )
164struct GfxNode<Node_T> final
165 : CustomGpuOutputNodeBase
166 , GpuNodeElements<Node_T>
167{
168 oscr::ProcessModel<Node_T>& processModel;
169 GfxNode(
171 std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls ctls,
172 int64_t id, const score::DocumentContext& ctx)
173 : CustomGpuOutputNodeBase{std::move(q), std::move(ctls), ctx}
174 , processModel{element}
175 {
176 this->instance = id;
177
178 initGfxPorts<Node_T>(this, this->input, this->output);
179 }
180
182 createRenderer(score::gfx::RenderList& r) const noexcept override
183 {
184 return new GfxRenderer<Node_T>{*this};
185 }
186};
187}
188#endif
Definition score-plugin-avnd/Crousti/ProcessModel.hpp:86
Definition OutputNode.hpp:18
List of nodes to be rendered to an output.
Definition RenderList.hpp:19
RenderState & state
RenderState corresponding to this RenderList.
Definition RenderList.hpp:94
Definition Factories.hpp:19
Base toolkit upon which the software is built.
Definition Application.cpp:111
STL namespace.
Definition DocumentContext.hpp:18
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:71
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:49
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:53
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:116