Flutter iOS Embedder
FlutterPlatformViewsController Class Reference

#import <FlutterPlatformViewsController.h>

Inheritance diagram for FlutterPlatformViewsController:

Instance Methods

(instancetype) - NS_DESIGNATED_INITIALIZER
 
(void) - registerViewFactory:withId:gestureRecognizersBlockingPolicy:
 set the factory used to construct embedded UI Views. More...
 
(void) - beginFrameWithSize:
 Mark the beginning of a frame and record the size of the onscreen. More...
 
(void) - cancelFrame
 Cancel the current frame, indicating that no platform views are composited. More...
 
(void) - prerollCompositeEmbeddedView:withParams:
 Record a platform view in the layer tree to be rendered, along with the positioning and mutator parameters. More...
 
(FlutterTouchInterceptingView *) - flutterTouchInterceptingViewForId:
 Returns theFlutterTouchInterceptingView with the provided view_id. More...
 
(flutter::PostPrerollResult) - postPrerollActionWithThreadMerger:
 Determine if thread merging is required after prerolling platform views. More...
 
(void) - endFrameWithResubmit:threadMerger:
 Mark the end of a compositor frame. More...
 
(flutter::DlCanvas *) - compositeEmbeddedViewWithId:
 Returns the Canvas for the overlay slice for the given platform view. More...
 
(void) - reset
 Discards all platform views instances and auxiliary resources. More...
 
(BOOL) - submitFrame:withIosContext:
 Encode rendering for the Flutter overlay views and queue up perform platform view mutations. More...
 
(void) - onMethodCall:result:
 Handler for platform view message channels. More...
 
(long) - firstResponderPlatformViewId
 Returns the platform view id if the platform view (or any of its descendant view) is the first responder. More...
 
(void) - pushFilterToVisitedPlatformViews:withRect:
 Pushes backdrop filter mutation to the mutator stack of each visited platform view. More...
 
(void) - pushVisitedPlatformViewId:
 Pushes the view id of a visted platform view to the list of visied platform views. More...
 
(void) - pushClipRectToVisitedPlatformViews:
 Pushes the outstanding rectangular clips to the mutator stack of each visited platform view. More...
 
(void) - pushClipRRectToVisitedPlatformViews:
 Pushes the outstanding rounded rectangular clips to the mutator stack of each visited platform view. More...
 
(void) - pushClipRSuperellipseToVisitedPlatformViews:
 Pushes the outstanding round super elliptical clips to the mutator stack of each visited platform view. More...
 
(void) - pushClipPathToVisitedPlatformViews:
 Pushes the outstanding path clips to the mutator stack of each visited platform view. More...
 
(size_t) - embeddedViewCount
 
(UIView *_Nullable) - platformViewForId:
 
(void) - compositeView:withParams:
 
(const flutter::EmbeddedViewParams &) - compositionParamsForView:
 
(NSArray< NSNumber * > *) - previousCompositionOrder
 The composition order from the previous frame. More...
 

Properties

FlutterFMLTaskRunnertaskRunner
 The task runner used to post rendering tasks to the platform thread. More...
 
UIView *_Nullable flutterView
 The flutter view. More...
 
UIViewController< FlutterViewResponder > *_Nullable flutterViewController
 The flutter view controller. More...
 

Detailed Description

Definition at line 31 of file FlutterPlatformViewsController.h.

Method Documentation

◆ beginFrameWithSize:

- (void) beginFrameWithSize: (flutter::DlISize)  frameSize

Mark the beginning of a frame and record the size of the onscreen.

◆ cancelFrame

- (void) cancelFrame

Cancel the current frame, indicating that no platform views are composited.

Additionally, reverts the composition order to its original state at the beginning of the frame.

Definition at line 320 of file FlutterPlatformViewsController.mm.

505  {
506  [self resetFrameState];
507 }

◆ compositeEmbeddedViewWithId:

- (DlCanvas *) FlutterPlatformViewsController: (int64_t)  viewId

Returns the Canvas for the overlay slice for the given platform view.

Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

789  :(int64_t)viewId {
790  FML_DCHECK(self.slices.find(viewId) != self.slices.end());
791  return self.slices[viewId]->canvas();
792 }

◆ compositeView:withParams:

- (void) compositeView: (int64_t)  viewId
withParams: (const flutter::EmbeddedViewParams &)  params 

◆ compositionParamsForView:

- (const EmbeddedViewParams& FlutterPlatformViewsController(Testing)): (int64_t)  viewId

◆ embeddedViewCount

- (size_t) embeddedViewCount

◆ endFrameWithResubmit:threadMerger:

- (void) endFrameWithResubmit: (BOOL)  shouldResubmitFrame
threadMerger: (const fml::RefPtr<fml::RasterThreadMerger>&)  rasterThreadMerger 

