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