Repository navigation
Impeller: Fix for stroked circles with stroke half-width > radius, tessellation scaling - #191102
Conversation
`Tessellator::StrokedCircle` delegated to `GenerateStrokedCircle` whenever `half_width > 0`, but that generator zig-zags between an inner and an outer circle and asserts `half_width < radius`, since the inner radius goes negative once the stroke is at least as wide as the radius. That case should render as a filled circle whose radius reaches the outer edge of the stroke. We were hitting this when enabling construction lines during debugging. With `debugPaintSizeEnabled` set, `RenderSliver.debugPaint` draws a circle of radius 2.0 with a stroke width of 4.0, so toggling construction lines on in unopt builds triggered this `FML_DCHECK`: ``` [FATAL:flutter/impeller/tessellator/tessellator.cc(755)] Check failed: data.half_width > 0 && data.half_width < data.radii.width. ``` `GenerateStrokedArc` had the same issue but didn't assert: the inner radii went negative and the inner edge folded back through the centre of the oval, producing a self-intersecting strip. We now clamp to zero. Fixes: flutter#190597
a6446c8 to
a3d1232
Compare
There was a problem hiding this comment.
Code Review
This pull request updates the Impeller Tessellator to correctly handle wide strokes for circles and arcs. When a stroked circle's stroke width is greater than or equal to its radius, it is now tessellated as a filled circle reaching the outer edge of the stroke. For stroked arcs, the inner radius is clamped to zero to prevent self-intersection when the stroke width exceeds the base radii. Corresponding unit tests have been added to verify these changes. There are no review comments, so I have no feedback to provide.
flar
left a comment
There was a problem hiding this comment.
Just nits and agreeing with your analysis of the broken code, but otherwise looks good.
ac630f3 to
3c695cf
Compare
`Tessellator::StrokedCircle` computes its quadrant divisions based on the radius. The radius in this case should be the circle radius + the stroke half-width to get the outer radius of the resulting filled circle. The effect would be under-tessellation of the outer edge that gets worse with increasing half-width. This tosses a pair of brackets on to scale the whole thing.
3c695cf to
352040a
Compare
|
autosubmit label was removed for flutter/flutter/191102, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
Tessellator::StrokedCircledelegated toGenerateStrokedCirclewheneverhalf_width > 0, but that generator zig-zags between an inner and an outer circle and assertshalf_width < radius, since the inner radius goes negative once the stroke is at least as wide as the radius. That case should render as a filled circle whose radius reaches the outer edge of the stroke.We were hitting this when enabling construction lines during debugging. With
debugPaintSizeEnabledset,RenderSliver.debugPaintdraws a circle of radius 2.0 with a stroke width of 4.0, so toggling construction lines on in unopt builds triggered thisFML_DCHECK:GenerateStrokedArchad the same issue but didn't assert: the inner radii went negative and the inner edge folded back through the centre of the oval, producing a self-intersecting strip. We now clamp to the centre.Also fixed a small bug in stroked circle division count scaling.
Tessellator::StrokedCirclecomputes its quadrant divisions based on the radius. The radius in this case should be the circle radius + the stroke half-width to get the outer radius of the resulting filled circle.The effect would be under-tessellation of the outer edge that gets worse with increasing half-width. This tosses a pair of brackets on to scale the whole thing.
Fixes: #190597
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.