Mark the end of a compositor frame.

May determine changes are required to the thread merging state. Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

514  :(BOOL)shouldResubmitFrame
515  threadMerger:(const fml::RefPtr<fml::RasterThreadMerger>&)rasterThreadMerger {
516 }

◆ firstResponderPlatformViewId

- (long) firstResponderPlatformViewId

Returns the platform view id if the platform view (or any of its descendant view) is the first responder.

Returns -1 if no such platform view is found.

Definition at line 320 of file FlutterPlatformViewsController.mm.

560  {
561  for (auto const& [id, platformViewData] : self.platformViews) {
562  UIView* rootView = platformViewData.root_view;
563  if (rootView.flt_hasFirstResponderInViewHierarchySubtree) {
564  return id;
565  }
566  }
567  return -1;
568 }

◆ flutterTouchInterceptingViewForId:

- (FlutterTouchInterceptingView *) flutterTouchInterceptingViewForId: (int64_t)  viewId

Returns theFlutterTouchInterceptingView with the provided view_id.

Returns nil if there is no platform view with the provided id. Called from the platform thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

553  :(int64_t)viewId {
554  if (self.platformViews.empty()) {
555  return nil;
556  }
557  return self.platformViews[viewId].touch_interceptor;
558 }

◆ NS_DESIGNATED_INITIALIZER

- (instancetype) NS_DESIGNATED_INITIALIZER

◆ onMethodCall:result:

- (void) onMethodCall: (FlutterMethodCall*)  call
result: (FlutterResult result 

Handler for platform view message channels.

Definition at line 320 of file FlutterPlatformViewsController.mm.

342  :(FlutterMethodCall*)call result:(FlutterResult)result {
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];
351  } else {
353  }
354 }
void(^ FlutterResult)(id _Nullable result)
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented

◆ platformViewForId:

- (UIView* _Nullable) platformViewForId: (int64_t)  viewId

◆ postPrerollActionWithThreadMerger:

- (PostPrerollResult) FlutterPlatformViewsController: (const fml::RefPtr<fml::RasterThreadMerger>&)  rasterThreadMerger

Determine if thread merging is required after prerolling platform views.

Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

509  :
510  (const fml::RefPtr<fml::RasterThreadMerger>&)rasterThreadMerger {
511  return flutter::PostPrerollResult::kSuccess;
512 }

◆ prerollCompositeEmbeddedView:withParams:

- (void) prerollCompositeEmbeddedView: (int64_t)  viewId
withParams: (std::unique_ptr<flutter::EmbeddedViewParams>)  params 

Record a platform view in the layer tree to be rendered, along with the positioning and mutator parameters.

Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

527  :(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));
533 
534  self.compositionOrder.push_back(viewId);
535 
536  if (self.currentCompositionParams.count(viewId) == 1 &&
537  self.currentCompositionParams[viewId] == *params.get()) {
538  // Do nothing if the params didn't change.
539  return;
540  }
541  self.currentCompositionParams[viewId] = flutter::EmbeddedViewParams(*params.get());
542  self.viewsToRecomposite.insert(viewId);
543 }

◆ previousCompositionOrder

- (NSArray<NSNumber*>*) previousCompositionOrder

The composition order from the previous frame.

Only accessed from the platform thread.

Provided by category FlutterPlatformViewsController(Testing).

◆ pushClipPathToVisitedPlatformViews:

- (void) pushClipPathToVisitedPlatformViews: (const flutter::DlPath&)  clipPath

Pushes the outstanding path clips to the mutator stack of each visited platform view.

Definition at line 320 of file FlutterPlatformViewsController.mm.

1162  :(const flutter::DlPath&)clipPath {
1163  for (int64_t id : self.visitedPlatformViews) {
1164  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1165  params.PushPlatformViewClipPath(clipPath);
1166  self.currentCompositionParams[id] = params;
1167  }
1168 }

◆ pushClipRectToVisitedPlatformViews:

- (void) pushClipRectToVisitedPlatformViews: (const flutter::DlRect&)  clipRect

Pushes the outstanding rectangular clips to the mutator stack of each visited platform view.

Definition at line 320 of file FlutterPlatformViewsController.mm.

1138  :(const flutter::DlRect&)clipRect {
1139  for (int64_t id : self.visitedPlatformViews) {
1140  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1141  params.PushPlatformViewClipRect(clipRect);
1142  self.currentCompositionParams[id] = params;
1143  }
1144 }

◆ pushClipRRectToVisitedPlatformViews:

- (void) pushClipRRectToVisitedPlatformViews: (const flutter::DlRoundRect&)  clipRRect

Pushes the outstanding rounded rectangular clips to the mutator stack of each visited platform view.

