Add some extra slack room for stroked and filled circles that use the SDF shader#183536
Add some extra slack room for stroked and filled circles that use the SDF shader#183536auto-submit[bot] merged 13 commits intoflutter:masterfrom
Conversation
|
Will likely have to update goldens |
There was a problem hiding this comment.
Code Review
This pull request expands the geometry for stroked and filled circles that use the SDF shader, which allows for a two-sided fade and improves the appearance of anti-aliasing. The changes involve updating CircleContents and CircleGeometry to handle the expanded geometry, and modifying the circle.frag shader to implement the new fading logic.
My review identified two related issues concerning the handling of stroke_width coordinate spaces. In circle_contents.cc, the stroke width is passed to the shader in local units instead of the required screen units. In circle_geometry.cc, the calculation for the stroke's half-width for the geometry tessellator is incorrect due to a similar coordinate space mismatch. I've provided suggestions to correct these issues.
engine/src/flutter/impeller/display_list/aiks_dl_basic_unittests.cc
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| float outer_distance = distanceFromCircle(outer_radius, center, point); | ||
| void main() { |
There was a problem hiding this comment.
I don't usually say this but there is a lot of dense math happening here that takes a while to parse. Some comments outlining the procedure would be helpful so people don't have to parse everything in order to orient themselves.
There was a problem hiding this comment.
This, in general, in a lot of our code...
There was a problem hiding this comment.
I think I've got the right understanding here, I took Flar's math directly and looked at it for a while until it made sense. @flar, does the comments sound about right to you?
There was a problem hiding this comment.
Perhaps for a general comment at the top of this function we could say something like:
// We need to make sure that for stroked circles we have a cross section
// that is at least as wide as a pixel. The cross section is measured towards
// the center of the circle which is the same direction in both local and screen
// coordinates for uniformly scale transforms and only slightly off for skewed
// transforms.
|
Spot checking the Google test results and the results look smoother with this change. |
|
In some of the flutter gold results, the object changed colors completely...? |
flar
left a comment
There was a problem hiding this comment.
Some nits that I think should be addressed, but I'll leave it to you whether you want me to double check the results...
I changed the translation and the background in the test. Changed back |
|
Golden file changes are available for triage from new commit, Click here to view. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
| std::unique_ptr<CircleGeometry> geometry, | ||
| Color color, | ||
| bool stroked) { | ||
| geometry->SetAntialiasPadding(kAntiliasPixels); |
There was a problem hiding this comment.
This method is used for both AA and non-AA circles, only the caller knows which. This call should be moved up to the canvas.cc methods that create the geometry and know which type they want.
There was a problem hiding this comment.
Are you talking about CircleContents::Make? It's only used for AA circles. The contents is the thing that controls which shader to use, and the circle_contents uses the SDF shader which applies antialiasing.
There was a problem hiding this comment.
The name doesn't suggest that.
It has the same arguments as a constructor that is used for non-AA circles.
How is the caller to know this?
If, in the future, the non-AA case decides it wants to move from a stack allocated contents to a shared_ptr contents, it will suddenly generate the wrong geometry. And vide-versa.
There was a problem hiding this comment.
I'm facing a similar situation with the UberSDFContents. I like Jim's point on surfacing the idea of antialiasing somehow into the canvas level. An easy solution is to make the canvas set the antialias amount on the geometry. We're going to have to foist that value up to the canvas level at some point.
On thing that is weird here too is that by adding the antialias amount to the geometry we create data on it that is ignored in other instances. Don't you find that odd? I guess the alternative is to have an AntialiasedCircleGeometry or storing the antialias amount on the contents which might be awkward?
There was a problem hiding this comment.
If, in the future, the non-AA case decides it wants to move from a stack allocated contents to a shared_ptr contents, it will suddenly generate the wrong geometry. And vide-versa.
If someone were to somehow refactor the non-AA case to use a CircleContents (and created it via CircleContents::Make()), they may be surprised to end up with both the extra geometry and an SDF-antialiasing shader being applied (the latter being applied with no regard for the geometry).
I guess the alternative is to have an AntialiasedCircleGeometry or storing the antialias amount on the contents which might be awkward?
The contents (in this PR) stores and controls the antialias amount. It needs to at least store it in order to pass it along to the shader.
Maybe we need an AntialiasedCircleGeometry and an AntialiasedCircleContents to disambiguate the API? I also think that this will all change very soon with https://github.com/orgs/flutter/projects/240. My main goal in this PR is to address the immediate visual issues users are experiencing.
There was a problem hiding this comment.
On thing that is weird here too is that by adding the antialias amount to the geometry we create data on it that is ignored in other instances. Don't you find that odd? I guess the alternative is to have an AntialiasedCircleGeometry or storing the antialias amount on the contents which might be awkward?
It's not "ignored" in other instances. The other instances are simply asking for no padding for antialiasing. It's default is (should be?) 0. But, it is applied in all uses, it just has no effect when it is left at 0.
There was a problem hiding this comment.
I suspect that the way we reuse the CircleGeometry for both AA and non-AA cases will be reflected in other geometries as well. Their basic role is the same regardless of whether they've been padded for AA.
There was a problem hiding this comment.
One thing that we will need to decide about. There is a difference between "aa pixels" and "aa padding". For a rectangle, they are the same, but for a circle, the padding is theoretically sqrt2*aa_pixels. Rather than have a configurable "padding amount", the geometries should have a configurable "aa pixels" and then they can decide what their padding is based on how their geometry works.
Of course, in practice, when I brought up the issue of the sqrt2 before, I eventually convinced myself that the slightly larger radius didn't matter. But, it points out that the caller is not necessarily in the best context to know how much padding will be needed.
There was a problem hiding this comment.
The padding vs pixels may matter more for AA lines which really care more about the angular fidelity compared to a circle where that fidelity is constantly changing through its circumference. Also, we may find that developers will care about the tiny amount of fidelity that padding by sqrt2 matters for circles. It's best not to assume that geometry constructor/callers understand the issues we see today and that we discover tomorrow wrt the actual best number of pixels to pad any given geometry by.
There was a problem hiding this comment.
@flar we are going to revisit this for the UberSDF. I think this is an acceptable approach for now. How about we accept this and wrap the cleanup into the ubersdf work? We don't want to mix this up with the ubersdf since that will make it hard to cherry-pick. I share your concerns and we'll get it hashed out.
I'm good with punting these issues to the Uber shader. We currently have a misspelling, but we can fix that either here or there as well...
|
autosubmit label was removed for flutter/flutter/183536, because This PR has not met approval requirements for merging. Changes were requested by {flar}, please make the needed changes and resubmit this PR.
|
| circle_geometry->GetPositionBuffer(renderer, entity, pass); | ||
| return geometry_result; | ||
| } | ||
| Scalar kAntiliasPixels = 1.0; |
There was a problem hiding this comment.
This configuration should be similar across all AA rendering so perhaps this should be moved to a more central location. Canvas?
There was a problem hiding this comment.
Also, it's misspelled. Antilias -> Antialias
There was a problem hiding this comment.
We can leave this for the Uber work to sort.
flar
left a comment
There was a problem hiding this comment.
The implementation works fine as is. The remaining issues, mostly about internal API, can be fixed as we continue to develop and generalize the basic concepts.
It looks like the background is still different? |
|
|
||
| flutter::DisplayListBuilder builder; | ||
|
|
||
| DlPaint background_paint; |
There was a problem hiding this comment.
Are these deleted lines intentional?
There was a problem hiding this comment.
Yeah, that's what caused the background diff. I found it easier to look at the result with a white background. Both you and Willie commented on it though, so I'm probably the weird one - changing back.
There was a problem hiding this comment.
I just wanted to make sure it was intentional...
|
An existing Git SHA, To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with |
|
Golden file changes are available for triage from new commit, Click here to view. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
This PR expands the geometry of stroked and filled circles that use the SDF shader. This allows the fading to occur in both the inside and outside of the rendered circle, improving appearance - especially on thinner stroked circles.
This addresses the issues noted in #182708 and #183002
Fixes #183418
Sample using Skia:

Sample at HEAD:

Sample after this change:
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on [Discord].
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.