Change footprint to always be in physical instead of logical space#4280
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the rendering pipeline to consistently manage physical and logical coordinate spaces. It scales the footprint transform by the render scale early in the pipeline and introduces logical transforms where needed across background rendering, caching, and pixel preview nodes. The reviewer suggests a further simplification in render_pixel_preview.rs to remove an unnecessary multiplication by physical_scale when applying the transform to the metadata, since the upstream metadata is already in logical space.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| result | ||
| .metadata | ||
| .apply_transform(footprint.transform * DAffine2::from_translation(upstream_min) * DAffine2::from_scale(DVec2::splat(physical_scale))); | ||
| .apply_transform(logical_transform * DAffine2::from_translation(upstream_min) * DAffine2::from_scale(DVec2::splat(physical_scale))); |
There was a problem hiding this comment.
With upstream_render_params.scale set to 1.0, the upstream metadata is already in logical space, so we no longer need to multiply by physical_scale to undo the mismatch.
| result | |
| .metadata | |
| .apply_transform(footprint.transform * DAffine2::from_translation(upstream_min) * DAffine2::from_scale(DVec2::splat(physical_scale))); | |
| .apply_transform(logical_transform * DAffine2::from_translation(upstream_min) * DAffine2::from_scale(DVec2::splat(physical_scale))); | |
| result | |
| .metadata | |
| .apply_transform(logical_transform * DAffine2::from_translation(upstream_min)); |
There was a problem hiding this comment.
1 issue found across 4 files
Confidence score: 3/5
- In
node-graph/nodes/gstd/src/render_background.rs, invertingrender_params.scalewithout a zero check can produce non-finite transform values when scale is 0, which can lead to invalid SVG output at runtime — add a guard/fallback for zero (or near-zero) scale before computing1.0 / scalebefore merging.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="node-graph/nodes/gstd/src/render_background.rs">
<violation number="1" location="node-graph/nodes/gstd/src/render_background.rs:55">
P2: Unconditional `1.0 / render_params.scale` can create non-finite transforms when scale is 0. Guard scale before inversion to avoid invalid SVG transform output.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| } => { | ||
| let mut render = SvgRender::new(); | ||
|
|
||
| let logical_transform = glam::DAffine2::from_scale(glam::DVec2::splat(1.0 / render_params.scale)) * render_params.footprint.transform; |
There was a problem hiding this comment.
P2: Unconditional 1.0 / render_params.scale can create non-finite transforms when scale is 0. Guard scale before inversion to avoid invalid SVG transform output.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At node-graph/nodes/gstd/src/render_background.rs, line 55:
<comment>Unconditional `1.0 / render_params.scale` can create non-finite transforms when scale is 0. Guard scale before inversion to avoid invalid SVG transform output.</comment>
<file context>
@@ -52,6 +52,8 @@ async fn render_background<'a: 'n>(
} => {
let mut render = SvgRender::new();
+ let logical_transform = glam::DAffine2::from_scale(glam::DVec2::splat(1.0 / render_params.scale)) * render_params.footprint.transform;
+
if render_params.viewport_zoom > 0. {
</file context>
|
Why is there the Vello vs SVG asymmetry in the first commit? Would this lead to blurry results when embedding raster content using the svg rendering path? |
I think yes, I just accepted the current behavior for SVG but you are likely right that we should also change that. |
cd2121a to
f00b8c1
Compare
|
|
||
| let device_scale = render_params.scale; | ||
| let zoom = footprint.scale_magnitudes().x; | ||
| let zoom = footprint.scale_magnitudes().x / render_params.scale; |
There was a problem hiding this comment.
could the scale be just removed here?
9674ccc to
094e0f3
Compare
The render node(s) pass along the logical instead of the physical scale as part of the footprint, leading to upstream nodes rendering at the wrong scale and producing textures of the wrong size.
wrong at 2.8x scale

correct at 2.8x scale

The first Commit is a minimal fix.
The second makes the create context node responsible for converting the render configs footprint to physical scale and then passing that along. Things that explicitly require logical scale like metadata and svg rendering convert back to logical.
Both approaches work, @TrueDoctor any opinions?
I'm slightly in favor of the second.