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.

680  :(int64_t)viewId {
681  FML_DCHECK(self.slices.find(viewId) != self.slices.end());
682  return self.slices[viewId]->canvas();
683 }

◆ 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.

1040  :(const flutter::DlPath&)clipPath {
1041  for (int64_t id : self.visitedPlatformViews) {
1042  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1043  params.PushPlatformViewClipPath(clipPath);
1044  self.currentCompositionParams[id] = params;
1045  }
1046 }

◆ 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.

1016  :(const flutter::DlRect&)clipRect {
1017  for (int64_t id : self.visitedPlatformViews) {
1018  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1019  params.PushPlatformViewClipRect(clipRect);
1020  self.currentCompositionParams[id] = params;
1021  }
1022 }

◆ 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.

1024  :(const flutter::DlRoundRect&)clipRRect {
1025  for (int64_t id : self.visitedPlatformViews) {
1026  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1027  params.PushPlatformViewClipRRect(clipRRect);
1028  self.currentCompositionParams[id] = params;
1029  }
1030 }

◆ 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.

1032  :(const flutter::DlRoundSuperellipse&)clipRse {
1033  for (int64_t id : self.visitedPlatformViews) {
1034  flutter::EmbeddedViewParams params = self.currentCompositionParams[id];
1035  params.PushPlatformViewClipRSuperellipse(clipRse);
1036  self.currentCompositionParams[id] = params;
1037  }
1038 }

◆ 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.

1012  :(int64_t)viewId {
1013  self.visitedPlatformViews.push_back(viewId);
1014 }

◆ 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.

685  {
686  // Reset will only be called from the raster thread or a merged raster/platform thread.
687  // _platformViews must only be modified on the platform thread, and any operations that
688  // read or modify platform views should occur there.
689  fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, [self]() {
690  for (int64_t viewId : self.compositionOrder) {
691  [self.platformViews[viewId].root_view removeFromSuperview];
692  }
693  self.platformViews.clear();
694  self.previousCompositionOrder.clear();
695  });
696 
697  self.compositionOrder.clear();
698  self.slices.clear();
699  self.currentCompositionParams.clear();
700  self.viewsToRecomposite.clear();
701  self.layerPool->RecycleLayers();
702  self.visitedPlatformViews.clear();
703 }

◆ 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.

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