MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BufferQuery.cpp
Go to the documentation of this file.
1#include "Inspector.hpp"
2
8
11
13
15
16// -----------------------------------------------------------------------------
17// Single buffer + processing chain
18// -----------------------------------------------------------------------------
19
21 const std::shared_ptr<Buffers::Buffer>& buf,
22 Surface& surface,
23 LayoutCursor& cursor,
24 float x_min, float x_max, float row_h, int depth)
25{
26 const float ind = x_min + static_cast<float>(depth) * k_inspect_indent;
27 const std::string header_label = Reflect::short_dynamic_type_name(*buf);
28
29 std::vector<ValueSpec> values {
30 ValueSpec {
31 .label = "default_proc",
32 .reader = [buf] {
33 auto p = buf->get_default_processor();
34 return p ? std::string(Reflect::short_dynamic_type_name(*p)) : "-";
35 },
36 },
37 };
38
39 auto chain = buf->get_processing_chain();
40 if (chain) {
41 auto pre = chain->get_preprocessor(buf);
42 values.push_back(ValueSpec {
43 .label = "pre",
44 .reader = [pre] {
45 return pre ? std::string(Reflect::short_dynamic_type_name(*pre)) : "-";
46 },
47 });
48
49 const auto& processors = chain->get_processors(buf);
50 for (size_t i = 0; i < processors.size(); ++i) {
51 auto p = processors[i];
52 values.push_back(ValueSpec {
53 .label = "chain[" + std::to_string(i) + "]",
54 .reader = [p] {
55 return p ? std::string(Reflect::short_dynamic_type_name(*p)) : "-";
56 },
57 });
58 }
59
60 auto post = chain->get_postprocessor(buf);
61 values.push_back(ValueSpec {
62 .label = "post",
63 .reader = [post] {
64 return post ? std::string(Reflect::short_dynamic_type_name(*post)) : "-";
65 },
66 });
67
68 auto final_p = chain->get_final_processor(buf);
69 values.push_back(ValueSpec {
70 .label = "final",
71 .reader = [final_p] {
72 return final_p ? std::string(Reflect::short_dynamic_type_name(*final_p)) : "-";
73 },
74 });
75 }
76
77 const auto dims = row_pixel_dims(surface.window(), ind, x_max, row_h);
78 auto hbuf = make_row_buffer(surface.window(), header_label, dims);
79 std::vector<RowBuffer> rbufs;
80 rbufs.reserve(values.size());
81
82 for (const auto& spec : values)
83 rbufs.push_back(make_row_buffer(surface.window(), spec.label, dims));
84 auto group = make_value_group(values, std::move(hbuf), rbufs,
85 surface, cursor, ind, x_max, row_h, false);
86
87 InspectResult result;
88 result.group = std::move(group);
89 return result;
90}
91
92// -----------------------------------------------------------------------------
93// Root audio buffer: single channel
94// -----------------------------------------------------------------------------
95
97 Buffers::ProcessingToken token, uint32_t channel,
98 Surface& surface,
99 LayoutCursor& cursor,
100 float x_min, float x_max, float row_h, int depth)
101{
102 auto root = m_bm.get_root_audio_buffer(token, channel);
103 const auto children = root->get_child_buffers();
104
105 const float ind = x_min + static_cast<float>(depth) * k_inspect_indent;
106 const std::string header_label = "ch " + std::to_string(channel);
107
108 std::vector<ValueSpec> values {
109 ValueSpec {
110 .label = "samples",
111 .reader = [root] { return std::to_string(root->get_num_samples()); },
112 },
113 ValueSpec {
114 .label = "children",
115 .reader = [root] { return std::to_string(root->get_num_children()); },
116 },
117 };
118
119 const auto dims = row_pixel_dims(surface.window(), ind, x_max, row_h);
120 auto hbuf = make_row_buffer(surface.window(), header_label, dims);
121 std::vector<RowBuffer> rbufs;
122 rbufs.reserve(values.size());
123 for (const auto& spec : values)
124 rbufs.push_back(make_row_buffer(surface.window(), spec.label, dims));
125 auto group = make_value_group(values, std::move(hbuf), rbufs,
126 surface, cursor, ind, x_max, row_h, false);
127
128 InspectResult result;
129 result.group = std::move(group);
130
131 auto root_result = buffer(
132 root, surface, cursor,
133 x_min, x_max, row_h, depth + 1);
134 surface.layer().relate(result.group.header.header_id, root_result.group.header.header_id);
135 result.children.push_back(std::move(root_result));
136
137 for (const auto& child : children) {
138 auto child_result = buffer(
139 child, surface, cursor,
140 x_min, x_max, row_h, depth + 2);
141 surface.layer().relate(result.group.header.header_id, child_result.group.header.header_id);
142 result.children.push_back(std::move(child_result));
143 }
144
145 return result;
146}
147
148// -----------------------------------------------------------------------------
149// Root audio buffer: all channels
150// -----------------------------------------------------------------------------
151
154 Surface& surface,
155 LayoutCursor& cursor,
156 float x_min, float x_max, float row_h, int depth)
157{
158 const uint32_t ch_count = m_bm.get_num_channels(token);
159
160 const float ind = x_min + static_cast<float>(depth) * k_inspect_indent;
161 const std::string header_label = std::string(Reflect::enum_to_string(token))
162 + " [" + std::to_string(ch_count) + " ch]";
163
164 auto& bm = m_bm;
165 std::vector<ValueSpec> values {
166 ValueSpec {
167 .label = "channels",
168 .reader = [&bm, token] { return std::to_string(bm.get_num_channels(token)); },
169 },
170 };
171
172 const auto dims = row_pixel_dims(surface.window(), ind, x_max, row_h);
173 auto hbuf = make_row_buffer(surface.window(), header_label, dims);
174 std::vector<RowBuffer> rbufs;
175 rbufs.reserve(values.size());
176 for (const auto& spec : values)
177 rbufs.push_back(make_row_buffer(surface.window(), spec.label, dims));
178 auto group = make_value_group(values, std::move(hbuf), rbufs,
179 surface, cursor, ind, x_max, row_h, false);
180
181 InspectResult result;
182 result.group = std::move(group);
183
184 for (uint32_t ch = 0; ch < ch_count; ++ch) {
185 auto ch_result = root_audio_buffer(
186 token, ch,
187 surface, cursor,
188 x_min, x_max, row_h, depth + 1);
189 surface.layer().relate(result.group.header.header_id, ch_result.group.header.header_id);
190 result.children.push_back(std::move(ch_result));
191 }
192
193 return result;
194}
195
196// -----------------------------------------------------------------------------
197// Root graphics buffer
198// -----------------------------------------------------------------------------
199
202 Surface& surface,
203 LayoutCursor& cursor,
204 float x_min, float x_max, float row_h, int depth)
205{
206 auto root = m_bm.get_root_graphics_buffer(token);
207 const auto children = root->get_child_buffers();
208
209 const float ind = x_min + static_cast<float>(depth) * k_inspect_indent;
210 const std::string header_label = "graphics ["
211 + std::string(Reflect::enum_to_string(token)) + "]";
212
213 std::vector<ValueSpec> values {
214 ValueSpec {
215 .label = "vk_buffers",
216 .reader = [root] { return std::to_string(root->get_buffer_count()); },
217 },
218 };
219
220 const auto dims = row_pixel_dims(surface.window(), ind, x_max, row_h);
221 auto hbuf = make_row_buffer(surface.window(), header_label, dims);
222 std::vector<RowBuffer> rbufs;
223 rbufs.reserve(values.size());
224 for (const auto& spec : values)
225 rbufs.push_back(make_row_buffer(surface.window(), spec.label, dims));
226 auto group = make_value_group(values, std::move(hbuf), rbufs,
227 surface, cursor, ind, x_max, row_h, false);
228
229 InspectResult result;
230 result.group = std::move(group);
231
232 auto root_result = buffer(
233 root, surface, cursor,
234 x_min, x_max, row_h, depth + 1);
235 surface.layer().relate(result.group.header.header_id, root_result.group.header.header_id);
236 result.children.push_back(std::move(root_result));
237
238 for (const auto& child : children) {
239 auto child_result = buffer(
240 child, surface, cursor,
241 x_min, x_max, row_h, depth + 2);
242 surface.layer().relate(result.group.header.header_id, child_result.group.header.header_id);
243 result.children.push_back(std::move(child_result));
244 }
245
246 return result;
247}
248
249// -----------------------------------------------------------------------------
250// BufferManager aggregate
251// -----------------------------------------------------------------------------
252
254 Surface& surface,
255 LayoutCursor& cursor,
256 float x_min, float x_max, float row_h)
257{
258 if (s_buffer_result) {
259 return *s_buffer_result;
260 }
261
262 const auto tokens = m_bm.get_active_tokens();
263 const uint32_t in_count = m_bm.get_num_input_channels();
264 const std::string header_label = "BufferManager";
265 auto& bm = m_bm;
266 std::vector<ValueSpec> values {
267 ValueSpec {
268 .label = "tokens",
269 .reader = [&bm] { return std::to_string(bm.get_active_tokens().size()); },
270 },
271 ValueSpec {
272 .label = "inputs",
273 .reader = [&bm] { return std::to_string(bm.get_num_input_channels()); },
274 },
275 };
276
277 const auto dims = row_pixel_dims(surface.window(), x_min, x_max, row_h);
278 auto hbuf = make_row_buffer(surface.window(), header_label, dims);
279 std::vector<RowBuffer> rbufs;
280 rbufs.reserve(values.size());
281 for (const auto& spec : values)
282 rbufs.push_back(make_row_buffer(surface.window(), spec.label, dims));
283
284 auto group = make_value_group(values, std::move(hbuf), rbufs,
285 surface, cursor, x_min, x_max, row_h, false);
286
287 InspectResult& result = s_buffer_result.emplace();
288 result.group = std::move(group);
289
290 for (const auto tok : tokens) {
293 InspectResult tok_result = is_audio
294 ? root_audio_buffer(tok, surface, cursor, x_min, x_max, row_h, 1)
295 : root_graphics_buffer(tok, surface, cursor, x_min, x_max, row_h, 1);
296 surface.layer().relate(result.group.header.header_id, tok_result.group.header.header_id);
297 result.children.push_back(std::move(tok_result));
298 }
299
300 if (in_count > 0) {
301 const std::string in_label = "inputs [" + std::to_string(in_count) + "]";
302 const auto in_dims = row_pixel_dims(surface.window(), x_min + k_inspect_indent, x_max, row_h);
303 auto in_hbuf = make_row_buffer(surface.window(), in_label, in_dims);
304 auto in_group = make_value_group({}, std::move(in_hbuf), {},
305 surface, cursor, x_min + k_inspect_indent, x_max, row_h, false);
306
307 InspectResult in_result;
308 in_result.group = std::move(in_group);
309 surface.layer().relate(result.group.header.header_id, in_result.group.header.header_id);
310
311 for (uint32_t ch = 0; ch < in_count; ++ch) {
312 auto buf = m_bm.get_input_buffer(ch);
313 auto buf_result = buffer(
314 std::dynamic_pointer_cast<Buffers::Buffer>(buf), surface, cursor,
315 x_min, x_max, row_h, 2);
316 surface.layer().relate(in_result.group.header.header_id, buf_result.group.header.header_id);
317 in_result.children.push_back(std::move(buf_result));
318 }
319
320 result.children.push_back(std::move(in_result));
321 }
322
323 return result;
324}
325
326} // namespace MayaFlux::Portal::Forma
std::shared_ptr< RootAudioBuffer > get_root_audio_buffer(ProcessingToken token, uint32_t channel=0)
Gets a root buffer for a specific token and channel (audio-specific due to channels)
std::shared_ptr< Buffers::InputAudioBuffer > get_input_buffer(uint32_t channel) const
uint32_t get_num_channels(ProcessingToken token) const
Gets the number of channels for a token (audio-specific)
std::shared_ptr< RootGraphicsBuffer > get_root_graphics_buffer(ProcessingToken token)
Gets a root graphics buffer for a specific token.
std::vector< ProcessingToken > get_active_tokens() const
Gets all currently active processing tokens.
static std::optional< InspectResult > s_buffer_result
InspectResult & buffer_manager(Surface &surface, LayoutCursor &cursor, float x_min=-0.95F, float x_max=0.95F, float row_h=0.05F)
Inspect the full BufferManager state across all active tokens.
RowBuffer make_row_buffer(const std::shared_ptr< Core::Window > &window, std::string_view text, glm::uvec2 pixel_dims) const
Definition Inspector.cpp:13
InspectResult root_audio_buffer(Buffers::ProcessingToken token, uint32_t channel, Surface &surface, LayoutCursor &cursor, float x_min=-0.95F, float x_max=0.95F, float row_h=0.05F, int depth=0)
Inspect the root audio buffer for a specific token and channel.
InspectResult root_graphics_buffer(Buffers::ProcessingToken token, Surface &surface, LayoutCursor &cursor, float x_min=-0.95F, float x_max=0.95F, float row_h=0.05F, int depth=0)
Inspect the root graphics buffer for a token.
InspectResult buffer(const std::shared_ptr< Buffers::Buffer > &buf, Surface &surface, LayoutCursor &cursor, float x_min=-0.95F, float x_max=0.95F, float row_h=0.05F, int depth=0)
Inspect a single Buffer: default processor and full processing chain.
Buffers::BufferManager & m_bm
bool relate(uint32_t primary_id, uint32_t related_id)
Record that related_id belongs with primary_id.
Definition Layer.cpp:152
Reactive Y-position accumulator for vertical primitive stacking.
const std::shared_ptr< Core::Window > & window() const noexcept
Access the rendering target window.
Definition Surface.hpp:126
Layer & layer() noexcept
Access the spatial registry.
Definition Surface.hpp:107
Named owner of a (Window, Layer, Context) triple - the Forma canvas.
Definition Surface.hpp:58
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ AUDIO_PARALLEL
High-performance audio processing with GPU acceleration.
ValueGroup make_value_group(std::span< const ValueSpec > values, RowBuffer header_buf, std::span< const RowBuffer > row_bufs, Surface &surface, LayoutCursor &cursor, float x_min, float x_max, float row_h, bool initially_open)
Construct a collapsible header followed by N value rows under it.
constexpr float k_inspect_indent
glm::uvec2 row_pixel_dims(const std::shared_ptr< Core::Window > &window, float x_min, float x_max, float row_h)
Convert an NDC row rect into integer pixel dimensions.
constexpr std::string_view enum_to_string(EnumType value) noexcept
Universal enum to string converter using magic_enum (original case)
std::string short_dynamic_type_name(const T &obj) noexcept
Returns the unqualified dynamic type name of obj.
Definition TypeInfo.hpp:95
bool is_audio(const fs::path &filepath)
Definition Depot.cpp:113
uint32_t header_id
Element id of the header strip. Valid after place().
std::vector< InspectResult > children
Result of an introspect call.
A single value to display in a ValueGroup body row.