Loading...
Searching...
No Matches
InjectBuffer.hpp
1#pragma once
2#include <halp/buffer.hpp>
3#include <halp/controls.hpp>
4#include <halp/meta.hpp>
5
6#include <ossia/dataflow/geometry_port.hpp>
7
8#include <cstdint>
9#include <memory>
10#include <string>
11
12namespace Threedim
13{
14
15// Mid-pipeline aux-buffer injection. Takes a scene_spec passthrough cable
16// plus a live GPU buffer from an upstream producer (CSF output, another
17// aux node, etc.) and attaches it to the scene as a pending injection
18// under a caller-supplied name. ScenePreprocessor consumes
19// `scene_state::inject_buffers` at flatten-time and writes matching
20// `auxiliary_buffer` entries onto every output geometry — so the live
21// handle ends up bound to any downstream consumer shader that declares
22// an AUXILIARY entry with the same name (SSBO or UBO kind).
23//
24// Wiring:
25// CSFProducer → InjectBuffer(name="scene_params", is_uniform=true)
26// → ScenePreprocessor → classic_pbr_full
27//
28// Name collisions with existing auxes published by the scene producers
29// (e.g., ScenePreprocessor's own scene_lights / scene_materials) follow
30// last-wins — the injection appended after flatten overrides the
31// flatten-time entry. Use this to selectively replace standard auxes
32// with custom data without forking the preprocessor.
34{
35public:
36 halp_meta(name, "Inject Buffer")
37 halp_meta(category, "Visuals/3D/Scene")
38 halp_meta(c_name, "inject_buffer")
39 halp_meta(authors, "ossia team")
40 halp_meta(
41 manual_url,
42 "https://ossia.io/score-docs/processes/inject-buffer.html")
43 halp_meta(uuid, "4f9a6e2d-7c83-4b5d-9e1f-8a3c5d6b2f4e")
44
45 struct ins
46 {
47 struct
48 {
49 halp_meta(name, "Scene In");
50 ossia::scene_spec scene;
51 uint8_t dirty{0};
52 } scene_in;
53
54 // Port-driven rebuild: aux_name triggers rebuild(). scene_in +
55 // buffer handle changes are detected in operator()() because they
56 // can change without a port-update event.
57 // Live GPU buffer from an upstream producer. Null handle → the
58 // injection is skipped (passthrough), so unwiring is safe.
59 halp::gpu_buffer_input<"Buffer"> buffer;
60
61 struct : halp::lineedit<"Aux name", "">
62 { void update(InjectBuffer& n) { n.rebuild(); } } aux_name;
63 } inputs;
64
65 struct outs
66 {
67 struct
68 {
69 halp_meta(name, "Scene Out");
70 ossia::scene_spec scene;
71 uint8_t dirty{0};
72 } scene_out;
73 } outputs;
74
75 void rebuild();
76 void operator()();
77
78 // Stable shared_ptr cached while inputs are unchanged — keeps
79 // ScenePreprocessor's fingerprint fast-path warm.
80 std::shared_ptr<const ossia::scene_state> m_cached_out;
81 uint8_t m_pending_dirty{0xFF};
82 const ossia::scene_state* m_cached_in_state{};
83 // -2 is a sentinel no live input can produce (a null input reads as
84 // -1): it forces the first tick's rebuild without needing
85 // `!m_cached_out` as a trigger — a null cached output is legitimate
86 // whenever the input scene is null, and using it as a rebuild trigger
87 // re-dirties every tick of an unwired node.
88 int64_t m_cached_in_version{-2};
89 std::string m_cached_name;
90 void* m_cached_handle{};
91 int64_t m_cached_byte_size{};
92 int64_t m_version_counter{0};
93};
94
95}
Definition InjectBuffer.hpp:34
Definition InjectBuffer.hpp:46
Definition InjectBuffer.hpp:66