没有合适的资源?快使用搜索试试~ 我知道了~
Flutter_iOS_PlatformView_BackdropFilter.pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 162 浏览量
2024-03-27
09:34:35
上传
评论
收藏 6.85MB PDF 举报
温馨提示
试读
23页
Flutter_iOS_PlatformView_BackdropFilter.pdf
资源推荐
资源详情
资源评论
SUMMARY
Implementing iOS PlatformView BackdropFilter. (Blur)
Authors:
Chris Yang(@cyanglaz), Emily Best(@emilyabest), Javon Thomas(@JTKryptic)
Go Link: flutter.dev/go/ios-platformview-backdrop-filter-blur
Created: 6/2022 / Last updated: 10/2022
WHAT PROBLEM IS THIS SOLVING?
Add the ability for an iOS PlatformView to be filtered when it is underneath a
backdrop filtered widget. See: https://github.com/flutter/flutter/issues/43902
Note that when the child of BackdropFilterLayer is a PlatformView, and there are no
PlatformViews underneath the BackdropFilterLayer, the PlatformView does not
need to be filtered. See the layer trees below:
BACKGROUND
PUBLICLY SHARED
PUBLICLY SHARED
A BackdropFilter widget applies a filter to the existing painted content and then
paints its child. The most common use case of the BackdropFilter widget is to blur
the background, but any image filters can be added to the background.
PlatformViews on iOS are not rendered with Skia, instead, they are rendered with
Quartz. As a result, mutations on an iOS PlatformView do not work automatically.
Each mutation has to be implemented separately for iOS PlatformViews. For
example, transform and clipRect on iOS PlatformView is implemented in this PR.
BackdropFilter works differently from other mutators because it applies to a given
region rather than a view/layer. A standard approach to apply a backdrop filter is to
screenshot the requested region and apply the filter to that screenshot.
In general, there are 3 options to apply mutation to a frame containing
PlatformViews.
1. Use Flow to apply the mutation to all layers.
2. Use Quartz to apply the mutation to all layers.
3. Use Flow to apply the mutation to none-PlatformView layers and Quartz to
apply the mutation to PlatformView layers.
See “Decide The Top Level Approach” section for more information on comparing
the 3 options for backdrop filter mutation.
Glossary
● Flow - Flutter’s compositor. Flow knows the layer structures of each frame,
including PlatformView. Flow does not know the content of the PlatformView.
● Quartz - Apple’s 2D drawing engine. Quartz has the knowledge of the
PlatformView’s content. Quartz does not know the layer structure of a frame
that is composite by Flow.
● FlutterView - The UIView that Flutter’s widgets are rendered on. FlutterView
is the parent view of the PlatformView.
● PlatformView - 1. A type of flutter widget that embeds UIView to Flutter
widget tree; 2. The UIView that is embedded.
● PlatformView Layer - The layer represents a PlatformView in the Flutter
engine layer tree.
● BackdropFilter Layer - The layer represents a backdrop filter in the Flutter
engine layer tree. The BackdropFilter layer applies its filter to the layers
beneath itself in a given region. In the context of this project, when a
PlatformView is beneath a BackdropFilter Layer, the PlatformView needs to
be filtered.
● PlatformView Overlay (Or Overlay) - The UIView that Flutter’s widgets are
rendered on if the widgets cover PlatformView. The rect of an overlay is the
intersection of all the flutter widgets and the PlatformView. If a flutter widget
partially covers the PlatformView, the overlay’s rect will be only part of the
widget’s rect. Part of the widget will be rendered on the Overlay and part of
the widget will be rendered on the FlutterView. See Unobstructed
PlatformView for how the overlay rect is decided and the reason behind it.
PUBLICLY SHARED
PUBLICLY SHARED
● Mutation - An effect that applies to the PlatformView which results in a
visual change of the view. Transform, ClipRect, Opacity and Backdrop Filters
are types of the mutations.
● Mutator - A c++ object that represents a mutation.
● Mutator Stack - A stack contains all the mutations to be applied to the
PlatformView. Each PlatformView has its own mutator stack.
● Layer Tree - The layer tree contains the container layers for the mutators
(transform, clip rect, backdrop filter, etc) and the leaf layers for the views that
the mutators will be applied to (platform views, picture layers). When a frame
is built a layer tree of all the mutators and views used is created, and in order
to display the frame, two important functions are called: Preroll and Paint.
● Preroll - The preroll function navigates through the layer tree and
determines what mutators will be applied to PlatformViews. For platform
views, the function pushes the mutator to a global stack, and when it reaches
the platform view layer, it creates a copy of the mutator stack for that specific
view of all the mutators that should be applied to it during paint.
● Paint - The paint function essentially applies all the mutators to each
platform view from their respective mutator stack.
OVERVIEW
The approach we decide to use is to let non-PlatformView widgets to be blurred as
is and apply the blur effect to the PlatformView using a gaussian blur CAFilter. This
approach is similar to how we implemented other mutators. See the “Decide The
Top Level Approach” section for more details on how we came to this solution.
Non-goals
We do not discuss implementing a BackdropFilter with an arbitrary ImageFilter in
this integration. Supporting other ImageFilters on PlatformView is a completely
separate topic and deserves its own project and design document.
DETAILED DESIGN/DISCUSSION
Decide The Top Level Approach
Option 1. Use Flow to apply the mutation to all layers.
Backdrop filter mutation requires the compositor to know the content of the layer.
Because Flow does not know the content of PlatformView, option 1 is impossible.
One workaround would be to convert the content of the PlatformView to a texture
and feed the texture to Flow. We explored the option and there are a few severe
dropbacks:
PUBLICLY SHARED
PUBLICLY SHARED
● There is no arbitrary Quartz API to convert a UIView to texture directly. One
has to snapshot the UIView and convert the resulting UIImage to a texture.
● Snapshotting UIView does not always work for all types of UIViews. For
example, WKWebView cannot be snapshotted. See “Take a screenshot of the
PlatformView and use the CIGaussianBlur filter to blur the screenshot”
section for more discussion on the drawbacks of snapshotting
PlatformVIews.
Option 2. Use quartz to apply the mutation to all layers.
This can be potentially done by adding a UIVisualEffectView as a subView of the
FlutterView and setting the right ZIndex. In a flutter app with PlatformViews, as a
byproduct of “Unobstructed PlatformView”, a layer’s ZIndex in Flow does not
necessarily match its ZIndex in Quartz.
Below is an example of a frame containing PlatformView and Overlay:
In this example, The final composition is made of 3 layers in Quartz. The FlutterView
contains the background orange and the red rectangle widget, the blue
PUBLICLY SHARED
PUBLICLY SHARED
PlatformView, and the overlay contains part of the red rectangle widget that covers
the PlatformView.
Let’s make a scenario where the backdrop filter is to blur everything behind the red
rectangle widget. If we add a backdrop between PlatformView and Overlay, the top
part of the red widget will be blurred, because the top part is rendered in
FlutterView, which is under the backdrop. This makes option 2 impossible under
the current PlatformView/Overlay implementation.
Option 3. Use Flow to apply the mutation to none-PlatformView layers and
Quarts to apply the mutation to PlatformView layers. (Selected)
Because neither option 1 or option 2 is possible, the blur on PlatformView needs to
be applied with Quartz while we keep the non-PlatformView widgets to be blurred
with Flow. Because the blur effect for PlatformView and non-PlatformView is
applied separately without the knowledge of the pixels outside of the blurred
region, the edge between PlatformView and non-PlatformView widget is ignored
with a standard gaussian blur algorithm, which leads to some visual artifacts. See
the Apply Filter Effect section for more details.
The solution for this approach includes 2 parts:
1. Propagate the BackdropFilter mutation to the PlatformView. This includes:
a. adding a new backdrop filter mutator type
b. push the backdrop filter mutator to the mutator stack.
2. After getting the BackdropFilter information from the mutator stack, apply
the blur effect on the PlatformView. There are 3 major approaches to blur a
PlatformView (iOS UIView):
a. Use the “gaussianBlur” filter provided by UIVisualEffectView.
b. Take a screenshot of the PlatformView and use CIGaussianBlur filter to
blur the screenshot.
c. Use the “gaussian” filter provided by SwiftUI.blur.
Propagate The BackdropFilter mutation
Possible Approaches
● Tracking each visited PlatformView
● Rewalking the layer tree
Approach 1: Tracking each visited platform view
This approach essentially keeps each platform view leaf layer that is crossed during
the tree walking. When a platform view is encountered in the layer tree, the
platform view id of that view will be stored in a list. Normally, when a backdrop
filter mutator is encountered in the layer tree, platform view layers that were
PUBLICLY SHARED
剩余22页未读,继续阅读
资源评论
百态老人
- 粉丝: 1184
- 资源: 2万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功