ASPECT_RENDER - mark-ik/graphshell GitHub Wiki
Date: 2026-02-28 Status: Architectural aspect note Priority: Immediate architecture clarification
Related:
-
2026-04-12_rendering_pipeline_status_quo_plan.md- current execution anchor for the rendering pipeline as it actually exists in code ../viewer/viewer_presentation_and_fallback_spec.md../viewer/2026-02-26_composited_viewer_pass_contract.md2026-02-27_egui_wgpu_custom_canvas_migration_strategy.md2026-03-03_servo_wgpu_upgrade_audit_report.md../2026-02-28_ux_contract_register.md
Policy authority: This file is the canonical policy authority for the Render aspect. Supporting render docs refine contracts/implementation detail and must defer policy authority to this file. Policy in this file should be distilled from canonical specs and accepted research conclusions.
This note defines the Render aspect as the architectural owner of frame assembly and GPU surface lifecycle.
It exists to keep one boundary explicit:
- what content is visible is owned by Canvas, Workbench, and Viewer,
- how each frame is assembled, composited, and committed to the GPU is owned by the Render aspect,
- and the GUI shell (
shell/desktop/ui/gui.rs,shell/desktop/ui/gui_frame.rs) is a host โ not a semantic owner of rendering policy.
- egui frame loop coordination (begin frame, layout pass, paint)
- composition pass ordering (UI chrome โ content โ overlay affordance)
-
CompositorAdapterlifecycle and GL/wgpu state isolation -
TileRenderModeresolution and per-tile render dispatch - thumbnail pipeline (
thumbnail_pipeline.rs) - render callback registration and execution ordering
- GPU surface lifecycle (surface creation, resize, present)
- egui โ wgpu migration boundary (tracking what has crossed and what has not)
The Render aspect does not own what is rendered โ it owns the pipeline that commits frames.
- Viewer owns fallback state and content presentation policy.
- Canvas and Workbench own what surfaces exist and which are active.
- Render owns when and how those surfaces are assembled into a committed frame.
The GUI decomposition is complete: shell/desktop/ui/gui.rs (681 lines) focuses on Gui struct/lifecycle entrypoints. Frame orchestration is in shell/desktop/ui/gui/gui_update_coordinator.rs. Workbench layout driving is in shell/desktop/ui/gui_orchestration.rs.
- Render -> Viewer: invokes per-tile composition passes in Viewer-defined order
- Render -> Workbench: reads tile tree for render traversal; does not mutate layout
- Render -> Canvas: invokes graph canvas render callback within the tile frame
- Registry -> Render:
ViewerRegistrysuppliesTileRenderModeper viewer;ThemeRegistrysupplies visual tokens for UI chrome pass
The initial GUI decomposition has landed (see ยง3). shell/desktop/ui/gui.rs (681 lines) is now focused on Gui struct and lifecycle entrypoints. Frame orchestration moved to gui/gui_update_coordinator.rs; workbench driving is in gui_orchestration.rs.
Remaining deferred decomposition work:
- frame loop and GPU surface lifecycle โ Render aspect module
- per-tile composition dispatch โ CompositorAdapter (already partially extracted)
This remaining decomposition is pending the egui_graphs custom canvas migration (see 2026-02-27_egui_wgpu_custom_canvas_migration_strategy.md). Plans belong in this folder; they are not abandoned.
If a behavior answers "how is a frame assembled and committed to the GPU?" it belongs to the Render aspect.
Status: Deferred โ not yet written.
A window_surface_lifecycle_spec.md should be created once the GPU surface and
window management path is stabilized and the shell/desktop/ui/gui.rs decomposition (ยง5) has
extracted the GPU surface lifecycle into its own Render aspect module.
When written, window_surface_lifecycle_spec.md must define the normative contract
for:
- swapchain creation: when a
wgpu::Surface(or equivalent Glow surface) is created relative to OS window creation, - resize handling: the full sequence from OS resize event through surface reconfiguration to the first correctly-sized committed frame,
- DPI scaling: how logical-to-physical pixel scaling is applied and when it changes,
- device loss recovery: the reinit path when a GPU device is lost โ what is torn down, re-created, and in what order; which backend capability probes re-run,
- multi-window behavior: whether multiple
EmbedderWindowinstances share a device or each own a surface independently, - present timing contract: vsync, mailbox, or immediate present selection policy and how it is selected per platform,
- surface lifecycle diagnostics channels: at minimum, channels for surface creation, resize, device loss, and present timing samples.
This spec is blocked on the shell/desktop/ui/gui.rs decomposition completing enough that GPU surface
lifecycle is owned by a discrete module (not the gui monolith). Until then, the
surface lifecycle is co-located with frame orchestration and cannot be separately
specified without creating a misleading boundary.