Expand description
Compositor: renders the timeline at time t into an RGBA canvas. Used by preview (small canvas)
and export (project-size canvas) — same output, so preview == export. The one gap left against the
GL renderer: node graphs (Clip.graph) and the GPU-only effect kinds (effects::gpu_only) are not
evaluated here; export::cpu_gaps names them in the export progress line.
Layer order: video tracks bottom→top in project.tracks order (V1 first, then V2 drawn over it…).
For each active (project.active(track)), enabled, visual clip containing t:
- Video/Image:
pool.video(asset.path).frame_at(clip.src_time(t), dw, dh, ..)where (dw,dh) is the placement size (clamped to native size, min 1) — decoders scale for us. - Text / Shape:
text.render(style, canvas_w / project.width)/shapes.render(style, s, local_t)(already at canvas scale) — contain=false. - Sequence: the nested timeline is rendered recursively at
clip.src_time(t)into its own canvas (the sequence’s size, fit like a video layer), depth ≤ 8. - Adjustment: no layer of its own — the effect stack re-runs over the canvas below it.
clip.effectsrun in stack order on the decoded layer (Wobble moves the placement instead: dx/dy/roll, and yaw/pitch render through a perspective homography).Effect.masklimits an effect to its shape (layer space);Clip.masklimits the whole layer (canvas space) — both mirrorshaders.rs::MASK.- Transform the layer into canvas space per
placement()(sampling perproject.scaler; straight row copies for the common axis-aligned case), thenblend::composite_row/blend::composite_rect. Transitions render both clips of the cut — extended virtually into the window, which is clamped to the two clips (trans_window) so an over-long one cannot hide the rest of the track — and blend per kind. Subtitles (Project::cue_at) draw last, bottom-centre. Background is opaque black. Out-of-view layers are skipped.
Structs§
- Compositor
- Holds scratch buffers so rendering does not allocate per frame.
- Extra 🔒
- Per-clip render tweaks used by transitions (opacity fade, push offset, fade-to-colour).
- Placement
- Where a layer lands on a canvas of (cw, ch) pixels: centre, size and rotation (degrees, clockwise).
yaw/pitch(degrees) tilt the layer about the vertical/horizontal axis (camera shake) — rendered through a perspective homography with focal length ≈ canvas width; 0 = flat.
Constants§
- MAX_
DEPTH 🔒 - Recursion limit for nested sequences.
- MAX_
MASK_ 🔒POINTS - Mask polygon vertex cap — same as the GPU’s
m_points[64].
Functions§
- apply_
effects 🔒 - Run the clip’s effect stack on the layer image; geometric effects (Wobble) move
pinstead.s= canvas px per project px;img_scale= layer-image px per project px. A masked effect is mixed back over the pre-effect image by the mask’s coverage (asshaders.rs::apply_maskdoes). - catmull 🔒
- Catmull-Rom weights for taps at offsets -1, 0, 1, 2 for fractional position
t. - clip_
mask 🔒 - Coverage for
clip.maskover the whole canvas, or None when the clip has no enabled mask. The mask lives in canvas space around the layer’s placed centre (matching gpu.rs). - dir_vec 🔒
- Direction unit vector scaled to canvas size: 0 = left, 1 = right, 2 = up, 3 = down.
- draw_
layer - Draw
srcintodst(canvas) atpwith blend mode & opacity, usingscratchas the canvas-sized layer buffer. Sampling perscaler; pixels outsidesrcare transparent. - draw_
layer_ 🔒masked draw_layerwith an optional canvas-sized coverage mask (0..255 per pixel) multiplied into the layer’s alpha. A masked draw always takes the general path, which is where coverage is applied.- draw_
layer_ 🔒perspective - Perspective path: project the placed rect’s corners tilted by yaw (about Y) and pitch (about X) with focal length = canvas width, then inverse-map each canvas pixel through the homography.
- fade_to 🔒
- Mix the layer’s RGB towards
colorbyf(FadeToColor transitions). - invert3 🔒
- Inverse of a 3×3 (adjugate / det); None when singular.
- mask_
coverage 🔒 - Rasterise
maskintoout(one coverage byte per pixel of a w×h buffer) — the CPU twin ofshaders.rs::MASK, so preview and export agree.scale= buffer px per project px,centre= the layer centre in buffer px. - placement
- Placement of a clip’s layer on a (cw, ch) canvas at timeline time t.
native= the layer image size. Withcontain(video/images) the image is first fitted inside the canvas preserving aspect; text is already rendered at canvas scale socontain = false. Then: scale about the centre byclip.scale, offset by (clip.x, clip.y) project pixels (scaled to canvas), rotate byclip.rotation. - placement_
w 🔒 placementwith an explicit project width (nested sequences use the sequence’s own size).- sample 🔒
- Sample
srcat (sx, sy) — already clamped to [0, sw-1]/[0, sh-1] — returning straight RGBA (r, g, b in 0..255, a in 0..255). - sd_box 🔒
- Signed distance to a box of half-size (bx, by).
- sd_
ellipse 🔒 - Cheap ellipse SDF (exact only on circles), matching the shader.
- sd_poly 🔒
- Signed distance to the closed polygon through
pts(negative inside). - square_
to_ 🔒quad - Homography mapping the unit square (0,0)(1,0)(1,1)(0,1) onto
q(Heckbert). - track_
active 🔒 - Mute/solo resolution over an arbitrary track list (mirrors
Project::active). - trans_
progress - Eased progress 0..1 over the clamped window of any placement (edge transitions have one side).
- trans_
progress_ at - Eased progress 0..1 across a transition window of
cut ± half.