Expand description
Native paint seam - the way a plugin draws its own pixels inside the retained scene.
A plugin that owns a drawing surface (a chart, a map, a canvas) has content the core
primitives cannot describe. The seam gives it an opaque leaf: the plugin contributes an
ExtractedNative from a normal extract fn, registers a NativePainter for the same
extension_id, and the render backend calls that painter with its own draw target when the
leaf’s turn comes in paint order.
This is the same shape as QSGRenderNode in Qt SceneGraph and GskGLShaderNode in GTK 4:
an opaque leaf that the scene graph positions, orders, and clips, and whose interior only the
backend and the extension understand.
§Contracts
- Bounds enclose the paint.
ExtractedNative::boundsmust cover every pixel the painter touches. The damage diff repaints exactly that rect, so paint outside it survives as stale pixels until something else damages the region. revisionis pixel identity. Two leaves with the sameextension_id,bounds,clip_to_bounds, andrevisionare treated as identical pixels and contribute no damage. Callnext_revisionwhenever the content changes, or the frame never repaints. Payload identity is deliberately not part of the comparison: producers rebuild theArcon every dirty frame, which would mark the leaf changed every time.- Painters take
&self. One painter serves every leaf carrying itsextension_id, so per-frame state goes behind interior mutability. extension_idnames a contract, covering both the concrete payload type and the API the painter expects from the backend. A backend with no painter registered for an id skips the leaf, which is what keeps a scene portable across backends.- Bounds with no area never repaint on their own. Damage is a rect, and an empty rect is no damage, so a leaf that declares zero width or height falls back to whole-viewport damage when its revision moves. Declare the area you paint.
§Producing leaves
NativeExtract resolves the placement of one entity - paint order, scroll offset, inherited
opacity, hidden subtrees - the same way the built-in extractors do, and
upsert_native_leaves carries the leaves across frames under one extension id so two plugins
extracting in the same frame cannot evict each other’s entities.
Structs§
- Extracted
Native - Render-world component describing one backend-painted leaf.
- Native
Extract - The hierarchy-derived facts a plugin’s extract fn needs, computed once per frame.
- Native
Paint Ctx - What a backend hands a
NativePainterfor one leaf. - Native
Painters - Render-world registry mapping an
extension_idto the painter that draws it. - Native
Placement - Where one entity’s leaf belongs this frame, as
NativeExtractresolved it.
Traits§
- Native
Painter - Paints one
ExtractedNativeleaf onto a backend draw target.
Functions§
- next_
revision - Monotonic content stamps for
ExtractedNative::revision. - upsert_
native_ leaves - Carries one extension’s leaves into the render world, reusing each entity’s render-world entity across frames and despawning the ones that went away.