Add buffer around rerasterized input to fragment shaders to maintain coordinate space when clipped#181743
Conversation
There was a problem hiding this comment.
Code Review
This pull request aims to fix an issue with fragment shaders by adding a buffer around rerasterized input, which is particularly relevant when clipping is involved. A new test case has been added to validate the fix, and the core logic is updated in RuntimeEffectFilterContents. While the approach of using AnonymousContents to adjust the coverage is sound, the current implementation for calculating the new coverage may lead to unintentional clipping in some scenarios. I've added a specific comment highlighting this potential issue.
engine/src/flutter/impeller/entity/contents/filters/runtime_effect_filter_contents.cc
Show resolved
Hide resolved
|
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. |
|
The goldens demonstrate some different behavior when the transformed textcoords are outside the bounds of the image. That's fine since I don't think we've spent any effort making sure that that case is accounted for yet. |
| const Entity& entity, RenderPass& pass) -> bool { | ||
| return texture_contents.Render(renderer, entity, pass); | ||
| }, | ||
| [maybe_input_coverage, |
There was a problem hiding this comment.
nit:
maybe_input_coverage is an optional rect, right? Since value() will throw an exception anyway if there's nothing, is it more efficient to just dereference and not take the runtime hit of the .value check?
[coverage, entity_offset](const Entity& entity) -> std::optional<Rect> {
return Rect::MakeLRTB(entity_offset.x, entity_offset.y, coverage->GetRight(), coverage->GetBottom());
}
There was a problem hiding this comment.
Since value() will throw an exception anyway if there's nothing
Pedantic note: We (google) compile c++ with exceptions disabled.
is it more efficient to just dereference and not take the runtime hit of the .value check
Dereferencing an std::optional works with an operator overload, it has the same cost as .value(). Capturing the value instead of the optional type in the lambda would have a slight memory improvement because sizeof(std::optional) > sizeof(X). But it's just like 1 byte difference, maybe 4 bytes for padding. I believe that should all be on the stack though so it's not a big deal.
walley892
left a comment
There was a problem hiding this comment.
I think flar will have more interesting feedback. Just a minor question
|
I'm currently trying to wrap my head around the issue. |
@flar Let me try to say it all another way. The backdrop filter operates on the whole backdrop, so if you do a blur, then a fragment shader, both of them should be operating on the full screen. compose(inner: blur, outer: shader, input: image{width: 1024, height: 768}) -> image{width: 1024, height: 768} Where this get's tricky though is if you have a clip rect. Conceptually the backdrop filter is supposed to be running on the whole backdrop, but we know if there is a clip rect, there is no point in blurring content that will be clipped out. So we skipp those pixels. Also, the blur may be returning an image that needs to be scaled up to represent the output since we downsample large sigma blurs, So: blur(image{width: 1024, height: 768}, clip_rect{width: 200, height: 100}) -> image{width: 100, height: 50, scale: 2} What this PR does is rerasterizes the output of the blur, revitalizing the space that had been clipped out so that the fragment shader's local sensitive operations operate as if we had done shader(backdrop) when we do shader(blur(backdrop)). So, There is potentially a more optimized fix here where we manipulate the vertices and texture coords of the shader. That's more difficult to implement and I leave that for a future optimization. |
|
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. |
Clipping affects the output pixels used only. The input pixels are usually determined by asking the filter "if you generate results for pixels in xywh, then what region of input pixels do you require to correctly determine those output pixels". So, for a blur filter that spreads the pixels out over an NxN area, if we need output pixels for R, then we need to run it on input pixels for R.expand(N/2). But custom fragment programs cannot provide us with this information. Built-in filters can express their "reverse bounds" because they are written in C++ and invoked from our C++ renderer. |
flar
left a comment
There was a problem hiding this comment.
I'm not sure what anonymous context does, but it looks like it lets you lie about the coverage geometry of the input and it looks like this will do what you want with the caveat that I'm assuming a lot about how the anonymous contents does its job.
I do agree with gemini here, I'm not sure xy from one source and right/bottom from another mix in any meaningful way. I think you want xy from one source and width/height from the other, no?
| entity_offset](const Entity& entity) -> std::optional<Rect> { | ||
| Rect coverage = maybe_input_coverage.value(); | ||
| return Rect::MakeLTRB(entity_offset.x, entity_offset.y, | ||
| coverage.GetRight(), coverage.GetBottom()); |
There was a problem hiding this comment.
Shouldn't that be MakeXYWH(offset.xy, coverage.wh)?
There was a problem hiding this comment.
If the input coverage is always 0,0 based then Right == Width and Bottom == Height, and the 2 are the same, but it "reads wrong". Shouldn't you be transferring the dimensions and the fact that the bottom right coordinates match the dimensions is "information not readily transparent from this code"? Even if it doesn't fix any issues, I think that using WH vs RB is the better way to express this line.
Or just using the Shift method...
There was a problem hiding this comment.
No, actually, that's not the case. Even if the rect is 0,0 based, by not offsetting the RB coordinates you are indeed clipping it. Imagine a clip that is 100x100 but is positioned with a translation of 500,500. You'd end up with a rect that was Left=500, Right=100 which is backwards and therefore empty. Same with the height.
There was a problem hiding this comment.
No, actually, that's not the case. Even if the rect is 0,0 based, by not offsetting the RB coordinates you are indeed clipping it. Imagine a clip that is 100x100 but is positioned with a translation of 500,500. You'd end up with a rect that was Left=500, Right=100 which is backwards and therefore empty. Same with the height.
I spent a while looking into the width and height of the coverage. That's why I have so many parameters to the added unit test. I too was worried that we could accidentally cause stretching of the circle if we got the width and the height wrong. I switched to the Shift then reverted it. I think this is the correct math and the reason why is that the coordinates are in the global coordinate space. So there is no translation that will make the rect go inside out. If you think there is still an issue with the math I think it would be better if we could express it as a test case to make sure we don't break it in the future.
|
I think the issue with the example you gave with the Alternately, you can tell the After looking at the fix, it seems that you are not intending to solve this underlying problem here, you are just adjusting the "reported geometry" of the intermediate output to match the coordinate space that the shader is expecting? In that case, my code review comment is all I can offer... |
|
Shouldn't the coverage reported by the previous stage result already be in the proper location in local coordinates? I think what we might be seeing here is that our internal filters don't care where the pixels are located - they are pixel-relative - so we haven't been producing the proper output coverage values all along and a runtime shader that is written to care about the frag coords is the first to notice? |
This reverts commit 617549a.
Not quite. I'm not tricking the reported geometry, I'm rasterizing to a texture so that it matches the geometry that is expected in the fragment shader phase. The AnonymousContents is just a Contents whose rendering and coverage is supplied by functions. That is how we are adding padding when we rasterize the blur output. We render the output of the blur into a texture that matches the size that is expected as the input for the fragment shader.
I don't think they are wrong. The blur is doing an optimization and the coverage is just assuming they it be consumed in a way that doesn't care about the context from which they were rendered. The way backdrop filters interact with clip rects though, that's not the case. This PR demonstrates a fix to the issue, but it's possible there is a gap in the math. I think the best thing would be to demonstrate any gap in the math so we can codify it as a unit test to prove that it gets addressed or not. |
|
@flar I increased the limits on the clip rect so we can see all possible combinations for it to alleviate any concerns that there is a case we are missing. |
|
@flar I also tested this PR against this test that uses the composition on a layer filter that isn't backdrop and has a transform and while I'm not sure if the result is 100% what we want, it behaves similar to HEAD except that it doesn't flicker. I think this addresses you concern about having a translate affecting the coverage? Maybe that can be a jumping off point for you to express your concern. TEST_P(AiksTest, ClippedImageFilterWithShader) {
struct FragUniforms {
Vector2 uSize;
} frag_uniforms = {.uSize = Vector2(400, 400)};
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
uniform_data->resize(sizeof(FragUniforms));
memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
auto runtime_stages_result =
OpenAssetAsRuntimeStage("runtime_stage_border.frag.iplr");
ABSL_ASSERT_OK(runtime_stages_result);
std::shared_ptr<RuntimeStage> runtime_stage =
runtime_stages_result
.value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
ASSERT_TRUE(runtime_stage);
ASSERT_TRUE(runtime_stage->IsDirty());
std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
nullptr,
};
auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
uniform_data);
Scalar sigma = 20.0;
Scalar translate_x = 0.0;
Scalar translate_y = 0.0;
auto callback = [&]() -> sk_sp<DisplayList> {
if (AiksTest::ImGuiBegin("Controls", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::SliderFloat("sigma", &sigma, 0, 50);
ImGui::SliderFloat("translate_x", &translate_x, 0, 2048);
ImGui::SliderFloat("translate_y", &translate_y, 0, 1536);
ImGui::End();
}
auto blur_filter =
DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
auto composed_filter =
DlImageFilter::MakeCompose(runtime_filter, blur_filter);
DisplayListBuilder builder;
// Draw a background so we can see the effect against white
DlPaint background_paint;
background_paint.setColor(DlColor::kWhite());
builder.DrawPaint(background_paint);
builder.Save();
builder.Translate(translate_x, translate_y);
// Replicate the clip rect (inset by 66)
builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
DlPaint save_paint;
save_paint.setImageFilter(composed_filter);
builder.SaveLayer(std::nullopt, &save_paint, nullptr);
// Draw some pattern to be filtered
DlPaint pattern_paint;
pattern_paint.setColor(DlColor::kRed());
builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), pattern_paint);
pattern_paint.setColor(DlColor::kBlue());
builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), pattern_paint);
builder.Restore(); // Restore SaveLayer
builder.Restore(); // Restore Save (Clip)
return builder.Build();
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
} |
|
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. |
|
There's a heavy lift in this situation wrt how we got here and how this code affects expectations at the Flutter API level. It's going to take a while for me to get my head around why that code works when it makes no sense from how rectangles work. Pairing an independent xy with a second independent right/bottom is going to have either an intersection or an expansion effect unless it is well documented how the xy and the left/top/right/bottom of the second parameter relate, including what coordinate space each is relative to. |
|
autosubmit label was removed for flutter/flutter/181743, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR. |
… maintain coordinate space when clipped (flutter/flutter#181743)
… maintain coordinate space when clipped (flutter/flutter#181743)
… maintain coordinate space when clipped (flutter/flutter#181743)
… maintain coordinate space when clipped (flutter/flutter#181743)
Roll Flutter from f916dd6887bf to e8f9dc50356d (34 revisions) flutter/flutter@f916dd6...e8f9dc5 2026-02-08 [email protected] Roll Skia from 9325111e6ee4 to b7db9f35f0f2 (1 revision) (flutter/flutter#182062) 2026-02-08 [email protected] Roll Skia from 3167229206b5 to 9325111e6ee4 (1 revision) (flutter/flutter#182061) 2026-02-08 [email protected] Roll Fuchsia Linux SDK from sYqpDF9l9-kldd9_Q... to iqtwdXlgKIyZkL5Li... (flutter/flutter#182058) 2026-02-08 [email protected] Roll Skia from ae78024b261e to 3167229206b5 (1 revision) (flutter/flutter#182055) 2026-02-07 [email protected] Roll Dart SDK from ad6368edbe02 to 965b51c219d3 (1 revision) (flutter/flutter#182050) 2026-02-07 [email protected] Roll Skia from a471f253b941 to ae78024b261e (1 revision) (flutter/flutter#182049) 2026-02-07 [email protected] Roll Fuchsia Linux SDK from IOzzhWfhdzhu3zHsz... to sYqpDF9l9-kldd9_Q... (flutter/flutter#182043) 2026-02-07 [email protected] Roll Dart SDK from 02092faa97c5 to ad6368edbe02 (2 revisions) (flutter/flutter#182040) 2026-02-07 [email protected] Roll Skia from 9a983f6c2c06 to a471f253b941 (24 revisions) (flutter/flutter#182039) 2026-02-07 [email protected] Add buffer around rerasterized input to fragment shaders to maintain coordinate space when clipped (flutter/flutter#181743) 2026-02-07 [email protected] Update Flutter's style guide for dot shorthands and extension methods (flutter/flutter#181934) 2026-02-06 [email protected] Manual roll Skia from 39aa2a70213a to 9a983f6c2c06 (flutter/flutter#181986) 2026-02-06 [email protected] Update doc in foundation to match the style guide (flutter/flutter#181972) 2026-02-06 [email protected] Roll Dart SDK from ec674bdb3ae4 to 02092faa97c5 (11 revisions) (flutter/flutter#182017) 2026-02-06 [email protected] Roll Packages from c197455 to 7805d3e (4 revisions) (flutter/flutter#182016) 2026-02-06 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[cupertino.dart] Implement CupertinoMenuAnchor and CupertinoMenuItem using RawMenuAnchor (#174695)" (flutter/flutter#182010) 2026-02-06 [email protected] Update Dart SDK to 3.12 beta1 (flutter/flutter#181948) 2026-02-06 [email protected] [cupertino.dart] Implement CupertinoMenuAnchor and CupertinoMenuItem using RawMenuAnchor (flutter/flutter#174695) 2026-02-06 [email protected] `flutter_tool` : Remove redundant enum types inside the enum definition scope (flutter/flutter#181910) 2026-02-06 [email protected] Roll pub packages (flutter/flutter#181973) 2026-02-05 [email protected] Roll Fuchsia Linux SDK from J2QdLcY2gyt4NP_xV... to IOzzhWfhdzhu3zHsz... (flutter/flutter#181971) 2026-02-05 [email protected] Directly generate a Mach-O dynamic library using gen_snapshot. [reland] (flutter/flutter#181539) 2026-02-05 [email protected] macOS: Implement tooltip window controller (flutter/flutter#180895) 2026-02-05 [email protected] Constrain RawAutocomplete options by soft keyboard (flutter/flutter#181930) 2026-02-05 [email protected] Roll Skia from 079d092f49e6 to 39aa2a70213a (1 revision) (flutter/flutter#181970) 2026-02-05 [email protected] perf: web ui loadFontFromList (flutter/flutter#181440) 2026-02-05 [email protected] Improve accessibility contrast for pre-test message (flutter/flutter#180469) 2026-02-05 [email protected] Roll pub packages (flutter/flutter#181965) 2026-02-05 [email protected] Roll Skia from 8543ce512d5c to 079d092f49e6 (8 revisions) (flutter/flutter#181964) 2026-02-05 [email protected] Add `clearError` API to Form and FormFieldState (flutter/flutter#180752) 2026-02-05 [email protected] Bump minimum required Xcode version to 15 and recommended to 16 (flutter/flutter#180531) 2026-02-05 [email protected] Rename "widgetTester" parameter to "tester" in "WidgetTesterCallback" (flutter/flutter#180944) 2026-02-05 [email protected] Roll Packages from 3bddf2c to c197455 (3 revisions) (flutter/flutter#181962) 2026-02-05 [email protected] Temporarily remove the Pixel 9/API 36 device from the Firebase Test Lab tests. (flutter/flutter#181956) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 ...
…coordinate space when clipped (flutter#181743) fixes flutter#181660 This works by changing the rerasterization logic such that we will rerasterize the output from the blur filter to an image that matches the dimensions of the input. The undoes the optimization of the clip rect but standardizes the input to the fragment shader so that it is behaving as if the input was the same as a backdrop filter without the blur before hand. I think there may be opportunities in the future to find a way to make this more efficient if we could find some way to rerasterize only to the clipped region but tweak the coordinates in the fragment shader to make it act like it has a whole image. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. 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](https://developers.google.com/gemini-code-assist/docs/review-github-code). 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…coordinate space when clipped (flutter#181743) fixes flutter#181660 This works by changing the rerasterization logic such that we will rerasterize the output from the blur filter to an image that matches the dimensions of the input. The undoes the optimization of the clip rect but standardizes the input to the fragment shader so that it is behaving as if the input was the same as a backdrop filter without the blur before hand. I think there may be opportunities in the future to find a way to make this more efficient if we could find some way to rerasterize only to the clipped region but tweak the coordinates in the fragment shader to make it act like it has a whole image. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. 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](https://developers.google.com/gemini-code-assist/docs/review-github-code). 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…coordinate space when clipped (flutter#181743) fixes flutter#181660 This works by changing the rerasterization logic such that we will rerasterize the output from the blur filter to an image that matches the dimensions of the input. The undoes the optimization of the clip rect but standardizes the input to the fragment shader so that it is behaving as if the input was the same as a backdrop filter without the blur before hand. I think there may be opportunities in the future to find a way to make this more efficient if we could find some way to rerasterize only to the clipped region but tweak the coordinates in the fragment shader to make it act like it has a whole image. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. 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](https://developers.google.com/gemini-code-assist/docs/review-github-code). 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…works internally, see flutter/flutter#181743
fixes #181660
This works by changing the rerasterization logic such that we will rerasterize the output from the blur filter to an image that matches the dimensions of the input. The undoes the optimization of the clip rect but standardizes the input to the fragment shader so that it is behaving as if the input was the same as a backdrop filter without the blur before hand.
I think there may be opportunities in the future to find a way to make this more efficient if we could find some way to rerasterize only to the clipped region but tweak the coordinates in the fragment shader to make it act like it has a whole image.
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.