ff_render/nodes/mod.rs
1pub mod color_grade;
2pub mod composite;
3pub mod crossfade;
4pub mod overlay;
5pub mod scale;
6pub mod upload;
7
8pub use color_grade::ColorGradeNode;
9pub use composite::{
10 AlphaMatteNode, BlendMode, BlendModeNode, ChromaKeyNode, LumaMaskNode, ShapeMaskNode,
11 TransformNode,
12};
13pub use crossfade::CrossfadeNode;
14pub use overlay::OverlayNode;
15pub use scale::{ScaleAlgorithm, ScaleNode};
16pub use upload::{YuvFormat, YuvUploadNode};
17
18// ── RenderNodeCpu ─────────────────────────────────────────────────────────────
19
20/// CPU fallback processing for a render node.
21///
22/// Implemented by all built-in nodes. Nodes that do not change frame
23/// dimensions modify `rgba` in-place. Multi-input nodes (e.g. [`CrossfadeNode`])
24/// store their secondary inputs as fields and access them during `process_cpu`.
25pub trait RenderNodeCpu: Send {
26 /// Process `rgba` in-place.
27 ///
28 /// `rgba` is a row-major RGBA buffer of size `w × h × 4` bytes.
29 /// Nodes that cannot implement a CPU path leave `rgba` unchanged.
30 fn process_cpu(&self, rgba: &mut [u8], w: u32, h: u32);
31}
32
33// ── RenderNode ────────────────────────────────────────────────────────────────
34
35/// GPU render node. Extends [`RenderNodeCpu`] so both paths are available.
36///
37/// Each node is responsible for creating and caching its own wgpu pipeline
38/// on first use. The pipeline is stored in a [`std::sync::OnceLock`] field
39/// so it is created exactly once per node instance.
40///
41/// `process` may submit one or more `wgpu::CommandEncoder` buffers. The
42/// [`RenderGraph`](crate::graph::RenderGraph) guarantees that the queue
43/// processes them in submission order.
44#[cfg(feature = "wgpu")]
45pub trait RenderNode: RenderNodeCpu {
46 /// Number of input textures required by this node (default: 1).
47 fn input_count(&self) -> usize {
48 1
49 }
50
51 /// Number of render passes (default: 1). Multi-pass nodes (e.g. gaussian
52 /// blur) return 2 or more.
53 fn pass_count(&self) -> usize {
54 1
55 }
56
57 /// Run the GPU render pass.
58 ///
59 /// `inputs[i]` are the source textures (`len == input_count()`).
60 /// `outputs[i]` are pre-allocated `Rgba8Unorm` target textures
61 /// (`len == pass_count()`). Write the final result into `outputs[pass_count()-1]`.
62 fn process(
63 &self,
64 inputs: &[&wgpu::Texture],
65 outputs: &[&wgpu::Texture],
66 ctx: &crate::context::RenderContext,
67 );
68}