Gemini created these notes. They can contain errors so should be double-checked. How Gemini takes notes
Drag image to reposition
Outline
Outline
Document tabs
Flutter iOS PlatformView BackdropFilter
0
Headings you add to the document will appear here.
SUMMARY
WHAT PROBLEM IS THIS SOLVING?
BACKGROUND
Glossary
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
Non-goals
DETAILED DESIGN/DISCUSSION
Decide The Top Level Approach
Propagate The BackdropFilter mutation
Possible Approaches
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 traversed before the backdrop filter call do not know to blur. To combat this, we would use the list of platform view ids to manually push the mutation to the mutator stack of each platform view that needs to be blurred. This would work because at any point in the layer tree walking, the list would only contain the platform view ids of previously encountered views, so we would only touch the stacks of the platform views we need to blur.
Possible Implementation
To implement this approach, a list with its getter and setter methods could be created within embedded_views.h to hold the visited platform views. The visited platform view ids could be pushed to the list from platform_view_layer.cc. To update the mutator stacks of the visited platform views, the blur mutation would be pushed from backdrop_filter_layer.cc, and a method to receive the mutation, cycle through the list, and push the mutation to each view could created and implemented within FlutterPlatformViews.mm.
Approach 2: Rewalking the layer tree
This approach would rewalk the layer tree when a backdrop_filter_layer’s preroll method is called and push the blur mutation to each platform views mutator stack it encounters beforehand in real time. When a platform view is encountered in the layer tree, a flag will be set. As the tree walking continues, if a backdrop filter mutation is found later in the tree, it will call for a second walking of the tree up to the point of the current backdrop filter call, and each platform view encountered during this second walking will have the blur mutation pushed to their mutator stack
Possible Implementation
To implement this approach, a flag would be created within the embedded_views.h. When a platform view is encountered in the layer tree, the flag would be triggered through platform_view_layer.cc. When a backdrop filter mutation is later found in the layer tree, a separate second walking of the tree would be triggered by the backdrop filter layer, and the blur mutation would be pushed from the backdrop filter layer as well. From here, the blur could either be received by the platform view layer and pushed to the mutator stacks from platform_view_layer.cc, or the blur mutation could be pushed to FlutterPlatformViews.mm, along with the platform view id from platform_view_layer.cc, and the mutator stacks would be updated from there.
Approach Comparison
Readability
Approach 1 is the easier approach of the two to read and understand. The concept of storing the platform views to a list as they are encountered in the layer tree and manually pushing the blur mutation to each view in the list is very simple and easy to understand. Approach 2 would require a little more of an understanding of the layer tree and how the tree walking is achieved by the flutter engine.
Implementation
The implementation of Approach 1 would be simpler than that of Approach 2. The process of creating the list, populating it with the platform view ids, and pushing the blur to the mutator stacks is not a very complex process and should be fairly simple to implement. While creating and triggering the flags for Approach 2 may be simple, implementing the additional walk of the layer tree will be a lot more complex of a process. In addition, the second walking of the layer tree does not walk the entire tree, but must stop at the backdrop filter mutation that triggered the second walking in the first place. Because of this, this approach would also require the implementation of a way for the layer tree to know to stop at the backdrop filter layer, and how to know which backdrop filter layer within the tree to stop at if there are multiple.
Space Efficiency
Approach 1 creates the list of platform view ids which, although minimal, still takes up space and affects the build time of the engine and apps within flutter. This can be improved slightly with lazy initialization, which would only allocate space for the list once the first platform view id is populated. Additionally, if a backdrop filter mutator is not found within the layer tree walking, a list full of platform view ids was still created but unused, taking up space unnecessarily. Approach 2 does not create any additional objects or data structures besides the flag, making this approach more space efficient.
Time Efficiency
Approach 1 adds one loop when pushing the blur mutation to the platform views logged within the list, this process being O(n) as it only loops one time, but as far as overall time efficiency is concerned, this approach should not greatly affect the time composing a frame. Approach 2, when no backdrop filter mutation is found within the layer tree or no platform views were found before a backdrop filter mutation, should have no effect on the time composing a frame as it will not call for a rewalk of the tree. When a backdrop filter is found within the layer tree, and a platform view was found before its call, then this approach will call for a rewalk of the layer tree. The walking of the layer tree will be O(n) as it only walks through the tree one extra time, however a rewalking of the tree will likely affect the time composing a frame more than that of Approach 1.
Chosen Approach
Step 1: Track each visited platform view
Step 2: Creating backdrop filter mutator
To create the backdrop filter mutator, we had to update Mutator and MutatorsStack classes in embedded_views.h. For the Mutator class, a backdrop filter MutatorType and its respective constructors were created. In MutatorsStack class, we defined the push function for the backdrop filter mutator. The PushBackdropFilter method is then defined within embedded_views.cc