Definition at line 320 of file FlutterPlatformViewsController.mm.

1146  :(const flutter::DlRoundRect&)clipRRect {
1147  for (int64_t id : self.visitedPlatformViews) {
1148  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1149  params.PushPlatformViewClipRRect(clipRRect);
1150  self.currentCompositionParams[id] = params;
1151  }
1152 }

◆ pushClipRSuperellipseToVisitedPlatformViews:

- (void) pushClipRSuperellipseToVisitedPlatformViews: (const flutter::DlRoundSuperellipse&)  clipRse

Pushes the outstanding round super elliptical clips to the mutator stack of each visited platform view.

Definition at line 320 of file FlutterPlatformViewsController.mm.

1154  :(const flutter::DlRoundSuperellipse&)clipRse {
1155  for (int64_t id : self.visitedPlatformViews) {
1156  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1157  params.PushPlatformViewClipRSuperellipse(clipRse);
1158  self.currentCompositionParams[id] = params;
1159  }
1160 }

◆ pushFilterToVisitedPlatformViews:withRect:

- (void) pushFilterToVisitedPlatformViews: (const std::shared_ptr<flutter::DlImageFilter>&)  filter
withRect: (const flutter::DlRect&)  filterRect 

Pushes backdrop filter mutation to the mutator stack of each visited platform view.

Definition at line 320 of file FlutterPlatformViewsController.mm.

518  :(const std::shared_ptr<flutter::DlImageFilter>&)filter
519  withRect:(const flutter::DlRect&)filterRect {
520  for (int64_t id : self.visitedPlatformViews) {
521  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
522  params.PushImageFilter(filter, filterRect);
523  self.currentCompositionParams[id] = params;
524  }
525 }

◆ pushVisitedPlatformViewId:

- (void) pushVisitedPlatformViewId: (int64_t)  viewId

Pushes the view id of a visted platform view to the list of visied platform views.

Definition at line 320 of file FlutterPlatformViewsController.mm.

1134  :(int64_t)viewId {
1135  self.visitedPlatformViews.push_back(viewId);
1136 }

◆ registerViewFactory:withId:gestureRecognizersBlockingPolicy:

- (void) registerViewFactory: (NSObject<FlutterPlatformViewFactory>*)  factory
withId: (NSString*)  factoryId
gestureRecognizersBlockingPolicy: (FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy 

set the factory used to construct embedded UI Views.

Definition at line 320 of file FlutterPlatformViewsController.mm.

490  :(NSObject<FlutterPlatformViewFactory>*)factory
491  withId:(NSString*)factoryId
492  gestureRecognizersBlockingPolicy:
493  (FlutterPlatformViewGestureRecognizersBlockingPolicy)gestureRecognizerBlockingPolicy {
494  std::string idString([factoryId UTF8String]);
495  FML_CHECK(self.factories.count(idString) == 0);
496  self.factories[idString] = factory;
497  self.gestureRecognizersBlockingPoliciesByType[idString] = gestureRecognizerBlockingPolicy;
498 }
FlutterPlatformViewGestureRecognizersBlockingPolicy

◆ reset

- (void) reset

Discards all platform views instances and auxiliary resources.

Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

794  {
795  // Reset will only be called from the raster thread or a merged raster/platform thread.
796  // _platformViews must only be modified on the platform thread, and any operations that
797  // read or modify platform views should occur there.
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];
802  }
803  self.platformViews.clear();
804  _previousCompositionOrder.clear();
805  }];
806 
807  self.compositionOrder.clear();
808  self.slices.clear();
809  self.currentCompositionParams.clear();
810  self.viewsToRecomposite.clear();
811  self.layerPool->RecycleLayers();
812  self.visitedPlatformViews.clear();
813 }

◆ submitFrame:withIosContext:

- (BOOL) submitFrame: (std::unique_ptr<flutter::SurfaceFrame>)  frame
withIosContext: (const std::shared_ptr<flutter::IOSContext>&)  iosContext 

Encode rendering for the Flutter overlay views and queue up perform platform view mutations.

Called from the raster thread.

Definition at line 320 of file FlutterPlatformViewsController.mm.

