Skip to content

Impeller: Fix for stroked circles with stroke half-width > radius, tessellation scaling - #191102

Merged
cbracken merged 3 commits into
flutter:masterfrom
cbracken:fix-tesselation-dcheck
Aug 15, 2026
Merged

cbracken merged 3 commits into
flutter:masterfrom
cbracken:fix-tesselation-dcheck

Conversation

@cbracken

@cbracken cbracken commented Aug 14, 2026 •

Copy link
Copy Markdown
Member

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 the centre.

Also fixed a small bug in stroked circle division count scaling. 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.

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-assist bot 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.

@cbracken
cbracken requested a review from flar August 14, 2026 05:17
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 14, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Aug 14, 2026
`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
@cbracken
cbracken force-pushed the fix-tesselation-dcheck branch from a6446c8 to a3d1232 Compare August 14, 2026 05:18

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@cbracken cbracken changed the title Impeller: Fix assert on stroked circles wider than their radius Impeller: Fix assert on stroked circles with stroke half-width > radius Aug 14, 2026
flar
flar previously approved these changes Aug 14, 2026

@flar flar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just nits and agreeing with your analysis of the broken code, but otherwise looks good.

`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.
@cbracken
cbracken force-pushed the fix-tesselation-dcheck branch from 3c695cf to 352040a Compare August 14, 2026 11:23
@cbracken cbracken changed the title Impeller: Fix assert on stroked circles with stroke half-width > radius Impeller: Fix for stroked circles with stroke half-width > radius + tessellation scaling Aug 14, 2026
@cbracken cbracken changed the title Impeller: Fix for stroked circles with stroke half-width > radius + tessellation scaling Impeller: Fix for stroked circles with stroke half-width > radius, tessellation scaling Aug 14, 2026

@flar flar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cbracken cbracken added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 14, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 15, 2026
@auto-submit

auto-submit Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Impeller] Crash in debug mode when displaying construction lines

2 participants