MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
FormaProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace MayaFlux::Buffers {
8
9/**
10 * @class FormaProcessor
11 * @brief Default processor for FormaBuffer.
12 *
13 * Owns the CPU-to-GPU upload cycle for Forma geometry through a SliceSet.
14 * Geometry is held as one or more slices of one stride and topology, laid out
15 * in a single vertex buffer. set_bytes() writes the default slice, so a
16 * standalone buffer is a batch of one. Each graphics tick uploads only what
17 * changed, then points the RenderProcessor at the visible slices: one draw per
18 * run, adjacent runs coalesced.
19 *
20 * The topology is fixed at construction to derive the per-vertex stride.
21 *
22 * Slice calls and processing run on the graphics thread; nothing here is
23 * synchronised. A trailing partial vertex in submitted bytes is dropped.
24 */
25class MAYAFLUX_API FormaProcessor : public VKBufferProcessor {
26public:
28
30 ~FormaProcessor() override = default;
31
32 /**
33 * @brief Replace the default slice with new vertex bytes.
34 *
35 * Applied on the next processing_function call. The default slice is
36 * created on first use.
37 *
38 * @param bytes Raw interleaved vertex bytes matching the topology's
39 * vertex type (PointVertex, LineVertex, or MeshVertex).
40 */
41 void set_bytes(const std::vector<uint8_t>& bytes);
42
43 /**
44 * @brief Append a slice, drawn after the existing ones. Returns 0 on failure.
45 * @param topology Topology of this slice; the processor's when omitted. A
46 * slice of a different topology needs a render processor that
47 * triangulates, otherwise only matching topologies draw correctly.
48 */
49 SliceId add_slice(const std::vector<uint8_t>& bytes,
50 std::optional<Portal::Graphics::PrimitiveTopology> topology = std::nullopt);
51
52 /** @brief Replace a slice's vertices; later slices shift if the size changes. */
53 void update_slice(SliceId id, const std::vector<uint8_t>& bytes);
54
55 /** @brief Remove a slice; later slices shift down. */
56 void remove_slice(SliceId id);
57
58 /** @brief Hide or show a slice without moving its data. */
59 void set_slice_visible(SliceId id, bool visible);
60
61 /** @brief Draw a slice after every other. */
62 void bring_slice_to_front(SliceId id);
63
64 /** @brief Draw a slice before every other. */
65 void send_slice_to_back(SliceId id);
66
67 /** @brief Number of live slices. */
68 [[nodiscard]] size_t slice_count() const noexcept { return m_slices.size(); }
69
70 /** @brief True when @p id names a live slice. */
71 [[nodiscard]] bool has_slice(SliceId id) const noexcept { return m_slices.contains(id); }
72
73 /** @brief True when geometry or slice changes await the next tick. */
74 [[nodiscard]] bool has_pending() const noexcept;
75
76 /**
77 * @brief Supply a texture to bind on the next graphics tick.
78 *
79 * Stores the image and binding name behind an atomic dirty flag.
80 * On the next processing_function call the image is bound to the
81 * RenderProcessor via bind_texture(). Calling again replaces the
82 * pending binding before it has been consumed.
83 *
84 * @param image GPU image. nullptr clears the binding.
85 * @param binding Descriptor name matching the fragment shader.
86 */
87 void set_texture(std::shared_ptr<Core::VKImage> image, std::string binding);
88
89protected:
90 void on_attach(const std::shared_ptr<Buffer>& buffer) override;
91 void on_detach(const std::shared_ptr<Buffer>& buffer) override;
92 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
93
94private:
96 std::shared_ptr<Core::VKImage> image;
97 std::string binding;
98 };
99
101 uint32_t m_stride { 0 };
102
104 SliceId m_default_slice { 0 };
105 bool m_changed { false };
106 std::optional<std::vector<Portal::Graphics::DrawRun>> m_pending_runs;
107
108 std::optional<PendingTexture> m_pending_texture;
109 std::atomic_flag m_texture_dirty;
110
111 std::shared_ptr<VKBuffer> m_staging;
112
113 [[nodiscard]] std::span<const uint8_t> whole_vertices(const std::vector<uint8_t>& bytes) const noexcept;
114 void apply_runs(const std::shared_ptr<VKBuffer>& buffer);
115};
116
117} // namespace MayaFlux::Buffers
IO::ImageData image
Definition Decoder.cpp:47
std::shared_ptr< NetworkGeometryBuffer > buffer
PrimitiveTopology topology
Backend-agnostic interface for sequential data storage and transformation.
Definition Buffer.hpp:37
Portal::Graphics::PrimitiveTopology m_topology
bool has_slice(SliceId id) const noexcept
True when id names a live slice.
size_t slice_count() const noexcept
Number of live slices.
~FormaProcessor() override=default
std::shared_ptr< VKBuffer > m_staging
std::optional< PendingTexture > m_pending_texture
std::optional< std::vector< Portal::Graphics::DrawRun > > m_pending_runs
Default processor for FormaBuffer.
Many vertex blocks laid out in one buffer, drawn as few runs.
Definition SliceSet.hpp:34
PrimitiveTopology
Vertex assembly primitive topology.