-
Notifications
You must be signed in to change notification settings - Fork 6k
PlatformView partial blur #36015
PlatformView partial blur #36015
Changes from 5 commits
211e9cc
a0fc0b9
3ffceb5
598a11b
d3fb40a
5c1e65a
d4d74c1
5c0a33e
89f648e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -321,10 +321,11 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { | |
| } | ||
|
|
||
| void FlutterPlatformViewsController::PushFilterToVisitedPlatformViews( | ||
| std::shared_ptr<const DlImageFilter> filter) { | ||
| std::shared_ptr<const DlImageFilter> filter, | ||
| const SkRect& filter_rect) { | ||
| for (int64_t id : visited_platform_views_) { | ||
| EmbeddedViewParams params = current_composition_params_[id]; | ||
| params.PushImageFilter(filter); | ||
| params.PushImageFilter(filter, filter_rect); | ||
| current_composition_params_[id] = params; | ||
| } | ||
| } | ||
|
|
@@ -425,7 +426,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { | |
| CGRectGetWidth(flutter_view.bounds), | ||
| CGRectGetHeight(flutter_view.bounds))] autorelease]; | ||
|
|
||
| NSMutableArray* blurRadii = [[[NSMutableArray alloc] init] autorelease]; | ||
| NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease]; | ||
|
|
||
| auto iter = mutators_stack.Begin(); | ||
| while (iter != mutators_stack.End()) { | ||
|
|
@@ -448,13 +449,29 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { | |
| embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha; | ||
| break; | ||
| case kBackdropFilter: { | ||
| // We only support DlBlurImageFilter for BackdropFilter. | ||
| if ((*iter)->GetFilter().asBlur() && canApplyBlurBackdrop) { | ||
| // Only support DlBlurImageFilter for BackdropFilter. | ||
| if ((*iter)->GetFilterMutation().GetFilter().asBlur() && canApplyBlurBackdrop) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to stop pushing the mutation if it's not supported?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be an optimization in the future. Pushing is done in the shared code across all platforms, to stop pushing we would have to create a way for the iOS PlatformView communicate back to the layer tree. |
||
| // sigma_x is arbitrarily chosen as the radius value because Quartz sets | ||
| // sigma_x and sigma_y equal to each other. DlBlurImageFilter's Tile Mode | ||
| // is not supported in Quartz's gaussianBlur CAFilter, so it is not used | ||
| // to blur the PlatformView. | ||
| [blurRadii addObject:@((*iter)->GetFilter().asBlur()->sigma_x())]; | ||
| CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x(); | ||
| CGRect filterRect = | ||
| flutter::GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect()); | ||
| // `filterRect` reprents the rect that should be filtered inside the `flutter_view_`. | ||
| // The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be | ||
| // filtered. | ||
| CGRect intersection = CGRectIntersection(filterRect, clipView.frame); | ||
| if (CGRectContainsRect(clipView.frame, intersection)) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: CGRectIsNull(_:) instead?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like CGRectContainsRect is more readable. Also, we would have to check both
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://developer.apple.com/documentation/coregraphics/1455346-cgrectintersection says use CGRectIsNull to check if the two rects don't overlap. |
||
| CGRect frameInClipView = [flutter_view_.get() convertRect:intersection toView:clipView]; | ||
| UIVisualEffectView* visualEffectView = [[[UIVisualEffectView alloc] | ||
| initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]] autorelease]; | ||
| PlatformViewFilter* filter = | ||
| [[[PlatformViewFilter alloc] initWithFrame:frameInClipView | ||
| blurRadius:blurRadius | ||
| visualEffectView:visualEffectView] autorelease]; | ||
| [blurFilters addObject:filter]; | ||
| } | ||
| } | ||
| break; | ||
| } | ||
|
|
@@ -463,15 +480,16 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { | |
| } | ||
|
|
||
| if (canApplyBlurBackdrop) { | ||
| canApplyBlurBackdrop = [clipView applyBlurBackdropFilters:blurRadii]; | ||
| canApplyBlurBackdrop = [clipView applyBlurBackdropFilters:blurFilters]; | ||
| } | ||
|
|
||
| // Reverse the offset of the clipView. | ||
| // The clipView's frame includes the final translate of the final transform matrix. | ||
| // So we need to revese this translate so the platform view can layout at the correct offset. | ||
| // Thus, this translate needs to be reversed so the platform view can layout at the correct | ||
| // offset. | ||
| // | ||
| // Note that we don't apply this transform matrix the clippings because clippings happen on the | ||
| // mask view, whose origin is always (0,0) to the flutter_view. | ||
| // Note that the transforms are not applied to the clipping paths because clipping paths happen on | ||
| // the mask view, whose origin is always (0,0) to the flutter_view. | ||
| CATransform3D reverseTranslate = | ||
| CATransform3DMakeTranslation(-clipView.frame.origin.x, -clipView.frame.origin.y, 0); | ||
| embedded_view.layer.transform = CATransform3DConcat(finalTransform, reverseTranslate); | ||
|
|
||
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.
Is this comparing pointer equality?
Uh oh!
There was an error while loading. Please reload this page.
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 is comparing the data. I added a test for it in my latest commit