From 46f048b07ca59ecce377761b3d8ce9f7f3ae0b3a Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sat, 22 Aug 2026 12:15:08 +0000 Subject: [PATCH] Add the leveled render intermediate beside the legacy rows --- .../libraries/graphic-types/src/graphic.rs | 12 +++ node-graph/nodes/gstd/src/render_node.rs | 76 +++++++++++++------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/node-graph/libraries/graphic-types/src/graphic.rs b/node-graph/libraries/graphic-types/src/graphic.rs index 5e230dda2b..6582c67b2b 100644 --- a/node-graph/libraries/graphic-types/src/graphic.rs +++ b/node-graph/libraries/graphic-types/src/graphic.rs @@ -690,6 +690,18 @@ pub(crate) fn run_to_legacy_list(item: &core_t Some(list) } +/// One typed run as the legacy list its `Render` impl consumes, nested +/// groups converted to their legacy form. +pub fn run_to_render_list(item: &core_types::record::GroupItem) -> Option> { + let mut list = run_to_legacy_list::(item)?; + if let Some(graphics) = (&mut list as &mut dyn std::any::Any).downcast_mut::>() { + for element in graphics.iter_element_values_mut() { + *element = map_groups_to_legacy(element); + } + } + Some(list) +} + /// The deep clone-out for `Graphic` elements: a plain clone of a group /// interior would carry frame pointers into the evaluation's arena, so memo /// and capture seams copy out the legacy-converted form, which owns all of diff --git a/node-graph/nodes/gstd/src/render_node.rs b/node-graph/nodes/gstd/src/render_node.rs index e5702973a2..9d21b21af3 100644 --- a/node-graph/nodes/gstd/src/render_node.rs +++ b/node-graph/nodes/gstd/src/render_node.rs @@ -1,7 +1,7 @@ use core_types::gpoll::Interrupt; use core_types::list::List; use core_types::transform::{Footprint, Transform}; -use core_types::{Color, Context, Ctx, DeriveCtx, ExtractFootprint, ExtractVarArgs, VarArgLink, VarArgSlots, WasmNotSend}; +use core_types::{Color, Context, Ctx, DeriveCtx, ExtractFootprint, ExtractIndex, ExtractVarArgs, InjectIndex, VarArgLink, VarArgSlots, WasmNotSend}; use graph_craft::document::value::{RenderOutput, RenderOutputType}; use graphene_application_io::{ExportFormat, RenderConfig}; use graphic_types::raster_types::{CPU, Raster}; @@ -22,6 +22,35 @@ pub struct RenderIntermediate { pub(crate) metadata: RenderMetadata, } +fn intermediate_of(data: &R, render_params: &RenderParams) -> RenderIntermediate { + let footprint = Footprint::default(); + let mut metadata = RenderMetadata::default(); + data.collect_metadata(&mut metadata, footprint, None); + match &render_params.render_output_type { + RenderOutputTypeRequest::Vello => { + let mut scene = vello::Scene::new(); + + let mut context = wgpu_executor::RenderContext::default(); + data.render_to_vello(&mut scene, Default::default(), &mut context, render_params); + + RenderIntermediate { + ty: RenderIntermediateType::Vello(Arc::new((scene, context))), + metadata, + } + } + RenderOutputTypeRequest::Svg => { + let mut render = SvgRender::new(); + + data.render_svg(&mut render, render_params); + + RenderIntermediate { + ty: RenderIntermediateType::Svg(Arc::new(render.into())), + metadata, + } + } + } +} + #[node_macro::node(category(""))] fn render_intermediate( ctx: impl Ctx + ExtractVarArgs + DeriveCtx, @@ -43,32 +72,29 @@ fn render_intermediate( .downcast_ref::() .expect("Downcasting render params yielded invalid type"); - let footprint = Footprint::default(); - let mut metadata = RenderMetadata::default(); - data.collect_metadata(&mut metadata, footprint, None); - Ok(match &render_params.render_output_type { - RenderOutputTypeRequest::Vello => { - let mut scene = vello::Scene::new(); + Ok(intermediate_of(&data, render_params)) +} - let mut context = wgpu_executor::RenderContext::default(); - data.render_to_vello(&mut scene, Default::default(), &mut context, render_params); +/// The leveled form of `render_intermediate`: the wire's records materialize +/// into a run and render through the legacy conversion. +#[node_macro::node(category(""))] +fn render_intermediate_leveled( + ctx: impl Ctx + ExtractVarArgs + ExtractIndex + InjectIndex + Copy, + #[implementations(Artboard, Graphic, Vector, Raster, Color, GradientStops, String)] data: IList, +) -> Result +where + List: Render, +{ + // SAFETY: a materialized input's frames are arena-resident. + let item = unsafe { core_types::record::GroupItem::from_resident(data.batch()) }; + let data = graphic_types::graphic::run_to_render_list::(&item).expect("the run holds the row's element type"); + let render_params = ctx + .vararg(0) + .expect("Did not find var args") + .downcast_ref::() + .expect("Downcasting render params yielded invalid type"); - RenderIntermediate { - ty: RenderIntermediateType::Vello(Arc::new((scene, context))), - metadata, - } - } - RenderOutputTypeRequest::Svg => { - let mut render = SvgRender::new(); - - data.render_svg(&mut render, render_params); - - RenderIntermediate { - ty: RenderIntermediateType::Svg(Arc::new(render.into())), - metadata, - } - } - }) + Ok(intermediate_of(&data, render_params)) } #[node_macro::node(category(""))]