17#import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
39 std::shared_ptr<flutter::OverlayLayer>
layer;
41using LayersMap = std::unordered_map<int64_t, LayerData>;
48 NSObject<FlutterPlatformView>*
view;
55 CATransform3D
transform = CATransform3DIdentity;
83 layer.anchorPoint = CGPointZero;
84 layer.position = CGPointZero;
88 return CGRectMake(clipDlRect.GetLeft(),
90 clipDlRect.GetWidth(),
91 clipDlRect.GetHeight());
95 auto iter =
params.mutatorsStack().Begin();
96 while (iter !=
params.mutatorsStack().End()) {
97 switch ((*iter)->GetType()) {
116 auto iter =
params.mutatorsStack().Begin();
117 while (iter !=
params.mutatorsStack().End()) {
118 switch ((*iter)->GetType()) {
127 auto transformed_path =
139 auto transformed_path =
171@property(nonatomic, readonly)
172 std::unordered_map<int64_t, std::unique_ptr<flutter::EmbedderViewSlice>>& slices;
176@property(nonatomic, readonly)
177 std::unordered_map<std::string, NSObject<FlutterPlatformViewFactory>*>& factories;
180@property(nonatomic, readonly)
181 std::unordered_map<std::string, FlutterPlatformViewGestureRecognizersBlockingPolicy>&
182 gestureRecognizersBlockingPoliciesByType;
185@property(nonatomic, assign) DlISize frameSize;
191@property(nonatomic, readonly) std::unordered_map<int64_t, PlatformViewData>& platformViews;
196@property(nonatomic, readonly)
197 std::unordered_map<int64_t, flutter::EmbeddedViewParams>& currentCompositionParams;
203@property(nonatomic, readonly) std::unordered_set<int64_t>& viewsToDispose;
208@property(nonatomic, readonly) std::vector<int64_t>& compositionOrder;
213@property(nonatomic, readonly) std::vector<int64_t>& visitedPlatformViews;
218@property(nonatomic, readonly) std::unordered_set<int64_t>& viewsToRecomposite;
227@property(nonatomic, assign)
BOOL hadPlatformViews;
232@property(nonatomic, assign)
BOOL canApplyBlurBackdrop;
237- (void)createMissingOverlays:(
size_t)requiredOverlayLayers
238 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext;
241- (void)performSubmit:(const
LayersMap&)platformViewLayers
242 currentCompositionParams:
243 (
std::unordered_map<int64_t,
flutter::EmbeddedViewParams>&)currentCompositionParams
244 viewsToRecomposite:(const
std::unordered_set<int64_t>&)viewsToRecomposite
245 compositionOrder:(const
std::vector<int64_t>&)compositionOrder
247 (const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
249 (const
std::vector<
std::unique_ptr<
flutter::SurfaceFrame>>&)surfaceFrames;
256- (void)clipViewSetMaskView:(UIView*)clipView;
270- (void)applyMutators:(const
flutter::MutatorsStack&)mutatorsStack
271 embeddedView:(UIView*)embeddedView
272 boundingRect:(const DlRect&)boundingRect;
276- (void)bringLayersIntoView:(const
LayersMap&)layerMap
277 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder;
279- (
std::shared_ptr<flutter::OverlayLayer>)nextLayerInPool;
282- (void)createLayerWithIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext
283 pixelFormat:(MTLPixelFormat)pixelFormat;
287- (void)removeUnusedLayers:(const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
288 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder;
294- (
std::vector<UIView*>)computeViewsToDispose;
297- (void)resetFrameState;
308 std::unique_ptr<flutter::OverlayLayerPool> _layerPool;
309 std::unordered_map<int64_t, std::unique_ptr<flutter::EmbedderViewSlice>>
_slices;
310 std::unordered_map<std::string, NSObject<FlutterPlatformViewFactory>*>
_factories;
311 std::unordered_map<std::string, FlutterPlatformViewGestureRecognizersBlockingPolicy>
324 if (
self = [super init]) {
325 _layerPool = std::make_unique<flutter::OverlayLayerPool>();
328 _hadPlatformViews = NO;
329 _canApplyBlurBackdrop = YES;
343 if ([[call method] isEqualToString:
@"create"]) {
344 [
self onCreate:call result:result];
345 }
else if ([[call method] isEqualToString:
@"dispose"]) {
346 [
self onDispose:call result:result];
347 }
else if ([[call method] isEqualToString:
@"acceptGesture"]) {
348 [
self onAcceptGesture:call result:result];
349 }
else if ([[call method] isEqualToString:
@"rejectGesture"]) {
350 [
self onRejectGesture:call result:result];
359 int64_t viewId = [args[@"id"] longLongValue];
360 NSString* viewTypeString =
args[@"viewType"];
361 std::string viewType(viewTypeString.UTF8String);
363 if (
self.platformViews.count(viewId) != 0) {
365 message:
@"trying to create an already created view"
366 details:[NSString stringWithFormat:
@"view id: '%lld'", viewId]]);
370 NSObject<FlutterPlatformViewFactory>* factory =
self.factories[viewType];
371 if (factory == nil) {
373 errorWithCode:
@"unregistered_view_type"
374 message:[NSString stringWithFormat:
@"A UIKitView widget is trying to create a "
375 @"PlatformView with an unregistered type: < %@ >",
377 details:
@"If you are the author of the PlatformView, make sure `registerViewFactory` "
380 @"https://docs.flutter.dev/development/platform-integration/"
381 @"platform-views#on-the-platform-side-1 for more details.\n"
382 @"If you are not the author of the PlatformView, make sure to call "
383 @"`GeneratedPluginRegistrant.register`."]);
388 if ([factory respondsToSelector:@selector(createArgsCodec)]) {
389 NSObject<FlutterMessageCodec>* codec = [factory createArgsCodec];
390 if (codec != nil &&
args[
@"params"] != nil) {
392 params = [codec decode:paramsData.data];
396 NSObject<FlutterPlatformView>* embeddedView = [factory createWithFrame:CGRectZero
397 viewIdentifier:viewId
399 UIView* platformView = [embeddedView view];
401 platformView.accessibilityIdentifier = [NSString stringWithFormat:@"platform_view[%lld]", viewId];
403 NSString* gestureBlockingPolicyValue =
args[@"gestureBlockingPolicy"];
409 }
else if ([gestureBlockingPolicyValue
411 gestureBlockingPolicy =
413 }
else if ([gestureBlockingPolicyValue
415 gestureBlockingPolicy =
self.gestureRecognizersBlockingPoliciesByType[viewType];
418 errorWithCode:
@"unknown_gesture_blocking_policy"
419 message:
@"Trying to create a platform view with an unknown gesture blocking policy"
420 details:[NSString stringWithFormat:
@"view id: '%lld'", viewId]]);
426 platformViewsController:self
427 gestureRecognizersBlockingPolicy:gestureBlockingPolicy];
430 [clippingView addSubview:touchInterceptor];
433 .
view = embeddedView,
434 .touch_interceptor = touchInterceptor,
435 .root_view = clippingView
443 int64_t viewId = [arg longLongValue];
445 if (
self.platformViews.count(viewId) == 0) {
447 message:
@"trying to dispose an unknown"
448 details:[NSString stringWithFormat:
@"view id: '%lld'", viewId]]);
452 self.viewsToDispose.insert(viewId);
458 int64_t viewId = [args[@"id"] longLongValue];
460 if (
self.platformViews.count(viewId) == 0) {
462 message:
@"trying to set gesture state for an unknown view"
463 details:[NSString stringWithFormat:
@"view id: '%lld'", viewId]]);
475 int64_t viewId = [args[@"id"] longLongValue];
477 if (
self.platformViews.count(viewId) == 0) {
479 message:
@"trying to set gesture state for an unknown view"
480 details:[NSString stringWithFormat:
@"view id: '%lld'", viewId]]);
491 withId:(NSString*)factoryId
492 gestureRecognizersBlockingPolicy:
494 std::string idString([factoryId UTF8String]);
496 self.factories[idString] = factory;
497 self.gestureRecognizersBlockingPoliciesByType[idString] = gestureRecognizerBlockingPolicy;
500- (void)beginFrameWithSize:(
DlISize)frameSize {
501 [
self resetFrameState];
502 self.frameSize = frameSize;
506 [
self resetFrameState];
509- (
flutter::PostPrerollResult)postPrerollActionWithThreadMerger:
510 (const
fml::RefPtr<
fml::RasterThreadMerger>&)rasterThreadMerger {
514- (void)endFrameWithResubmit:(
BOOL)shouldResubmitFrame
515 threadMerger:(const
fml::RefPtr<
fml::RasterThreadMerger>&)rasterThreadMerger {
518- (void)pushFilterToVisitedPlatformViews:(const
std::shared_ptr<
flutter::DlImageFilter>&)filter
520 for (int64_t
id :
self.visitedPlatformViews) {
527- (void)prerollCompositeEmbeddedView:(int64_t)viewId
528 withParams:(
std::unique_ptr<
flutter::EmbeddedViewParams>)params {
529 DlRect viewBounds = DlRect::MakeSize(
self.frameSize);
530 std::unique_ptr<flutter::EmbedderViewSlice>
view;
531 view = std::make_unique<flutter::DisplayListEmbedderViewSlice>(viewBounds);
532 self.slices.insert_or_assign(viewId, std::move(view));
534 self.compositionOrder.push_back(viewId);
536 if (
self.currentCompositionParams.count(viewId) == 1 &&
537 self.currentCompositionParams[viewId] == *
params.get()) {
542 self.viewsToRecomposite.insert(viewId);
545- (size_t)embeddedViewCount {
546 return self.compositionOrder.size();
549- (UIView*)platformViewForId:(int64_t)viewId {
550 return [
self flutterTouchInterceptingViewForId:viewId].embeddedView;
554 if (
self.platformViews.empty()) {
557 return self.platformViews[viewId].touch_interceptor;
560- (long)firstResponderPlatformViewId {
561 for (
auto const& [
id, platformViewData] :
self.platformViews) {
562 UIView* rootView = platformViewData.root_view;
563 if (rootView.flt_hasFirstResponderInViewHierarchySubtree) {
570- (void)clipViewSetMaskView:(UIView*)clipView {
571 FML_DCHECK([[NSThread currentThread] isMainThread]);
572 if (clipView.maskView) {
576 CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y,
577 CGRectGetWidth(
self.flutterView.bounds), CGRectGetHeight(
self.flutterView.bounds));
578 clipView.maskView = [
self.maskViewPool getMaskViewWithFrame:frame];
581- (void)applyMutators:(const
flutter::MutatorsStack&)mutatorsStack
582 embeddedView:(UIView*)embeddedView
583 boundingRect:(const
DlRect&)boundingRect {
584 if (
self.flutterView == nil) {
592 NSMutableArray* blurFilters = [[NSMutableArray alloc] init];
593 NSMutableArray<PendingRRectClip*>* pendingClipRRects = [[NSMutableArray alloc] init];
597 if (clipView.maskView) {
598 [
self.maskViewPool insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)];
599 clipView.maskView = nil;
601 CGFloat screenScale = [UIScreen mainScreen].scale;
602 auto iter = mutatorsStack.Begin();
603 while (iter != mutatorsStack.End()) {
604 switch ((*iter)->GetType()) {
606 transformMatrix = transformMatrix * (*iter)->GetMatrix();
611 (*iter)->GetRect(), transformMatrix, boundingRect)) {
614 [
self clipViewSetMaskView:clipView];
616 matrix:transformMatrix];
621 (*iter)->GetRRect(), transformMatrix, boundingRect)) {
624 [
self clipViewSetMaskView:clipView];
626 matrix:transformMatrix];
631 (*iter)->GetRSE(), transformMatrix, boundingRect)) {
634 [
self clipViewSetMaskView:clipView];
636 matrix:transformMatrix];
643 [
self clipViewSetMaskView:clipView];
645 matrix:transformMatrix];
649 embeddedView.alpha = (*iter)->GetAlphaFloat() * embeddedView.alpha;
653 if (!
self.canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
658 filterRect = CGRectApplyAffineTransform(
659 filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale));
663 if (CGRectIsNull(CGRectIntersection(filterRect, clipView.frame))) {
666 CGRect intersection = CGRectIntersection(filterRect, clipView.frame);
667 CGRect frameInClipView = [
self.flutterView convertRect:intersection toView:clipView];
672 CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x();
673 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
674 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
677 CGFloat cornerRadius = 0.0;
678 BOOL isRoundedSuperellipse = NO;
681 if ([pendingClipRRects count] > 0) {
682 cornerRadius = pendingClipRRects.lastObject.topLeftRadius;
683 isRoundedSuperellipse = pendingClipRRects.lastObject.isRoundedSuperellipse;
684 [pendingClipRRects removeAllObjects];
686 visualEffectView.layer.cornerRadius = cornerRadius;
687 visualEffectView.layer.cornerCurve =
688 isRoundedSuperellipse ? kCACornerCurveContinuous : kCACornerCurveCircular;
689 visualEffectView.clipsToBounds = YES;
692 blurRadius:blurRadius
693 cornerRadius:cornerRadius
694 isRoundedSuperellipse:isRoundedSuperellipse
695 visualEffectView:visualEffectView];
697 self.canApplyBlurBackdrop = NO;
699 [blurFilters addObject:filter];
710 DlRoundRect rrect = (*iter)->GetBackdropClipRRect().rrect;
712 clip.
rect = boundingRect;
718 [pendingClipRRects addObject:clip];
725 clip.
rect = boundingRect;
732 [pendingClipRRects addObject:clip];
743 if (
self.canApplyBlurBackdrop) {
744 [clipView applyBlurBackdropFilters:blurFilters];
753 transformMatrix = DlMatrix::MakeScale({pointScale, pointScale, 1}) * transformMatrix;
763 transformMatrix = DlMatrix::MakeTranslation(-origin) * transformMatrix;
768- (void)compositeView:(int64_t)viewId withParams:(const
flutter::EmbeddedViewParams&)params {
770 CGRect frame = CGRectMake(0, 0,
params.sizePoints().width,
params.sizePoints().height);
772 touchInterceptor.layer.transform = CATransform3DIdentity;
773 touchInterceptor.frame = frame;
774 touchInterceptor.alpha = 1;
777 UIView* clippingView =
self.platformViews[viewId].root_view;
783 CGFloat screenScale = [UIScreen mainScreen].scale;
784 clippingView.frame = CGRectMake(rect.GetX() / screenScale, rect.GetY() / screenScale,
785 rect.GetWidth() / screenScale, rect.GetHeight() / screenScale);
786 [
self applyMutators:mutatorStack embeddedView:touchInterceptor boundingRect:rect];
789- (
flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId {
791 return self.slices[viewId]->canvas();
798 std::vector<int64_t> compositionOrder =
self.compositionOrder;
799 [
self.taskRunner runNowOrPostTask:^{
800 for (int64_t viewId : compositionOrder) {
801 [
self.platformViews[viewId].root_view removeFromSuperview];
803 self.platformViews.clear();
804 _previousCompositionOrder.clear();
807 self.compositionOrder.clear();
809 self.currentCompositionParams.clear();
810 self.viewsToRecomposite.clear();
811 self.layerPool->RecycleLayers();
812 self.visitedPlatformViews.clear();
815- (
BOOL)submitFrame:(
std::unique_ptr<
flutter::SurfaceFrame>)background_frame
816 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
817 TRACE_EVENT0(
"flutter",
"PlatformViewsController::SubmitFrame");
820 if (
self.flutterView == nil || (
self.compositionOrder.empty() && !
self.hadPlatformViews)) {
823 if (
self.flutterView != nil) {
827 [
self.taskRunner runNowOrPostTask:^{
832 [strongSelf performResize:frameSize];
836 self.hadPlatformViews = NO;
837 return background_frame->Submit();
839 self.hadPlatformViews = !
self.compositionOrder.empty();
841 bool didEncode =
true;
843 std::vector<std::unique_ptr<flutter::SurfaceFrame>> surfaceFrames;
844 surfaceFrames.reserve(
self.compositionOrder.size());
845 std::unordered_map<int64_t, DlRect> viewRects;
846 std::unordered_set<int64_t> viewsWithUnderlayPreserved;
848 for (int64_t viewId :
self.compositionOrder) {
852 viewsWithUnderlayPreserved.insert(viewId);
856 std::unordered_map<int64_t, DlRect> overlayLayers =
858 viewsWithUnderlayPreserved);
860 size_t requiredOverlayLayers = 0;
861 for (int64_t viewId :
self.compositionOrder) {
862 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
863 if (overlay == overlayLayers.end()) {
866 requiredOverlayLayers++;
872 [
self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
874 int64_t overlayId = 0;
875 for (int64_t viewId :
self.compositionOrder) {
876 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
877 if (overlay == overlayLayers.end()) {
880 std::shared_ptr<flutter::OverlayLayer> layer =
self.nextLayerInPool;
885 std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(
self.frameSize);
892 overlayCanvas->
Save();
893 overlayCanvas->
ClipRect(overlay->second);
894 if (viewsWithUnderlayPreserved.find(viewId) != viewsWithUnderlayPreserved.end()) {
898 self.slices[viewId]->render_into(overlayCanvas);
903 frame->set_submit_info({.frame_boundary =
false, .present_with_transaction =
true});
904 layer->did_submit_last_frame = frame->Encode();
906 didEncode &= layer->did_submit_last_frame;
908 .
rect = overlay->second,
910 .overlay_id = overlayId,
913 surfaceFrames.push_back(std::move(frame));
917 auto previousSubmitInfo = background_frame->submit_info();
918 background_frame->set_submit_info({
919 .frame_damage = previousSubmitInfo.frame_damage,
920 .buffer_damage = previousSubmitInfo.buffer_damage,
921 .present_with_transaction =
true,
923 background_frame->Encode();
924 surfaceFrames.push_back(std::move(background_frame));
927 std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
928 self.layerPool->RemoveUnusedLayers();
929 self.layerPool->RecycleLayers();
931 platformViewLayers = std::move(platformViewLayers),
932 currentCompositionParams =
self.currentCompositionParams,
933 viewsToRecomposite =
self.viewsToRecomposite,
934 compositionOrder =
self.compositionOrder,
935 unusedLayers = std::move(unusedLayers),
936 surfaceFrames = std::move(surfaceFrames)]()
mutable {
937 [self performSubmit:platformViewLayers
938 currentCompositionParams:currentCompositionParams
939 viewsToRecomposite:viewsToRecomposite
940 compositionOrder:compositionOrder
941 unusedLayers:unusedLayers
942 surfaceFrames:surfaceFrames];
945 [
self.taskRunner runNowOrPostTask:^{
951- (void)createMissingOverlays:(
size_t)requiredOverlayLayers
952 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
953 TRACE_EVENT0(
"flutter",
"PlatformViewsController::CreateMissingLayers");
955 if (requiredOverlayLayers <= self.layerPool->
size()) {
958 auto missingLayerCount = requiredOverlayLayers -
self.layerPool->
size();
963 auto latch = std::make_shared<fml::CountDownLatch>(1u);
964 [
self.taskRunner runNowOrPostTask:^{
965 for (auto i = 0u; i < missingLayerCount; i++) {
966 [
self createLayerWithIosContext:iosContext
967 pixelFormat:((FlutterView*)self.flutterView).pixelFormat];
971 if (![[NSThread currentThread] isMainThread]) {
977 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformResize");
978 FML_DCHECK([[NSThread currentThread] isMainThread]);
980 if (
self.flutterView != nil) {
982 setIntrinsicContentSize:CGSizeMake(frameSize.width, frameSize.height)];
986- (void)performSubmit:(const
LayersMap&)platformViewLayers
987 currentCompositionParams:
988 (
std::unordered_map<int64_t,
flutter::EmbeddedViewParams>&)currentCompositionParams
989 viewsToRecomposite:(const
std::unordered_set<int64_t>&)viewsToRecomposite
990 compositionOrder:(const
std::vector<int64_t>&)compositionOrder
992 (const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
994 (const
std::vector<
std::unique_ptr<
flutter::SurfaceFrame>>&)surfaceFrames {
995 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformSubmit");
996 FML_DCHECK([[NSThread currentThread] isMainThread]);
998 [CATransaction begin];
1001 for (
const auto& [viewId, layerData] : platformViewLayers) {
1002 layerData.layer->UpdateViewState(
self.flutterView,
1005 layerData.overlay_id
1010 for (
auto& view : [
self computeViewsToDispose]) {
1011 [view removeFromSuperview];
1015 for (int64_t viewId : viewsToRecomposite) {
1016 [
self compositeView:viewId withParams:currentCompositionParams[viewId]];
1020 for (
const auto& frame : surfaceFrames) {
1026 [
self removeUnusedLayers:unusedLayers withCompositionOrder:compositionOrder];
1029 [
self bringLayersIntoView:platformViewLayers withCompositionOrder:compositionOrder];
1031 [CATransaction commit];
1034- (void)bringLayersIntoView:(const
LayersMap&)layerMap
1035 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1037 UIView* flutterView =
self.flutterView;
1040 NSMutableArray* desiredPlatformSubviews = [NSMutableArray array];
1041 for (int64_t platformViewId : compositionOrder) {
1043 UIView* platformViewRoot =
self.platformViews[platformViewId].root_view;
1044 if (platformViewRoot != nil) {
1045 [desiredPlatformSubviews addObject:platformViewRoot];
1048 auto maybeLayerData = layerMap.find(platformViewId);
1049 if (maybeLayerData != layerMap.end()) {
1050 auto view = maybeLayerData->second.layer->overlay_view_wrapper;
1052 [desiredPlatformSubviews addObject:view];
1057 NSSet* desiredPlatformSubviewsSet = [NSSet setWithArray:desiredPlatformSubviews];
1058 NSArray* existingPlatformSubviews = [flutterView.subviews
1059 filteredArrayUsingPredicate:[NSPredicate
1060 predicateWithBlock:^BOOL(id object, NSDictionary* bindings) {
1061 return [desiredPlatformSubviewsSet containsObject:object];
1068 if (![desiredPlatformSubviews isEqualToArray:existingPlatformSubviews]) {
1069 for (UIView* subview in desiredPlatformSubviews) {
1071 [flutterView addSubview:subview];
1076- (
std::shared_ptr<flutter::OverlayLayer>)nextLayerInPool {
1077 return self.layerPool->GetNextLayer();
1080- (void)createLayerWithIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext
1081 pixelFormat:(MTLPixelFormat)pixelFormat {
1082 self.layerPool->CreateLayer(iosContext, pixelFormat);
1085- (void)removeUnusedLayers:(const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
1086 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1087 for (
const std::shared_ptr<flutter::OverlayLayer>& layer : unusedLayers) {
1088 [layer->overlay_view_wrapper removeFromSuperview];
1091 std::unordered_set<int64_t> compositionOrderSet;
1092 for (int64_t viewId : compositionOrder) {
1093 compositionOrderSet.insert(viewId);
1097 if (compositionOrderSet.find(viewId) == compositionOrderSet.end()) {
1098 UIView* platformViewRoot =
self.platformViews[viewId].root_view;
1099 [platformViewRoot removeFromSuperview];
1104- (
std::vector<UIView*>)computeViewsToDispose {
1105 std::vector<UIView*> views;
1106 if (
self.viewsToDispose.empty()) {
1110 std::unordered_set<int64_t> viewsToComposite(
self.compositionOrder.begin(),
1111 self.compositionOrder.end());
1112 std::unordered_set<int64_t> viewsToDelayDispose;
1113 for (int64_t viewId :
self.viewsToDispose) {
1114 if (viewsToComposite.count(viewId)) {
1115 viewsToDelayDispose.insert(viewId);
1118 UIView* rootView =
self.platformViews[viewId].root_view;
1119 views.push_back(rootView);
1120 self.currentCompositionParams.erase(viewId);
1121 self.viewsToRecomposite.erase(viewId);
1122 self.platformViews.erase(viewId);
1124 self.viewsToDispose = std::move(viewsToDelayDispose);
1128- (void)resetFrameState {
1129 self.slices.clear();
1130 self.compositionOrder.clear();
1131 self.visitedPlatformViews.clear();
1134- (void)pushVisitedPlatformViewId:(int64_t)viewId {
1135 self.visitedPlatformViews.push_back(viewId);
1138- (void)pushClipRectToVisitedPlatformViews:(const
flutter::
DlRect&)clipRect {
1139 for (int64_t
id :
self.visitedPlatformViews) {
1147 for (int64_t
id :
self.visitedPlatformViews) {
1155 for (int64_t
id :
self.visitedPlatformViews) {
1162- (void)pushClipPathToVisitedPlatformViews:(const
flutter::
DlPath&)clipPath {
1163 for (int64_t
id :
self.visitedPlatformViews) {
1170- (const
flutter::EmbeddedViewParams&)compositionParamsForView:(int64_t)viewId {
1171 return self.currentCompositionParams.find(viewId)->second;
1174#pragma mark - Properties
1176- (
flutter::OverlayLayerPool*)layerPool {
1177 return _layerPool.get();
1180- (
std::unordered_map<int64_t, std::unique_ptr<flutter::EmbedderViewSlice>>&)slices {
1184- (
std::unordered_map<std::string, NSObject<FlutterPlatformViewFactory>*>&)factories {
1188- (
std::unordered_map<std::string, FlutterPlatformViewGestureRecognizersBlockingPolicy>&)
1189 gestureRecognizersBlockingPoliciesByType {
1193- (
std::unordered_map<int64_t, PlatformViewData>&)platformViews {
1197- (
std::unordered_map<int64_t, flutter::EmbeddedViewParams>&)currentCompositionParams {
1201- (
std::unordered_set<int64_t>&)viewsToDispose {
1205- (
std::vector<int64_t>&)compositionOrder {
1209- (
std::vector<int64_t>&)visitedPlatformViews {
1213- (
std::unordered_set<int64_t>&)viewsToRecomposite {
1217- (NSArray<NSNumber*>*)previousCompositionOrder {
1219 NSMutableArray* array = [NSMutableArray arrayWithCapacity:_previousCompositionOrder.size()];
1221 [array addObject:@(viewId)];
void(^ FlutterResult)(id _Nullable result)
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
FlutterPlatformViewGestureRecognizersBlockingPolicy
@ FlutterPlatformViewGestureRecognizersBlockingPolicyEager
@ FlutterPlatformViewGestureRecognizersBlockingPolicyWaitUntilTouchesEnded
@ FlutterPlatformViewGestureRecognizersBlockingPolicyDoNotBlockGesture
CGFloat bottomRightRadius
BOOL isRoundedSuperellipse
static bool TransformedRectCoversBounds(const DlRect &local_rect, const DlMatrix &matrix, const DlRect &cull_bounds)
Checks if the local rect, when transformed by the matrix, completely covers the indicated culling bou...
static bool TransformedRoundSuperellipseCoversBounds(const DlRoundSuperellipse &local_rse, const DlMatrix &matrix, const DlRect &cull_bounds)
Checks if the local round superellipse, when transformed by the matrix, completely covers the indicat...
static bool TransformedRRectCoversBounds(const DlRoundRect &local_rrect, const DlMatrix &matrix, const DlRect &cull_bounds)
Checks if the local round rect, when transformed by the matrix, completely covers the indicated culli...
Developer-facing API for rendering anything within the engine.
virtual void ClipRoundSuperellipse(const DlRoundSuperellipse &rse, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual int GetSaveCount() const =0
virtual void RestoreToCount(int restore_count)=0
virtual void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
void Clear(DlColor color)
static DlPath MakeRoundRect(const DlRoundRect &rrect)
static DlPath MakeRoundSuperellipse(const DlRoundSuperellipse &rse)
void PushImageFilter(const std::shared_ptr< DlImageFilter > &filter, const DlRect &filter_rect)
void PushPlatformViewClipRRect(const DlRoundRect &clip_rrect)
void PushPlatformViewClipPath(const DlPath &clip_path)
void PushPlatformViewClipRSuperellipse(const DlRoundSuperellipse &clip_rse)
void PushPlatformViewClipRect(const DlRect &clip_rect)
const DlRect & finalBoundingRect() const
Storage for Overlay layers across frames.
const EmbeddedViewParams * params
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
HWND(* FlutterPlatformViewFactory)(const FlutterPlatformViewCreationParameters *)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
impeller::Scalar DlScalar
impeller::RoundRect DlRoundRect
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
std::unordered_map< int64_t, DlRect > SliceViews(DlCanvas *background_canvas, const std::vector< int64_t > &composition_order, const std::unordered_map< int64_t, std::unique_ptr< EmbedderViewSlice > > &slices, const std::unordered_map< int64_t, DlRect > &view_rects, const std::unordered_set< int64_t > &views_with_underlay_preserved)
Compute the required overlay layers and clip the view slices according to the size and position of th...
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
impeller::RoundSuperellipse DlRoundSuperellipse
@ kBackdropClipRSuperellipse
SkMatrix ToSkMatrix(const DlMatrix &matrix)
internal::CopyableLambda< T > MakeCopyable(T lambda)
std::shared_ptr< flutter::OverlayLayer > layer
static constexpr DlColor kTransparent()
A 4x4 matrix using column-major storage.
constexpr bool IsIdentity() const
constexpr const RoundingRadii & GetRadii() const
#define TRACE_EVENT0(category_group, name)