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- (void)pushFilterToVisitedPlatformViews:(const
std::shared_ptr<
flutter::DlImageFilter>&)filter
511 for (int64_t
id :
self.visitedPlatformViews) {
518- (void)prerollCompositeEmbeddedView:(int64_t)viewId
519 withParams:(
std::unique_ptr<
flutter::EmbeddedViewParams>)params {
520 DlRect viewBounds = DlRect::MakeSize(
self.frameSize);
521 std::unique_ptr<flutter::EmbedderViewSlice>
view;
522 view = std::make_unique<flutter::DisplayListEmbedderViewSlice>(viewBounds);
523 self.slices.insert_or_assign(viewId, std::move(view));
525 self.compositionOrder.push_back(viewId);
527 if (
self.currentCompositionParams.count(viewId) == 1 &&
528 self.currentCompositionParams[viewId] == *
params.get()) {
533 self.viewsToRecomposite.insert(viewId);
536- (size_t)embeddedViewCount {
537 return self.compositionOrder.size();
540- (UIView*)platformViewForId:(int64_t)viewId {
541 return [
self flutterTouchInterceptingViewForId:viewId].embeddedView;
545 if (
self.platformViews.empty()) {
548 return self.platformViews[viewId].touch_interceptor;
551- (long)firstResponderPlatformViewId {
552 for (
auto const& [
id, platformViewData] :
self.platformViews) {
553 UIView* rootView = platformViewData.root_view;
554 if (rootView.flt_hasFirstResponderInViewHierarchySubtree) {
561- (void)clipViewSetMaskView:(UIView*)clipView {
562 FML_DCHECK([[NSThread currentThread] isMainThread]);
563 if (clipView.maskView) {
567 CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y,
568 CGRectGetWidth(
self.flutterView.bounds), CGRectGetHeight(
self.flutterView.bounds));
569 clipView.maskView = [
self.maskViewPool getMaskViewWithFrame:frame];
572- (void)applyMutators:(const
flutter::MutatorsStack&)mutatorsStack
573 embeddedView:(UIView*)embeddedView
574 boundingRect:(const
DlRect&)boundingRect {
575 if (
self.flutterView == nil) {
583 NSMutableArray* blurFilters = [[NSMutableArray alloc] init];
584 NSMutableArray<PendingRRectClip*>* pendingClipRRects = [[NSMutableArray alloc] init];
588 if (clipView.maskView) {
589 [
self.maskViewPool insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)];
590 clipView.maskView = nil;
592 CGFloat screenScale = [UIScreen mainScreen].scale;
593 auto iter = mutatorsStack.Begin();
594 while (iter != mutatorsStack.End()) {
595 switch ((*iter)->GetType()) {
597 transformMatrix = transformMatrix * (*iter)->GetMatrix();
602 (*iter)->GetRect(), transformMatrix, boundingRect)) {
605 [
self clipViewSetMaskView:clipView];
607 matrix:transformMatrix];
612 (*iter)->GetRRect(), transformMatrix, boundingRect)) {
615 [
self clipViewSetMaskView:clipView];
617 matrix:transformMatrix];
622 (*iter)->GetRSE(), transformMatrix, boundingRect)) {
625 [
self clipViewSetMaskView:clipView];
627 matrix:transformMatrix];
634 [
self clipViewSetMaskView:clipView];
636 matrix:transformMatrix];
640 embeddedView.alpha = (*iter)->GetAlphaFloat() * embeddedView.alpha;
644 if (!
self.canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
649 filterRect = CGRectApplyAffineTransform(
650 filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale));
654 if (CGRectIsNull(CGRectIntersection(filterRect, clipView.frame))) {
657 CGRect intersection = CGRectIntersection(filterRect, clipView.frame);
658 CGRect frameInClipView = [
self.flutterView convertRect:intersection toView:clipView];
663 CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x();
664 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
665 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
668 CGFloat cornerRadius = 0.0;
669 BOOL isRoundedSuperellipse = NO;
672 if ([pendingClipRRects count] > 0) {
673 cornerRadius = pendingClipRRects.lastObject.topLeftRadius;
674 isRoundedSuperellipse = pendingClipRRects.lastObject.isRoundedSuperellipse;
675 [pendingClipRRects removeAllObjects];
677 visualEffectView.layer.cornerRadius = cornerRadius;
678 visualEffectView.layer.cornerCurve =
679 isRoundedSuperellipse ? kCACornerCurveContinuous : kCACornerCurveCircular;
680 visualEffectView.clipsToBounds = YES;
683 blurRadius:blurRadius
684 cornerRadius:cornerRadius
685 isRoundedSuperellipse:isRoundedSuperellipse
686 visualEffectView:visualEffectView];
688 self.canApplyBlurBackdrop = NO;
690 [blurFilters addObject:filter];
701 DlRoundRect rrect = (*iter)->GetBackdropClipRRect().rrect;
703 clip.
rect = boundingRect;
709 [pendingClipRRects addObject:clip];
716 clip.
rect = boundingRect;
723 [pendingClipRRects addObject:clip];
734 if (
self.canApplyBlurBackdrop) {
735 [clipView applyBlurBackdropFilters:blurFilters];
744 transformMatrix = DlMatrix::MakeScale({pointScale, pointScale, 1}) * transformMatrix;
754 transformMatrix = DlMatrix::MakeTranslation(-origin) * transformMatrix;
759- (void)compositeView:(int64_t)viewId withParams:(const
flutter::EmbeddedViewParams&)params {
761 CGRect frame = CGRectMake(0, 0,
params.sizePoints().width,
params.sizePoints().height);
763 touchInterceptor.layer.transform = CATransform3DIdentity;
764 touchInterceptor.frame = frame;
765 touchInterceptor.alpha = 1;
768 UIView* clippingView =
self.platformViews[viewId].root_view;
774 CGFloat screenScale = [UIScreen mainScreen].scale;
775 clippingView.frame = CGRectMake(rect.GetX() / screenScale, rect.GetY() / screenScale,
776 rect.GetWidth() / screenScale, rect.GetHeight() / screenScale);
777 [
self applyMutators:mutatorStack embeddedView:touchInterceptor boundingRect:rect];
780- (
flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId {
782 return self.slices[viewId]->canvas();
789 std::vector<int64_t> compositionOrder =
self.compositionOrder;
790 [
self.taskRunner runNowOrPostTask:^{
791 for (int64_t viewId : compositionOrder) {
792 [
self.platformViews[viewId].root_view removeFromSuperview];
794 self.platformViews.clear();
795 _previousCompositionOrder.clear();
798 self.compositionOrder.clear();
800 self.currentCompositionParams.clear();
801 self.viewsToRecomposite.clear();
802 self.layerPool->RecycleLayers();
803 self.visitedPlatformViews.clear();
806- (
BOOL)submitFrame:(
std::unique_ptr<
flutter::SurfaceFrame>)background_frame
807 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
808 TRACE_EVENT0(
"flutter",
"PlatformViewsController::SubmitFrame");
811 if (
self.flutterView == nil || (
self.compositionOrder.empty() && !
self.hadPlatformViews)) {
814 if (
self.flutterView != nil) {
818 [
self.taskRunner runNowOrPostTask:^{
823 [strongSelf performResize:frameSize];
827 self.hadPlatformViews = NO;
828 return background_frame->Submit();
830 self.hadPlatformViews = !
self.compositionOrder.empty();
832 bool didEncode =
true;
834 std::vector<std::unique_ptr<flutter::SurfaceFrame>> surfaceFrames;
835 surfaceFrames.reserve(
self.compositionOrder.size());
836 std::unordered_map<int64_t, DlRect> viewRects;
837 std::unordered_set<int64_t> viewsWithUnderlayPreserved;
839 for (int64_t viewId :
self.compositionOrder) {
843 viewsWithUnderlayPreserved.insert(viewId);
847 std::unordered_map<int64_t, DlRect> overlayLayers =
849 viewsWithUnderlayPreserved);
851 size_t requiredOverlayLayers = 0;
852 for (int64_t viewId :
self.compositionOrder) {
853 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
854 if (overlay == overlayLayers.end()) {
857 requiredOverlayLayers++;
863 [
self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
865 int64_t overlayId = 0;
866 for (int64_t viewId :
self.compositionOrder) {
867 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
868 if (overlay == overlayLayers.end()) {
871 std::shared_ptr<flutter::OverlayLayer> layer =
self.nextLayerInPool;
876 std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(
self.frameSize);
883 overlayCanvas->
Save();
884 overlayCanvas->
ClipRect(overlay->second);
885 if (viewsWithUnderlayPreserved.find(viewId) != viewsWithUnderlayPreserved.end()) {
889 self.slices[viewId]->render_into(overlayCanvas);
894 frame->set_submit_info({.frame_boundary =
false, .present_with_transaction =
true});
895 layer->did_submit_last_frame = frame->Encode();
897 didEncode &= layer->did_submit_last_frame;
899 .
rect = overlay->second,
901 .overlay_id = overlayId,
904 surfaceFrames.push_back(std::move(frame));
908 auto previousSubmitInfo = background_frame->submit_info();
909 background_frame->set_submit_info({
910 .frame_damage = previousSubmitInfo.frame_damage,
911 .buffer_damage = previousSubmitInfo.buffer_damage,
912 .present_with_transaction =
true,
914 background_frame->Encode();
915 surfaceFrames.push_back(std::move(background_frame));
918 std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
919 self.layerPool->RemoveUnusedLayers();
920 self.layerPool->RecycleLayers();
922 platformViewLayers = std::move(platformViewLayers),
923 currentCompositionParams =
self.currentCompositionParams,
924 viewsToRecomposite =
self.viewsToRecomposite,
925 compositionOrder =
self.compositionOrder,
926 unusedLayers = std::move(unusedLayers),
927 surfaceFrames = std::move(surfaceFrames)]()
mutable {
928 [self performSubmit:platformViewLayers
929 currentCompositionParams:currentCompositionParams
930 viewsToRecomposite:viewsToRecomposite
931 compositionOrder:compositionOrder
932 unusedLayers:unusedLayers
933 surfaceFrames:surfaceFrames];
936 [
self.taskRunner runNowOrPostTask:^{
942- (void)createMissingOverlays:(
size_t)requiredOverlayLayers
943 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
944 TRACE_EVENT0(
"flutter",
"PlatformViewsController::CreateMissingLayers");
946 if (requiredOverlayLayers <= self.layerPool->
size()) {
949 auto missingLayerCount = requiredOverlayLayers -
self.layerPool->
size();
954 auto latch = std::make_shared<fml::CountDownLatch>(1u);
955 [
self.taskRunner runNowOrPostTask:^{
956 for (auto i = 0u; i < missingLayerCount; i++) {
957 [
self createLayerWithIosContext:iosContext
958 pixelFormat:((FlutterView*)self.flutterView).pixelFormat];
962 if (![[NSThread currentThread] isMainThread]) {
968 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformResize");
969 FML_DCHECK([[NSThread currentThread] isMainThread]);
971 if (
self.flutterView != nil) {
973 setIntrinsicContentSize:CGSizeMake(frameSize.width, frameSize.height)];
977- (void)performSubmit:(const
LayersMap&)platformViewLayers
978 currentCompositionParams:
979 (
std::unordered_map<int64_t,
flutter::EmbeddedViewParams>&)currentCompositionParams
980 viewsToRecomposite:(const
std::unordered_set<int64_t>&)viewsToRecomposite
981 compositionOrder:(const
std::vector<int64_t>&)compositionOrder
983 (const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
985 (const
std::vector<
std::unique_ptr<
flutter::SurfaceFrame>>&)surfaceFrames {
986 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformSubmit");
987 FML_DCHECK([[NSThread currentThread] isMainThread]);
989 [CATransaction begin];
992 for (
const auto& [viewId, layerData] : platformViewLayers) {
993 layerData.layer->UpdateViewState(
self.flutterView,
1001 for (
auto& view : [
self computeViewsToDispose]) {
1002 [view removeFromSuperview];
1006 for (int64_t viewId : viewsToRecomposite) {
1007 [
self compositeView:viewId withParams:currentCompositionParams[viewId]];
1011 for (
const auto& frame : surfaceFrames) {
1017 [
self removeUnusedLayers:unusedLayers withCompositionOrder:compositionOrder];
1020 [
self bringLayersIntoView:platformViewLayers withCompositionOrder:compositionOrder];
1022 [CATransaction commit];
1025- (void)bringLayersIntoView:(const
LayersMap&)layerMap
1026 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1028 UIView* flutterView =
self.flutterView;
1031 NSMutableArray* desiredPlatformSubviews = [NSMutableArray array];
1032 for (int64_t platformViewId : compositionOrder) {
1034 UIView* platformViewRoot =
self.platformViews[platformViewId].root_view;
1035 if (platformViewRoot != nil) {
1036 [desiredPlatformSubviews addObject:platformViewRoot];
1039 auto maybeLayerData = layerMap.find(platformViewId);
1040 if (maybeLayerData != layerMap.end()) {
1041 auto view = maybeLayerData->second.layer->overlay_view_wrapper;
1043 [desiredPlatformSubviews addObject:view];
1048 NSSet* desiredPlatformSubviewsSet = [NSSet setWithArray:desiredPlatformSubviews];
1049 NSArray* existingPlatformSubviews = [flutterView.subviews
1050 filteredArrayUsingPredicate:[NSPredicate
1051 predicateWithBlock:^BOOL(id object, NSDictionary* bindings) {
1052 return [desiredPlatformSubviewsSet containsObject:object];
1059 if (![desiredPlatformSubviews isEqualToArray:existingPlatformSubviews]) {
1060 for (UIView* subview in desiredPlatformSubviews) {
1062 [flutterView addSubview:subview];
1067- (
std::shared_ptr<flutter::OverlayLayer>)nextLayerInPool {
1068 return self.layerPool->GetNextLayer();
1071- (void)createLayerWithIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext
1072 pixelFormat:(MTLPixelFormat)pixelFormat {
1073 self.layerPool->CreateLayer(iosContext, pixelFormat);
1076- (void)removeUnusedLayers:(const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
1077 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1078 for (
const std::shared_ptr<flutter::OverlayLayer>& layer : unusedLayers) {
1079 [layer->overlay_view_wrapper removeFromSuperview];
1082 std::unordered_set<int64_t> compositionOrderSet;
1083 for (int64_t viewId : compositionOrder) {
1084 compositionOrderSet.insert(viewId);
1088 if (compositionOrderSet.find(viewId) == compositionOrderSet.end()) {
1089 UIView* platformViewRoot =
self.platformViews[viewId].root_view;
1090 [platformViewRoot removeFromSuperview];
1095- (
std::vector<UIView*>)computeViewsToDispose {
1096 std::vector<UIView*> views;
1097 if (
self.viewsToDispose.empty()) {
1101 std::unordered_set<int64_t> viewsToComposite(
self.compositionOrder.begin(),
1102 self.compositionOrder.end());
1103 std::unordered_set<int64_t> viewsToDelayDispose;
1104 for (int64_t viewId :
self.viewsToDispose) {
1105 if (viewsToComposite.count(viewId)) {
1106 viewsToDelayDispose.insert(viewId);
1109 UIView* rootView =
self.platformViews[viewId].root_view;
1110 views.push_back(rootView);
1111 self.currentCompositionParams.erase(viewId);
1112 self.viewsToRecomposite.erase(viewId);
1113 self.platformViews.erase(viewId);
1115 self.viewsToDispose = std::move(viewsToDelayDispose);
1119- (void)resetFrameState {
1120 self.slices.clear();
1121 self.compositionOrder.clear();
1122 self.visitedPlatformViews.clear();
1125- (void)pushVisitedPlatformViewId:(int64_t)viewId {
1126 self.visitedPlatformViews.push_back(viewId);
1129- (void)pushClipRectToVisitedPlatformViews:(const
flutter::
DlRect&)clipRect {
1130 for (int64_t
id :
self.visitedPlatformViews) {
1138 for (int64_t
id :
self.visitedPlatformViews) {
1146 for (int64_t
id :
self.visitedPlatformViews) {
1153- (void)pushClipPathToVisitedPlatformViews:(const
flutter::
DlPath&)clipPath {
1154 for (int64_t
id :
self.visitedPlatformViews) {
1161- (const
flutter::EmbeddedViewParams&)compositionParamsForView:(int64_t)viewId {
1162 return self.currentCompositionParams.find(viewId)->second;
1165#pragma mark - Properties
1167- (
flutter::OverlayLayerPool*)layerPool {
1168 return _layerPool.get();
1171- (
std::unordered_map<int64_t, std::unique_ptr<flutter::EmbedderViewSlice>>&)slices {
1175- (
std::unordered_map<std::string, NSObject<FlutterPlatformViewFactory>*>&)factories {
1179- (
std::unordered_map<std::string, FlutterPlatformViewGestureRecognizersBlockingPolicy>&)
1180 gestureRecognizersBlockingPoliciesByType {
1184- (
std::unordered_map<int64_t, PlatformViewData>&)platformViews {
1188- (
std::unordered_map<int64_t, flutter::EmbeddedViewParams>&)currentCompositionParams {
1192- (
std::unordered_set<int64_t>&)viewsToDispose {
1196- (
std::vector<int64_t>&)compositionOrder {
1200- (
std::vector<int64_t>&)visitedPlatformViews {
1204- (
std::unordered_set<int64_t>&)viewsToRecomposite {
1208- (NSArray<NSNumber*>*)previousCompositionOrder {
1210 NSMutableArray* array = [NSMutableArray arrayWithCapacity:_previousCompositionOrder.size()];
1212 [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)