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:
 
(std::vector< int64_t > &) - previousCompositionOrder
 

Properties

const fml::RefPtr< fml::TaskRunner > & taskRunner
 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 30 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 249 of file FlutterPlatformViewsController.mm.

413  {
414  [self resetFrameState];
415 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

699  :(int64_t)viewId {
700  FML_DCHECK(self.slices.find(viewId) != self.slices.end());
701  return self.slices[viewId]->canvas();
702 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

422  :(BOOL)shouldResubmitFrame
423  threadMerger:(const fml::RefPtr<fml::RasterThreadMerger>&)rasterThreadMerger {
424 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

468  {
469  for (auto const& [id, platformViewData] : self.platformViews) {
470  UIView* rootView = platformViewData.root_view;
471  if (rootView.flt_hasFirstResponderInViewHierarchySubtree) {
472  return id;
473  }
474  }
475  return -1;
476 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

461  :(int64_t)viewId {
462  if (self.platformViews.empty()) {
463  return nil;
464  }
465  return self.platformViews[viewId].touch_interceptor;
466 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

271  :(FlutterMethodCall*)call result:(FlutterResult)result {
272  if ([[call method] isEqualToString:@"create"]) {
273  [self onCreate:call result:result];
274  } else if ([[call method] isEqualToString:@"dispose"]) {
275  [self onDispose:call result:result];
276  } else if ([[call method] isEqualToString:@"acceptGesture"]) {
277  [self onAcceptGesture:call result:result];
278  } else if ([[call method] isEqualToString:@"rejectGesture"]) {
279  [self onRejectGesture:call result:result];
280  } else {
282  }
283 }
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 249 of file FlutterPlatformViewsController.mm.

417  :
418  (const fml::RefPtr<fml::RasterThreadMerger>&)rasterThreadMerger {
419  return flutter::PostPrerollResult::kSuccess;
420 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

435  :(int64_t)viewId
436  withParams:(std::unique_ptr<flutter::EmbeddedViewParams>)params {
437  DlRect viewBounds = DlRect::MakeSize(self.frameSize);
438  std::unique_ptr<flutter::EmbedderViewSlice> view;
439  view = std::make_unique<flutter::DisplayListEmbedderViewSlice>(viewBounds);
440  self.slices.insert_or_assign(viewId, std::move(view));
441 
442  self.compositionOrder.push_back(viewId);
443 
444  if (self.currentCompositionParams.count(viewId) == 1 &&
445  self.currentCompositionParams[viewId] == *params.get()) {
446  // Do nothing if the params didn't change.
447  return;
448  }
449  self.currentCompositionParams[viewId] = flutter::EmbeddedViewParams(*params.get());
450  self.viewsToRecomposite.insert(viewId);
451 }

◆ previousCompositionOrder

- (vector<int64_t>& 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 249 of file FlutterPlatformViewsController.mm.

1059  :(const flutter::DlPath&)clipPath {
1060  for (int64_t id : self.visitedPlatformViews) {
1061  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1062  params.PushPlatformViewClipPath(clipPath);
1063  self.currentCompositionParams[id] = params;
1064  }
1065 }

◆ pushClipRectToVisitedPlatformViews:

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

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

Definition at line 249 of file FlutterPlatformViewsController.mm.

1035  :(const flutter::DlRect&)clipRect {
1036  for (int64_t id : self.visitedPlatformViews) {
1037  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1038  params.PushPlatformViewClipRect(clipRect);
1039  self.currentCompositionParams[id] = params;
1040  }
1041 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

1043  :(const flutter::DlRoundRect&)clipRRect {
1044  for (int64_t id : self.visitedPlatformViews) {
1045  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1046  params.PushPlatformViewClipRRect(clipRRect);
1047  self.currentCompositionParams[id] = params;
1048  }
1049 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

1051  :(const flutter::DlRoundSuperellipse&)clipRse {
1052  for (int64_t id : self.visitedPlatformViews) {
1053  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1054  params.PushPlatformViewClipRSuperellipse(clipRse);
1055  self.currentCompositionParams[id] = params;
1056  }
1057 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

426  :(const std::shared_ptr<flutter::DlImageFilter>&)filter
427  withRect:(const flutter::DlRect&)filterRect {
428  for (int64_t id : self.visitedPlatformViews) {
429  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
430  params.PushImageFilter(filter, filterRect);
431  self.currentCompositionParams[id] = params;
432  }
433 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

1031  :(int64_t)viewId {
1032  self.visitedPlatformViews.push_back(viewId);
1033 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

398  :(NSObject<FlutterPlatformViewFactory>*)factory
399  withId:(NSString*)factoryId
400  gestureRecognizersBlockingPolicy:
401  (FlutterPlatformViewGestureRecognizersBlockingPolicy)gestureRecognizerBlockingPolicy {
402  std::string idString([factoryId UTF8String]);
403  FML_CHECK(self.factories.count(idString) == 0);
404  self.factories[idString] = factory;
405  self.gestureRecognizersBlockingPolicies[idString] = gestureRecognizerBlockingPolicy;
406 }
FlutterPlatformViewGestureRecognizersBlockingPolicy

◆ reset

- (void) reset

Discards all platform views instances and auxiliary resources.

Called from the raster thread.

Definition at line 249 of file FlutterPlatformViewsController.mm.

704  {
705  // Reset will only be called from the raster thread or a merged raster/platform thread.
706  // _platformViews must only be modified on the platform thread, and any operations that
707  // read or modify platform views should occur there.
708  fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, [self]() {
709  for (int64_t viewId : self.compositionOrder) {
710  [self.platformViews[viewId].root_view removeFromSuperview];
711  }
712  self.platformViews.clear();
713  self.previousCompositionOrder.clear();
714  });
715 
716  self.compositionOrder.clear();
717  self.slices.clear();
718  self.currentCompositionParams.clear();
719  self.viewsToRecomposite.clear();
720  self.layerPool->RecycleLayers();
721  self.visitedPlatformViews.clear();
722 }

◆ 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 249 of file FlutterPlatformViewsController.mm.

724  :(std::unique_ptr<flutter::SurfaceFrame>)background_frame
725  withIosContext:(const std::shared_ptr<flutter::IOSContext>&)iosContext {
726  TRACE_EVENT0("flutter", "PlatformViewsController::SubmitFrame");
727 
728  // No platform views to render.
729  if (self.flutterView == nil || (self.compositionOrder.empty() && !self.hadPlatformViews)) {
730  // No platform views to render but the FlutterView may need to be resized.
731  __weak FlutterPlatformViewsController* weakSelf = self;
732  if (self.flutterView != nil) {
733  fml::TaskRunner::RunNowOrPostTask(
734  weakSelf.platformTaskRunner,
735  fml::MakeCopyable([weakSelf, frameSize = weakSelf.frameSize]() {
736  FlutterPlatformViewsController* strongSelf = weakSelf;
737  if (!strongSelf) {
738  return;
739  }
740  [strongSelf performResize:frameSize];
741  }));
742  }
743 
744  self.hadPlatformViews = NO;
745  return background_frame->Submit();
746  }
747  self.hadPlatformViews = !self.compositionOrder.empty();
748 
749  bool didEncode = true;
750  LayersMap platformViewLayers;
751  std::vector<std::unique_ptr<flutter::SurfaceFrame>> surfaceFrames;
752  surfaceFrames.reserve(self.compositionOrder.size());
753  std::unordered_map<int64_t, DlRect> viewRects;
754 
755  for (int64_t viewId : self.compositionOrder) {
756  viewRects[viewId] = self.currentCompositionParams[viewId].finalBoundingRect();
757  }
758 
759  std::unordered_map<int64_t, DlRect> overlayLayers =
760  SliceViews(background_frame->Canvas(), self.compositionOrder, self.slices, viewRects);
761 
762  size_t requiredOverlayLayers = 0;
763  for (int64_t viewId : self.compositionOrder) {
764  std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
765  if (overlay == overlayLayers.end()) {
766  continue;
767  }
768  requiredOverlayLayers++;
769  }
770 
771  // If there are not sufficient overlay layers, we must construct them on the platform
772  // thread, at least until we've refactored iOS surface creation to use IOSurfaces
773  // instead of CALayers.
774  [self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
775 
776  int64_t overlayId = 0;
777  for (int64_t viewId : self.compositionOrder) {
778  std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
779  if (overlay == overlayLayers.end()) {
780  continue;
781  }
782  std::shared_ptr<flutter::OverlayLayer> layer = self.nextLayerInPool;
783  if (!layer) {
784  continue;
785  }
786 
787  std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(self.frameSize);
788  // If frame is null, AcquireFrame already printed out an error message.
789  if (!frame) {
790  continue;
791  }
792  flutter::DlCanvas* overlayCanvas = frame->Canvas();
793  int restoreCount = overlayCanvas->GetSaveCount();
794  overlayCanvas->Save();
795  overlayCanvas->ClipRect(overlay->second);
796  overlayCanvas->Clear(flutter::DlColor::kTransparent());
797  self.slices[viewId]->render_into(overlayCanvas);
798  overlayCanvas->RestoreToCount(restoreCount);
799 
800  // This flutter view is never the last in a frame, since we always submit the
801  // underlay view last.
802  frame->set_submit_info({.frame_boundary = false, .present_with_transaction = true});
803  layer->did_submit_last_frame = frame->Encode();
804 
805  didEncode &= layer->did_submit_last_frame;
806  platformViewLayers[viewId] = LayerData{
807  .rect = overlay->second, //
808  .view_id = viewId, //
809  .overlay_id = overlayId, //
810  .layer = layer //
811  };
812  surfaceFrames.push_back(std::move(frame));
813  overlayId++;
814  }
815 
816  auto previousSubmitInfo = background_frame->submit_info();
817  background_frame->set_submit_info({
818  .frame_damage = previousSubmitInfo.frame_damage,
819  .buffer_damage = previousSubmitInfo.buffer_damage,
820  .present_with_transaction = true,
821  });
822  background_frame->Encode();
823  surfaceFrames.push_back(std::move(background_frame));
824 
825  // Mark all layers as available, so they can be used in the next frame.
826  std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
827  self.layerPool->RemoveUnusedLayers();
828  self.layerPool->RecycleLayers();
829  auto task = [self, //
830  platformViewLayers = std::move(platformViewLayers), //
831  currentCompositionParams = self.currentCompositionParams, //
832  viewsToRecomposite = self.viewsToRecomposite, //
833  compositionOrder = self.compositionOrder, //
834  unusedLayers = std::move(unusedLayers), //
835  surfaceFrames = std::move(surfaceFrames)]() mutable {
836  [self performSubmit:platformViewLayers
837  currentCompositionParams:currentCompositionParams
838  viewsToRecomposite:viewsToRecomposite
839  compositionOrder:compositionOrder
840  unusedLayers:unusedLayers
841  surfaceFrames:surfaceFrames];
842  };
843 
844  fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, fml::MakeCopyable(std::move(task)));
845  return didEncode;
846 }
std::unordered_map< int64_t, LayerData > LayersMap
UIView *_Nullable flutterView
The flutter view.

Property Documentation

◆ flutterView

- (UIView* _Nullable) flutterView
readwritenonatomicweak

The flutter view.

Definition at line 38 of file FlutterPlatformViewsController.h.

◆ flutterViewController

- (UIViewController<FlutterViewResponder>* _Nullable) flutterViewController
readwritenonatomicweak

The flutter view controller.

Definition at line 41 of file FlutterPlatformViewsController.h.

◆ taskRunner

- (const RefPtr<) fml:
readwritenonatomicassign

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

Definition at line 35 of file FlutterPlatformViewsController.h.


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