Expand description
Retained Node IR - typed scene-graph tree produced from the flat Extracted* bag.
§Why a tree?
The render side previously consumed a flat ECS of one-component-per-drawable, painter-sorted at submit
(crate::render_world::ExtractedRect / ExtractedText / ExtractedShadow / ExtractedOutline).
The flat shape lost the parent-driven invariants every modern scenegraph relies on - opacity composition,
transform stacks, and clip regions all have to be reconstructed at submit. This module replaces that with
a typed Node tree owned per-frame by the render world.
§1:1 mapping to Qt SceneGraph + GTK GSK
The variants below were chosen to map directly onto the two reference scenegraphs - Qt 6.8 Scene Graph
(QSG*) and GTK 4 / GSK (gtk_snapshot_* / GskRenderNode). The renderer back-end only needs to know how
to translate each variant to its native equivalent.
Lumen Node | Qt SceneGraph | GTK 4 / GSK |
|---|---|---|
Node::Container | QSGNode (parent of children) | implicit container via gtk_snapshot_push_* / pop bracket |
Node::Transform | QSGTransformNode::setMatrix | gtk_snapshot_push_transform -> GskTransformNode |
Node::Opacity | QSGOpacityNode::setOpacity | gtk_snapshot_push_opacity -> GskOpacityNode |
Node::Clip (rect) | QSGClipNode { isRectangular = true } (scissor) | gtk_snapshot_push_clip -> GskClipNode |
Node::Clip (radii) | QSGClipNode + custom geometry | gtk_snapshot_push_rounded_clip -> GskRoundedClipNode |
Node::Rect (solid) | QSGSimpleRectNode | gtk_snapshot_append_color -> GskColorNode |
Node::Rect (gradient) | QSGGeometryNode + gradient QSGMaterial | GskLinearGradientNode / GskRadialGradientNode / GskConicGradientNode |
Node::Shadow (outer) | QSGGeometryNode + blur material | gtk_snapshot_append_outset_shadow -> GskOutsetShadowNode |
Node::Shadow (inner) | (custom material) | gtk_snapshot_append_inset_shadow -> GskInsetShadowNode |
Node::Outline | QSGGeometryNode (line list) | GskBorderNode (4-side uniform) or composed GskColorNodes |
Node::Text | QSGTextNode (via QSGRendererInterface::createTextNode) | gtk_snapshot_append_layout -> GskTextNode |
Node::Image | QSGSimpleTextureNode::setTexture + setSourceRect | gtk_snapshot_append_texture -> GskTextureNode |
Node::Native | QSGRenderNode | GskGLShaderNode / gtk_snapshot_push_gl_shader |
§Content sharing
Children are held in Arc<Node> so identical subtrees can share storage across frames - the diff can
short-circuit via Arc::ptr_eq and the leaf-encoding [crate::render_world::SceneFragmentCache] becomes a
content-addressed layer on top.
§Wave 2 status
- W2.1 ships the types + a
transform_extracted_to_nodessystem that walks the existing extract output and produces aRetainedSceneeach frame. The legacyExtracted*components stay in place so the existing render systems keep compiling during the migration. - W2.2 wires the renderer walker (
lumen_render_wgpu::walk_node) to consumeRetainedScene. - W2.3 puts overflow clipping back on the rails via the
Node::Clipvariant - see the [Clip] doc-comment. - W2.4 lets the offscreen render path reuse the same walker (and hence the [
crate::render_world::SceneFragmentCache]).
Structs§
- Affine2
- A 2D affine transform stored as
[a, b, c, d, e, f]in column-major order - same convention asvello::kurbo::Affineso back-ends can construct without conversion glue. The default is the identity. - Previous
Scene - Snapshot of the previous tick’s
RetainedScene. Stored on the render world so the renderer can diffArc::ptr_eqbetween corresponding subtrees and emit damage rects intocrate::render_world::FrameDamage. - Retained
Scene - The retained scene-graph root for the current frame.
Enums§
- Clip
Shape - Clip-region shape for
Node::Clip. Rectangular clips map onto scissor on backends that support it (QtQSGClipNode { isRectangular = true }, GSKGskClipNode); rounded clips require stencil / mask (QtQSGClipNode+ geometry, GSKGskRoundedClipNode). - Draw
Entry - One drawable entry produced during extract, sorted by
PaintOrderbefore tree assembly. - Node
- One node in the retained scene-graph tree. The tree is produced each tick by
transform_extracted_to_nodesand rendered by the back-end walker.
Functions§
- transform_
extracted_ to_ nodes - Builds a
RetainedScenefrom the flatExtracted*components in the render world.