-
Notifications
You must be signed in to change notification settings - Fork 6k
[ios_platform_view] MaskView pool to reuse maskViews. #38989
[ios_platform_view] MaskView pool to reuse maskViews. #38989
Conversation
d2e8e43
to
d9aa181
Compare
reuse mask view format format draft draft fixes test
d9aa181
to
ef09d5b
Compare
@interface FlutterClippingMaskViewPool () | ||
|
||
@property(assign, nonatomic) NSUInteger capacity; | ||
@property(retain, nonatomic) NSMutableArray<FlutterClippingMaskView*>* pool; |
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.
Would this retain the FlutterClippingMaskView
even after the ChildClippingView
is dealloc'd?
Would NSPointerArray
with NSPointerFunctionsWeakMemory
(I think zeroes it out with MRC but worth testing) work better here? If you could reliably know the mask views in the pool are used (because they are retained by a ChildClippingView
), then you could get rid of recycleMaskViews
and during insert compact
, then insert at count
if there was capacity.
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.
Well never mind, retaining it after the ChildClippingView
is dealloc'd is the whole point of this PR...
Can you confirm that deallocating FlutterPlatformViewsController
releases the pool and the mask views?
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.
Will add a test for it!
@@ -328,6 +353,7 @@ class FlutterPlatformViewsController { | |||
fml::scoped_nsobject<FlutterMethodChannel> channel_; | |||
fml::scoped_nsobject<UIView> flutter_view_; | |||
fml::scoped_nsobject<UIViewController> flutter_view_controller_; | |||
fml::scoped_nsobject<FlutterClippingMaskViewPool> mask_view_pool_; |
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 there a reason to make this a scoped_nsobject
?
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, I should change it to properties. I was blindly following the current pattern.
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.
Oh, actually, it is in a c++ class. So I think scoped_nsobject is better that the lifecycle is automatically managed.
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.
Which class is c++? Your new FlutterClippingMaskViewPool
is a Obj-C class.
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.
FlutterPlatformViewsController is the c++ class.
@interface FlutterClippingMaskViewPool () | ||
|
||
@property(assign, nonatomic) NSUInteger capacity; | ||
@property(retain, nonatomic) NSMutableArray<FlutterClippingMaskView*>* pool; |
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.
Well never mind, retaining it after the ChildClippingView
is dealloc'd is the whole point of this PR...
Can you confirm that deallocating FlutterPlatformViewsController
releases the pool and the mask views?
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.
Just a question on the pool capacity.
- (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame { | ||
FML_DCHECK(self.availableIndex <= self.capacity); | ||
FlutterClippingMaskView* maskView; | ||
if (self.availableIndex == self.capacity) { |
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 looks like the capacity
is not updated? should it be increased when you add a new one?
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.
we can probably just compare with pool.count
, and do not keep this capacity ivar?
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.
The capacity is a static limit set for the pool. My intention is to limit the memory used by the pool. For example, (it is probably not possible in real life), I don't want the pool to cache 20 views for the whole application session.
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.
gotcha. I mistakenly thought that this capacity increases like an NSMutableArray.
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.
Ah, yeah it could be confusing, I added a comment.
@@ -451,6 +453,17 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, | |||
return clipCount; | |||
} | |||
|
|||
void FlutterPlatformViewsController::ClipViewAddMaskView(UIView* clipView) { |
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.
supernit: ClipViewSetMaskView
?
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.
done
…118938) * 2ee82578c [ios_platform_view] MaskView pool to reuse maskViews. (flutter/engine#38989) * c137b3b33 Roll Fuchsia Mac SDK from GvtVLigysBcywNN9T... to ZTKDeVL1HDAwsZdhl... (flutter/engine#39044) * 3a444b366 Roll Dart SDK from 807077cc5d1b to 8c2eb20b5376 (2 revisions) (flutter/engine#39047)
* reuse maskView reuse mask view format format draft draft fixes test * comments * fix comment * test for releasing maskView * updates * fix
…skViews. (flutter#38989)" (flutter#39490)" (flutter#39498)" This reverts commit 4270d74.
…er#39608) * Revert "Revert "Revert "[ios_platform_view] MaskView pool to reuse maskViews. (flutter#38989)" (flutter#39490)" (flutter#39498)" This reverts commit 4270d74. * fix build error
cp #42823. The PR fixes flutter/flutter#125620, which was a regression caused by #38989. We cannot simply revert #38989 because #38989 addressed a critical performance issue [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
The maskViews are constructed and destructed every frame for every PlatformView on the screen. It slows down the performance quite a lot.
This PR adds a pool that caches maximum of 5 maskViews. These maskViews are reused every frame.
If there are more than 5 maskViews required in a frame, extra maskViews are constructed and destructed each frame. (This scenario is very unlikely in real life application)
Part of flutter/flutter#116640
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.