815  :(std::unique_ptr<flutter::SurfaceFrame>)background_frame
816  withIosContext:(const std::shared_ptr<flutter::IOSContext>&)iosContext {
817  TRACE_EVENT0("flutter", "PlatformViewsController::SubmitFrame");
818 
819  // No platform views to render.
820  if (self.flutterView == nil || (self.compositionOrder.empty() && !self.hadPlatformViews)) {
821  // No platform views to render but the FlutterView may need to be resized.
822  __weak FlutterPlatformViewsController* weakSelf = self;
823  if (self.flutterView != nil) {
824  // Pass frameSize by value since self.frameSize is mutated both here (on the platform
825  // thread) and in beginFrameWithSize: (on the raster thread).
826  const flutter::DlISize frameSize = self.frameSize;
827  [self.taskRunner runNowOrPostTask:^{
828  FlutterPlatformViewsController* strongSelf = weakSelf;
829  if (!strongSelf) {
830  return;
831  }
832  [strongSelf performResize:frameSize];
833  }];
834  }
835 
836  self.hadPlatformViews = NO;
837  return background_frame->Submit();
838  }
839  self.hadPlatformViews = !self.compositionOrder.empty();
840 
841  bool didEncode = true;
842  LayersMap platformViewLayers;
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;
847 
848  for (int64_t viewId : self.compositionOrder) {
849  const flutter::EmbeddedViewParams& params = self.currentCompositionParams[viewId];
850  viewRects[viewId] = params.finalBoundingRect();
851  if (HasNonRectClipForUnderlayCutout(params)) {
852  viewsWithUnderlayPreserved.insert(viewId);
853  }
854  }
855 
856  std::unordered_map<int64_t, DlRect> overlayLayers =
857  SliceViews(background_frame->Canvas(), self.compositionOrder, self.slices, viewRects,
858  viewsWithUnderlayPreserved);
859 
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()) {
864  continue;
865  }
866  requiredOverlayLayers++;
867  }
868 
869  // If there are not sufficient overlay layers, we must construct them on the platform
870  // thread, at least until we've refactored iOS surface creation to use IOSurfaces
871  // instead of CALayers.
872  [self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
873 
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()) {
878  continue;
879  }
880  std::shared_ptr<flutter::OverlayLayer> layer = self.nextLayerInPool;
881  if (!layer) {
882  continue;
883  }
884 
885  std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(self.frameSize);
886  // If frame is null, AcquireFrame already printed out an error message.
887  if (!frame) {
888  continue;
889  }
890  flutter::DlCanvas* overlayCanvas = frame->Canvas();
891  int restoreCount = overlayCanvas->GetSaveCount();
892  overlayCanvas->Save();
893  overlayCanvas->ClipRect(overlay->second);
894  if (viewsWithUnderlayPreserved.find(viewId) != viewsWithUnderlayPreserved.end()) {
895  ApplyNonRectClipToOverlayCanvas(overlayCanvas, self.currentCompositionParams[viewId]);
896  }
897  overlayCanvas->Clear(flutter::DlColor::kTransparent());
898  self.slices[viewId]->render_into(overlayCanvas);
899  overlayCanvas->RestoreToCount(restoreCount);
900 
901  // This flutter view is never the last in a frame, since we always submit the
902  // underlay view last.
903  frame->set_submit_info({.frame_boundary = false, .present_with_transaction = true});
904  layer->did_submit_last_frame = frame->Encode();
905 
906  didEncode &= layer->did_submit_last_frame;
907  platformViewLayers[viewId] = LayerData{
908  .rect = overlay->second, //
909  .view_id = viewId, //
910  .overlay_id = overlayId, //
911  .layer = layer //
912  };
913  surfaceFrames.push_back(std::move(frame));
914  overlayId++;
915  }
916 
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,
922  });
923  background_frame->Encode();
924  surfaceFrames.push_back(std::move(background_frame));
925 
926  // Mark all layers as available, so they can be used in the next frame.
927  std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
928  self.layerPool->RemoveUnusedLayers();
929  self.layerPool->RecycleLayers();
930  auto task = fml::MakeCopyable([self, //
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];
943  });
944 
945  [self.taskRunner runNowOrPostTask:^{
946  task();
947  }];
948  return didEncode;
949 }
static bool HasNonRectClipForUnderlayCutout(const flutter::EmbeddedViewParams &params)
std::unordered_map< int64_t, LayerData > LayersMap
static void ApplyNonRectClipToOverlayCanvas(flutter::DlCanvas *overlay_canvas, const flutter::EmbeddedViewParams &params)
UIView *_Nullable flutterView
The flutter view.

Property Documentation

◆ flutterView

- (UIView* _Nullable) flutterView
readwritenonatomicweak

The flutter view.

Definition at line 39 of file FlutterPlatformViewsController.h.

◆ flutterViewController

- (UIViewController<FlutterViewResponder>* _Nullable) flutterViewController
readwritenonatomicweak

The flutter view controller.

Definition at line 42 of file FlutterPlatformViewsController.h.

◆ taskRunner

- (FlutterFMLTaskRunner *) taskRunner
readwritenonatomicstrong

The task runner used to post rendering tasks to the platform thread.

Definition at line 36 of file FlutterPlatformViewsController.h.

Referenced by flutter::testing::CreateTestPlatformViewsController().


The documentation for this class was generated from the following files: