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 if (@available(iOS 13.0, *)) {
688 visualEffectView.layer.cornerCurve =
689 isRoundedSuperellipse ? kCACornerCurveContinuous : kCACornerCurveCircular;
691 visualEffectView.clipsToBounds = YES;
694 blurRadius:blurRadius
695 cornerRadius:cornerRadius
696 isRoundedSuperellipse:isRoundedSuperellipse
697 visualEffectView:visualEffectView];
699 self.canApplyBlurBackdrop = NO;
701 [blurFilters addObject:filter];
712 DlRoundRect rrect = (*iter)->GetBackdropClipRRect().rrect;
714 clip.
rect = boundingRect;
720 [pendingClipRRects addObject:clip];
727 clip.
rect = boundingRect;
734 [pendingClipRRects addObject:clip];
745 if (
self.canApplyBlurBackdrop) {
746 [clipView applyBlurBackdropFilters:blurFilters];
755 transformMatrix = DlMatrix::MakeScale({pointScale, pointScale, 1}) * transformMatrix;
765 transformMatrix = DlMatrix::MakeTranslation(-origin) * transformMatrix;
770- (void)compositeView:(int64_t)viewId withParams:(const
flutter::EmbeddedViewParams&)params {
772 CGRect frame = CGRectMake(0, 0,
params.sizePoints().width,
params.sizePoints().height);
774 touchInterceptor.layer.transform = CATransform3DIdentity;
775 touchInterceptor.frame = frame;
776 touchInterceptor.alpha = 1;
779 UIView* clippingView =
self.platformViews[viewId].root_view;
785 CGFloat screenScale = [UIScreen mainScreen].scale;
786 clippingView.frame = CGRectMake(rect.GetX() / screenScale, rect.GetY() / screenScale,
787 rect.GetWidth() / screenScale, rect.GetHeight() / screenScale);
788 [
self applyMutators:mutatorStack embeddedView:touchInterceptor boundingRect:rect];
791- (
flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId {
793 return self.slices[viewId]->canvas();
800 std::vector<int64_t> compositionOrder =
self.compositionOrder;
801 [
self.taskRunner runNowOrPostTask:^{
802 for (int64_t viewId : compositionOrder) {
803 [
self.platformViews[viewId].root_view removeFromSuperview];
805 self.platformViews.clear();
806 _previousCompositionOrder.clear();
809 self.compositionOrder.clear();
811 self.currentCompositionParams.clear();
812 self.viewsToRecomposite.clear();
813 self.layerPool->RecycleLayers();
814 self.visitedPlatformViews.clear();
817- (
BOOL)submitFrame:(
std::unique_ptr<
flutter::SurfaceFrame>)background_frame
818 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
819 TRACE_EVENT0(
"flutter",
"PlatformViewsController::SubmitFrame");
822 if (
self.flutterView == nil || (
self.compositionOrder.empty() && !
self.hadPlatformViews)) {
825 if (
self.flutterView != nil) {
829 [
self.taskRunner runNowOrPostTask:^{
834 [strongSelf performResize:frameSize];
838 self.hadPlatformViews = NO;
839 return background_frame->Submit();
841 self.hadPlatformViews = !
self.compositionOrder.empty();
843 bool didEncode =
true;
845 std::vector<std::unique_ptr<flutter::SurfaceFrame>> surfaceFrames;
846 surfaceFrames.reserve(
self.compositionOrder.size());
847 std::unordered_map<int64_t, DlRect> viewRects;
848 std::unordered_set<int64_t> viewsWithUnderlayPreserved;
850 for (int64_t viewId :
self.compositionOrder) {
854 viewsWithUnderlayPreserved.insert(viewId);
858 std::unordered_map<int64_t, DlRect> overlayLayers =
860 viewsWithUnderlayPreserved);
862 size_t requiredOverlayLayers = 0;
863 for (int64_t viewId :
self.compositionOrder) {
864 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
865 if (overlay == overlayLayers.end()) {
868 requiredOverlayLayers++;
874 [
self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
876 int64_t overlayId = 0;
877 for (int64_t viewId :
self.compositionOrder) {
878 std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
879 if (overlay == overlayLayers.end()) {
882 std::shared_ptr<flutter::OverlayLayer> layer =
self.nextLayerInPool;
887 std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(
self.frameSize);
894 overlayCanvas->
Save();
895 overlayCanvas->
ClipRect(overlay->second);
896 if (viewsWithUnderlayPreserved.find(viewId) != viewsWithUnderlayPreserved.end()) {
900 self.slices[viewId]->render_into(overlayCanvas);
905 frame->set_submit_info({.frame_boundary =
false, .present_with_transaction =
true});
906 layer->did_submit_last_frame = frame->Encode();
908 didEncode &= layer->did_submit_last_frame;
910 .
rect = overlay->second,
912 .overlay_id = overlayId,
915 surfaceFrames.push_back(std::move(frame));
919 auto previousSubmitInfo = background_frame->submit_info();
920 background_frame->set_submit_info({
921 .frame_damage = previousSubmitInfo.frame_damage,
922 .buffer_damage = previousSubmitInfo.buffer_damage,
923 .present_with_transaction =
true,
925 background_frame->Encode();
926 surfaceFrames.push_back(std::move(background_frame));
929 std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
930 self.layerPool->RemoveUnusedLayers();
931 self.layerPool->RecycleLayers();
933 platformViewLayers = std::move(platformViewLayers),
934 currentCompositionParams =
self.currentCompositionParams,
935 viewsToRecomposite =
self.viewsToRecomposite,
936 compositionOrder =
self.compositionOrder,
937 unusedLayers = std::move(unusedLayers),
938 surfaceFrames = std::move(surfaceFrames)]()
mutable {
939 [self performSubmit:platformViewLayers
940 currentCompositionParams:currentCompositionParams
941 viewsToRecomposite:viewsToRecomposite
942 compositionOrder:compositionOrder
943 unusedLayers:unusedLayers
944 surfaceFrames:surfaceFrames];
947 [
self.taskRunner runNowOrPostTask:^{
953- (void)createMissingOverlays:(
size_t)requiredOverlayLayers
954 withIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext {
955 TRACE_EVENT0(
"flutter",
"PlatformViewsController::CreateMissingLayers");
957 if (requiredOverlayLayers <= self.layerPool->
size()) {
960 auto missingLayerCount = requiredOverlayLayers -
self.layerPool->
size();
965 auto latch = std::make_shared<fml::CountDownLatch>(1u);
966 [
self.taskRunner runNowOrPostTask:^{
967 for (auto i = 0u; i < missingLayerCount; i++) {
968 [
self createLayerWithIosContext:iosContext
969 pixelFormat:((FlutterView*)self.flutterView).pixelFormat];
973 if (![[NSThread currentThread] isMainThread]) {
979 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformResize");
980 FML_DCHECK([[NSThread currentThread] isMainThread]);
982 if (
self.flutterView != nil) {
984 setIntrinsicContentSize:CGSizeMake(frameSize.width, frameSize.height)];
988- (void)performSubmit:(const
LayersMap&)platformViewLayers
989 currentCompositionParams:
990 (
std::unordered_map<int64_t,
flutter::EmbeddedViewParams>&)currentCompositionParams
991 viewsToRecomposite:(const
std::unordered_set<int64_t>&)viewsToRecomposite
992 compositionOrder:(const
std::vector<int64_t>&)compositionOrder
994 (const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
996 (const
std::vector<
std::unique_ptr<
flutter::SurfaceFrame>>&)surfaceFrames {
997 TRACE_EVENT0(
"flutter",
"PlatformViewsController::PerformSubmit");
998 FML_DCHECK([[NSThread currentThread] isMainThread]);
1000 [CATransaction begin];
1003 for (
const auto& [viewId, layerData] : platformViewLayers) {
1004 layerData.layer->UpdateViewState(
self.flutterView,
1007 layerData.overlay_id
1012 for (
auto& view : [
self computeViewsToDispose]) {
1013 [view removeFromSuperview];
1017 for (int64_t viewId : viewsToRecomposite) {
1018 [
self compositeView:viewId withParams:currentCompositionParams[viewId]];
1022 for (
const auto& frame : surfaceFrames) {
1028 [
self removeUnusedLayers:unusedLayers withCompositionOrder:compositionOrder];
1031 [
self bringLayersIntoView:platformViewLayers withCompositionOrder:compositionOrder];
1033 [CATransaction commit];
1036- (void)bringLayersIntoView:(const
LayersMap&)layerMap
1037 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1039 UIView* flutterView =
self.flutterView;
1042 NSMutableArray* desiredPlatformSubviews = [NSMutableArray array];
1043 for (int64_t platformViewId : compositionOrder) {
1045 UIView* platformViewRoot =
self.platformViews[platformViewId].root_view;
1046 if (platformViewRoot != nil) {
1047 [desiredPlatformSubviews addObject:platformViewRoot];
1050 auto maybeLayerData = layerMap.find(platformViewId);
1051 if (maybeLayerData != layerMap.end()) {
1052 auto view = maybeLayerData->second.layer->overlay_view_wrapper;
1054 [desiredPlatformSubviews addObject:view];
1059 NSSet* desiredPlatformSubviewsSet = [NSSet setWithArray:desiredPlatformSubviews];
1060 NSArray* existingPlatformSubviews = [flutterView.subviews
1061 filteredArrayUsingPredicate:[NSPredicate
1062 predicateWithBlock:^BOOL(id object, NSDictionary* bindings) {
1063 return [desiredPlatformSubviewsSet containsObject:object];
1070 if (![desiredPlatformSubviews isEqualToArray:existingPlatformSubviews]) {
1071 for (UIView* subview in desiredPlatformSubviews) {
1073 [flutterView addSubview:subview];
1078- (
std::shared_ptr<flutter::OverlayLayer>)nextLayerInPool {
1079 return self.layerPool->GetNextLayer();
1082- (void)createLayerWithIosContext:(const
std::shared_ptr<
flutter::IOSContext>&)iosContext
1083 pixelFormat:(MTLPixelFormat)pixelFormat {
1084 self.layerPool->CreateLayer(iosContext, pixelFormat);
1087- (void)removeUnusedLayers:(const
std::vector<
std::shared_ptr<
flutter::OverlayLayer>>&)unusedLayers
1088 withCompositionOrder:(const
std::vector<int64_t>&)compositionOrder {
1089 for (
const std::shared_ptr<flutter::OverlayLayer>& layer : unusedLayers) {
1090 [layer->overlay_view_wrapper removeFromSuperview];
1093 std::unordered_set<int64_t> compositionOrderSet;
1094 for (int64_t viewId : compositionOrder) {
1095 compositionOrderSet.insert(viewId);
1099 if (compositionOrderSet.find(viewId) == compositionOrderSet.end()) {
1100 UIView* platformViewRoot =
self.platformViews[viewId].root_view;
1101 [platformViewRoot removeFromSuperview];
1106- (
std::vector<UIView*>)computeViewsToDispose {
1107 std::vector<UIView*> views;
1108 if (
self.viewsToDispose.empty()) {
1112 std::unordered_set<int64_t> viewsToComposite(
self.compositionOrder.begin(),
1113 self.compositionOrder.end());
1114 std::unordered_set<int64_t> viewsToDelayDispose;
1115 for (int64_t viewId :
self.viewsToDispose) {
1116 if (viewsToComposite.count(viewId)) {
1117 viewsToDelayDispose.insert(viewId);
1120 UIView* rootView =
self.platformViews[viewId].root_view;
1121 views.push_back(rootView);
1122 self.currentCompositionParams.erase(viewId);
1123 self.viewsToRecomposite.erase(viewId);
1124 self.platformViews.erase(viewId);
1126 self.viewsToDispose = std::move(viewsToDelayDispose);
1130- (void)resetFrameState {
1131 self.slices.clear();
1132 self.compositionOrder.clear();
1133 self.visitedPlatformViews.clear();
1136- (void)pushVisitedPlatformViewId:(int64_t)viewId {
1137 self.visitedPlatformViews.push_back(viewId);
1140- (void)pushClipRectToVisitedPlatformViews:(const
flutter::
DlRect&)clipRect {
1141 for (int64_t
id :
self.visitedPlatformViews) {
1149 for (int64_t
id :
self.visitedPlatformViews) {
1157 for (int64_t
id :
self.visitedPlatformViews) {
1164- (void)pushClipPathToVisitedPlatformViews:(const
flutter::
DlPath&)clipPath {
1165 for (int64_t
id :
self.visitedPlatformViews) {
1172- (const
flutter::EmbeddedViewParams&)compositionParamsForView:(int64_t)viewId {
1173 return self.currentCompositionParams.find(viewId)->second;
1176#pragma mark - Properties
1178- (
flutter::OverlayLayerPool*)layerPool {
1179 return _layerPool.get();
1182- (
std::unordered_map<int64_t, std::unique_ptr<flutter::EmbedderViewSlice>>&)slices {
1186- (
std::unordered_map<std::string, NSObject<FlutterPlatformViewFactory>*>&)factories {
1190- (
std::unordered_map<std::string, FlutterPlatformViewGestureRecognizersBlockingPolicy>&)
1191 gestureRecognizersBlockingPoliciesByType {
1195- (
std::unordered_map<int64_t, PlatformViewData>&)platformViews {
1199- (
std::unordered_map<int64_t, flutter::EmbeddedViewParams>&)currentCompositionParams {
1203- (
std::unordered_set<int64_t>&)viewsToDispose {
1207- (
std::vector<int64_t>&)compositionOrder {
1211- (
std::vector<int64_t>&)visitedPlatformViews {
1215- (
std::unordered_set<int64_t>&)viewsToRecomposite {
1219- (NSArray<NSNumber*>*)previousCompositionOrder {
1221 NSMutableArray* array = [NSMutableArray arrayWithCapacity:_previousCompositionOrder.size()];
1223 [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)