Standalone renderer GenServer. Owns the render pipeline and font registry so a slow frame doesn't block input dispatch in the Editor process.
Lifecycle
Started by MingaEditor.Supervisor for all non-headless backends.
The headless backend renders synchronously in-process for test
determinism; this server is not in the supervision tree in that case.
Snapshot mechanics
The Editor pushes RenderPipeline.Input snapshots via
cast_snapshot/3. The Renderer holds an in-flight snapshot, a
pending one, and the latest frontend cache state it emitted. When a
snapshot arrives while a render is in progress, the previous pending
snapshot is dropped (most-recent-wins coalescing) and a
[:minga, :render, :coalesced] telemetry event fires. Each snapshot
is normalized against the renderer-owned cache state before it renders.
After each render emit completes, the Renderer stores the emitted
cache state and threads it into any pending snapshot before starting
the next frame; otherwise it goes idle. If the Editor emits a direct
bare frame boundary, that newer snapshot cache wins instead. That keeps
delta frame bases aligned with what the frontend just received, even
when the Editor has not yet processed the prior render writeback.
Click-region writeback
The render pipeline computes modeline_click_regions and
tab_bar_click_regions as part of chrome rendering. These need to
flow back to the Editor so subsequent mouse events can resolve
click positions. The Renderer sends {:render_done, writeback}
back to the Editor after every emit; the Editor merges renderer-owned
fields from that payload via apply_renderer_writeback/2.
Telemetry
[:minga, :render, :pipeline]span aroundRenderPipeline.run/1.[:minga, :render, :coalesced]event when a pending snapshot is dropped.[:minga, :render, :frame_latency]measurement (push timestamp → emit complete).[:minga, :render, :hop_latency](hop: :cast_snapshot) measures the Editor → Renderer.Server scheduling delay; (hop: :render_done) measures the Renderer.Server → Editor writeback scheduling delay.
Determinism in tests
EditorCase tests use the headless backend, which renders synchronously in-process. This server is not started in the test supervision tree.
Summary
Types
Editor process reference used for renderer writebacks.
Injected render pipeline function.
Render pipeline output after a frame has run.
Renderer server state.
Click-region writeback payload sent to the Editor after each frame.
Functions
Pushes a render snapshot. Returns immediately; the actual emit happens asynchronously. If a previous snapshot is still rendering, this snapshot replaces any prior pending one.
Returns a specification to start this module under a supervisor.
Returns true while a render pass is in progress.
Starts the Renderer server. The :editor_pid option names the Editor
process to send {:render_done, ...} writebacks to; defaults to
MingaEditor (the registered name of the Editor GenServer).
Types
Editor process reference used for renderer writebacks.
@type pipeline() :: (MingaEditor.RenderPipeline.Input.t() -> render_output())
Injected render pipeline function.
@type render_output() :: MingaEditor.RenderPipeline.Input.t()
Render pipeline output after a frame has run.
@type t() :: %MingaEditor.Renderer.Server{ caches: MingaEditor.Renderer.Caches.t(), editor_pid: editor_ref(), font_registry: MingaEditor.UI.FontRegistry.t(), in_flight: {MingaEditor.RenderPipeline.Input.t(), non_neg_integer(), integer()} | nil, pending: {MingaEditor.RenderPipeline.Input.t(), non_neg_integer(), integer()} | nil, pipeline: pipeline(), rendering?: boolean() }
Renderer server state.
@type writeback() :: %{ caches: MingaEditor.Renderer.Caches.t(), layout: MingaEditor.Layout.t() | nil, focus_tree: MingaEditor.FocusTree.t() | nil, shell_id: atom(), shell_identity: MingaEditor.Shell.Identity.t() | nil, shell_state: term(), windows: term(), frame_seq: non_neg_integer(), keyframe?: boolean(), render_sent_at: integer() }
Click-region writeback payload sent to the Editor after each frame.
Functions
@spec cast_snapshot( GenServer.server(), MingaEditor.RenderPipeline.Input.t(), non_neg_integer() ) :: :ok
Pushes a render snapshot. Returns immediately; the actual emit happens asynchronously. If a previous snapshot is still rendering, this snapshot replaces any prior pending one.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec rendering?(GenServer.server()) :: boolean()
Returns true while a render pass is in progress.
@spec start_link(keyword()) :: GenServer.on_start()
Starts the Renderer server. The :editor_pid option names the Editor
process to send {:render_done, ...} writebacks to; defaults to
MingaEditor (the registered name of the Editor GenServer).