Rendering Pipeline
View SourceThe integrated pipeline is implemented by TermUI.Runtime and
TermUI.Runtime.NodeRenderer.
flowchart LR
V[root view/1] --> T[render tree]
T --> N[NodeRenderer]
N --> C[Buffer cells]
C --> R{backend mode}
R -->|Raw/custom| D[current vs previous diff]
R -->|TTY| F[full displayable frame]
D --> B[Backend.draw_cells/2]
F --> B
B --> O[Backend.flush/1]Render trees
use TermUI.Elm imports two compatible helper families:
TermUI.Component.Helpersproduces%TermUI.Component.RenderNode{}values throughtext,styled,box,stack,cells, andempty.TermUI.Elm.Helperssupplies tuple-basedrow,column, andfragmenthelpers. Its conflicting text/box helpers are not imported by the macro.
The node renderer also understands lists, constraint-wrapped stack children, and the viewport/overlay maps produced by widgets. Unknown values render nothing.
Layout and rasterization
Vertical and horizontal stacks allocate child space. A child can be paired
with a TermUI.Layout.Constraint; TermUI.Layout.Solver computes its share of
the available stack dimension. Rendering is clipped by buffer bounds.
Text is split on newlines and converted to TermUI.Renderer.Cell structs.
Parent and node styles are merged, and wide-character placeholders are retained
in the buffer so later cells remain aligned.
Raw and custom backend path
These modes own a TermUI.Renderer.BufferManager with current and previous ETS
buffers. Each dirty frame clears the current buffer, rasterizes the complete
tree, compares cells with the previous buffer, emits changed cells and needed
clears, then swaps the buffers.
The runtime performs this comparison itself. TermUI.Renderer.Diff is a public
standalone utility and is not called by the integrated runtime.
TTY path
TTY creates a temporary buffer for each dirty frame, rasterizes the tree, and
extracts all non-space cells plus spaces with non-default backgrounds. The
backend receives that full set and defaults to line_mode: :full_redraw.
Therefore claims about differential output apply to Raw/custom operation, not
the default TTY path.
Scheduling
The runtime schedules a render message every 16 ms by default. It calls
view/1 only when its own dirty flag is true. The separate
TermUI.Renderer.FramerateLimiter and TermUI.ViewCache modules are opt-in
utilities, not part of this loop.
Direct testing
For rasterization tests, create a TermUI.Renderer.Buffer or
TermUI.Renderer.BufferManager and call
TermUI.Runtime.NodeRenderer.render_to_buffer_direct/4 or
render_to_buffer/4. Always destroy standalone buffers after use.
Next: Event System.