Skip to main content

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}