-
Notifications
You must be signed in to change notification settings - Fork 29.8k
[Engine] iOS style blurring #175458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Engine] iOS style blurring #175458
Conversation
4db959d to
fcabe26
Compare
e879ce1 to
44678e0
Compare
gaaclarke
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I'm good with the approach. It's on a good trajectory. You need to add a golden test to aiks_dl_blur_unittests.
engine/src/flutter/display_list/effects/image_filters/dl_blur_image_filter.h
Show resolved
Hide resolved
| pass.SetPipeline( | ||
| renderer.GetDownsampleSoftwareDecalPipeline(pipeline_options)); | ||
| Rect bounds_rect = | ||
| pass_args.bounds_uv.value_or(Rect::MakeLTRB(0, 0, 1, 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this match old behavior when setting the bounds to (0,0,1,1)? Seems like that is potentially doing clipping that wasn't happening before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should match the old behavior.
The if branch works in the following way: (I've added this new commment above this statement)
// If the blur is unbounded, then the pipeline is selected based on
// whether the platform supports decal tile mode: The GLES backend
// conditionally supports decal tile mode, while decal is always supported
// for Vulkan and Metal.
//
// If the blur is bounded, software decal is always needed.So there are two ways to enter the else branch. The first way is that the blur is unbounded, and the else branch is chosen because of GLES, corresponding to GetDownsampleTextureGlesPipeline before the PR, whose behavior was defined by the Sample as follows:
vec4 Sample(vec2 uv) {
#ifdef SUPPORTS_DECAL // 0 for GLES
return texture(texture_sampler, uv, float16_t(kDefaultMipBias));
#else
if ((uv.x < 0 || uv.y < 0 || uv.x > 1 || uv.y > 1)) {
return vec4(0);
} else {
return texture(texture_sampler, uv, float16_t(kDefaultMipBias));
}
#endif
}The Sample function always checks the coord against (0,0,1,1).
The second way is that the blur is bounded. In this case the coord is checked against the bounds.
engine/src/flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
Outdated
Show resolved
Hide resolved
| case 0: | ||
| blur = std::make_shared<GaussianBlurFilterContents>( | ||
| blur_sigma_x.sigma, blur_sigma_y.sigma, | ||
| blur_sigma_x.sigma, blur_sigma_y.sigma, std::nullopt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a good place to expand the arguments to be able to control this. It's not an automated test though so it's optional. It would be helpful for you probably to mess around with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've attempted to mess around it but it's kind of complicated considering all the transform matrices and texture stuff. I think it'd be better done in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you get a chance to test how the bounded blur reacts to transforms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. As shown in the playground demo (in the latest comment) and the golden test, the blur bound respects the current transform matrix.
engine/src/flutter/impeller/entity/shaders/filters/gaussian.frag
Outdated
Show resolved
Hide resolved
engine/src/flutter/impeller/entity/shaders/filters/gaussian.frag
Outdated
Show resolved
Hide resolved
engine/src/flutter/impeller/entity/shaders/filters/gaussian.frag
Outdated
Show resolved
Hide resolved
|
I don't know if you are ready yet, but I'm going to hold off reviewing again until we get this PR green through CI so we can see the goldens. Let me know if you need any help getting it through. |
|
web part looks good! |
|
Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change). If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review. 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. |
|
gaaclarke : I'm aware that the golden test isn't representative. Actually some maths of the shaders aren't right, and I've been trying to figure them out for days. I'll let you know when I made progress. |
Thanks for the heads up. Let me know when you need me to look again. |
|
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. |
|
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. |
|
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. |
|
I've completed the PR and it should be ready to review. Here are notable changes:
Screen.Recording.2025-10-02.at.1.00.36.PM.mp4
Screen.Recording.2025-10-02.at.1.06.09.PM.mp4
|
|
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. |
|
It's been a second since I looked at this. I think you may have answered this in the past but it wasn't captured. Can you remind me why we couldn't implement this by tweaking the downsample pass to conditionally the crop the gutter and set the tilemode to clamp? So for example, in the case where we are blurring something that is running out of content it looks like this: input: downsample output: Then the blur is executed on it. If instead the downsample output was similar to the input with a tilemode set to clamp, wouldn't that give you the same result? |
|
@gaaclarke This PR is ready for a (hopefully final) review. For your convenience, here are the changes since the last review: Commit c9e56b1 rewrote some documents to reflect the fact that It also adds another option "Tile mode" to the playground. As we analyzed the last time, tile mode can still affect bounded blur if the blur bound crosses texture bound. Check out the following video while paying attention to the top left corner of the window. Screen.Recording.2025-12-22.at.11.04.56.AM.movCommit 8f59f39 reorders the parameters by placing
|
gaaclarke
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, thanks for all the following up and clarifying. I'm happy with were we ended up.
| /// The `bounds` rectangle is specified in the canvas's current coordinate | ||
| /// space (it is affected by the current transform). Consequently, the bounds | ||
| /// may not be axis-aligned in canvas coordinates. | ||
| /// space and is affected by the current transform; consequently, the bounds | ||
| /// may not be axis-aligned in the final canvas coordinates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No action required: I wish we had a canonical word for this coordinate space. I typically call it local coordinate space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah honestly I would call it "local coordinate" but I don't think it's clear enough for many people, which matters more.
|
@gaaclarke Thank you so much for patiently working through this PR with me! |
|
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. |
…10674) Manual roll Flutter from 57c3f8b66525 to 6ff7f300473f (83 revisions) Manual roll requested by [email protected] flutter/flutter@57c3f8b...6ff7f30 2025-12-23 [email protected] Roll Packages from f28cf2e to 5e3a766 (3 revisions) (flutter/flutter#180232) 2025-12-23 [email protected] Roll Fuchsia Linux SDK from CmFPyvSc-K8_WDd5p... to 5EgkVbjGVZmCFPdtR... (flutter/flutter#180230) 2025-12-23 [email protected] Roll Skia from db7ec9a14905 to bdb147ae3040 (2 revisions) (flutter/flutter#180222) 2025-12-23 [email protected] Add SnackBarTheme (flutter/flutter#180001) 2025-12-23 [email protected] Roll Skia from 0b1ba3920f1c to db7ec9a14905 (1 revision) (flutter/flutter#180219) 2025-12-23 [email protected] Roll Dart SDK from 31e9f619e18a to 94b05f717ba3 (1 revision) (flutter/flutter#180216) 2025-12-23 [email protected] Roll Skia from a3e4f7b9d5f3 to 0b1ba3920f1c (1 revision) (flutter/flutter#180214) 2025-12-23 [email protected] Roll Skia from b8517d1e25f7 to a3e4f7b9d5f3 (2 revisions) (flutter/flutter#180211) 2025-12-23 [email protected] [Engine] iOS style blurring (flutter/flutter#175458) 2025-12-23 [email protected] Roll Dart SDK from 2243e91acaf2 to 31e9f619e18a (1 revision) (flutter/flutter#180210) 2025-12-22 [email protected] Add error description for nbsp character(\u202f) (flutter/flutter#178895) 2025-12-22 [email protected] Roll Skia from 98c01ea504d7 to b8517d1e25f7 (1 revision) (flutter/flutter#180207) 2025-12-22 [email protected] Small clean up in `LocalizationPlugin` (flutter/flutter#180053) 2025-12-22 [email protected] Roll Skia from c5beca8fa90b to 98c01ea504d7 (2 revisions) (flutter/flutter#180202) 2025-12-22 [email protected] Roll Dart SDK from cff33b09b24d to 2243e91acaf2 (1 revision) (flutter/flutter#180199) 2025-12-22 [email protected] Remove usages of Android's `AsyncTask` in favor of `java.util.concurrent` (flutter/flutter#180050) 2025-12-22 [email protected] Roll Fuchsia Linux SDK from 18ZvfJB61p7Z8HAaC... to CmFPyvSc-K8_WDd5p... (flutter/flutter#180193) 2025-12-22 [email protected] Roll Skia from 7b7083ed9d57 to c5beca8fa90b (5 revisions) (flutter/flutter#180187) 2025-12-22 [email protected] Roll Dart SDK from 38812d17127d to cff33b09b24d (1 revision) (flutter/flutter#180185) 2025-12-22 [email protected] Roll Skia from 0eef18a0e2e6 to 7b7083ed9d57 (1 revision) (flutter/flutter#180184) 2025-12-22 [email protected] Roll Dart SDK from 66c8013acbff to 38812d17127d (1 revision) (flutter/flutter#180179) 2025-12-21 [email protected] Roll Skia from 6fbc6c75b9bb to 0eef18a0e2e6 (2 revisions) (flutter/flutter#180176) 2025-12-21 [email protected] Roll Fuchsia Linux SDK from kGnnY1-fTWwYAnk8e... to 18ZvfJB61p7Z8HAaC... (flutter/flutter#180173) 2025-12-21 [email protected] Roll Skia from 1a4ca755288a to 6fbc6c75b9bb (1 revision) (flutter/flutter#180167) 2025-12-20 [email protected] Roll Skia from 2ad7452bd9d1 to 1a4ca755288a (1 revision) (flutter/flutter#180160) 2025-12-20 [email protected] Roll Fuchsia Linux SDK from oe10epXkqGnv21AbZ... to kGnnY1-fTWwYAnk8e... (flutter/flutter#180158) 2025-12-20 [email protected] Roll Skia from b01ad49ea807 to 2ad7452bd9d1 (1 revision) (flutter/flutter#180155) 2025-12-20 [email protected] Roll Dart SDK from 8fb1c0c0a8ae to 66c8013acbff (1 revision) (flutter/flutter#180154) 2025-12-20 [email protected] Remove unnecessary RadioGroup migration TODOs (flutter/flutter#180105) 2025-12-20 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[reland] Unify canvas creation and Surface code in Skwasm and CanvasKit (#179473)" (flutter/flutter#180152) 2025-12-20 [email protected] Roll Skia from 3cc7e81928f0 to b01ad49ea807 (1 revision) (flutter/flutter#180151) 2025-12-20 [email protected] Roll Dart SDK from ac95c6e8a31d to 8fb1c0c0a8ae (1 revision) (flutter/flutter#180148) 2025-12-19 [email protected] Roll pub packages (flutter/flutter#180146) 2025-12-19 [email protected] Roll Skia from fa4434632ce6 to 3cc7e81928f0 (4 revisions) (flutter/flutter#180142) 2025-12-19 [email protected] [reland] Unify canvas creation and Surface code in Skwasm and CanvasKit (flutter/flutter#179473) 2025-12-19 [email protected] Roll Skia from ae5dd72b3591 to fa4434632ce6 (2 revisions) (flutter/flutter#180136) 2025-12-19 [email protected] Semantics headingLeveldoc update (flutter/flutter#179999) 2025-12-19 [email protected] Fix an issue where the semantics announce event may be encoded as either an int32_t or an int64_t depending on its value (flutter/flutter#180071) 2025-12-19 [email protected] [ Web ] Pass `--enable-experimental-ffi` when compiling WASM tests (flutter/flutter#180127) 2025-12-19 [email protected] Roll Dart SDK from cfc117d10d36 to ac95c6e8a31d (1 revision) (flutter/flutter#180130) 2025-12-19 [email protected] Pass canaryFeatures to BuildSettings (flutter/flutter#180108) 2025-12-19 [email protected] Roll Skia from fe2be289c9fe to ae5dd72b3591 (1 revision) (flutter/flutter#180129) 2025-12-19 [email protected] Roll Packages from 6f392aa to f28cf2e (1 revision) (flutter/flutter#180124) 2025-12-19 [email protected] Set text input purpose and hints on Linux platform (flutter/flutter#180013) ...
This PR adds the engine support for a new iOS-style blur. It works by adding parameters to the blur filter that specify its blurring bounds.
This is the engine-side implementation. The corresponding framework changes that expose this to developers are in:
ImageFilterConfig#175473Related issues:
Design doc & previous discussions: flutter.dev/go/ios-style-blur-support
The Visual (Before & After)
This new mode, which I'm calling "bounded blur," is different from the traditional (global) gaussian blur in that blurs would not sample transparent pixels from outside the provided area.
The demo below shows the old blur (left) and the new bounded blur (right). Both are blurring a black triangle.
Notice the new version on the right no longer has the bright "lining" at the top and left edges. This is because the blur algorithm now knows its own bounds and correctly stops sampling pixels from outside that area.
Technical details
API Change
To pass the bounds information down, I've added new parameters to
_initBlur:How the Bounds Are Used
These bounds are passed all the way down to
GaussianBlurFilterContentsand affect two key parts of the process:Notable Engine Changes
To handle the downsampling logic, I created a new downsampling shader
texture_downsample_bounded.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.