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...
 
(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 247 of file FlutterPlatformViewsController.mm.

411  {
412  [self resetFrameState];
413 }

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

639  :(int64_t)viewId {
640  FML_DCHECK(self.slices.find(viewId) != self.slices.end());
641  return self.slices[viewId]->canvas();
642 }

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

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

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

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

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

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

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

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

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

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

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

◆ previousCompositionOrder

- (vector<int64_t>& FlutterPlatformViewsController(Testing)):

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

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

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

950  :(int64_t)viewId {
951  self.visitedPlatformViews.push_back(viewId);
952 }

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

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

◆ reset

- (void) reset

Discards all platform views instances and auxiliary resources.

Called from the raster thread.

Definition at line 247 of file FlutterPlatformViewsController.mm.

644  {
645  // Reset will only be called from the raster thread or a merged raster/platform thread.
646  // _platformViews must only be modified on the platform thread, and any operations that
647  // read or modify platform views should occur there.
648  fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, [self]() {
649  for (int64_t viewId : self.compositionOrder) {
650  [self.platformViews[viewId].root_view removeFromSuperview];
651  }
652  self.platformViews.clear();
653  self.previousCompositionOrder.clear();
654  });
655 
656  self.compositionOrder.clear();
657  self.slices.clear();
658  self.currentCompositionParams.clear();
659  self.viewsToRecomposite.clear();
660  self.layerPool->RecycleLayers();
661  self.visitedPlatformViews.clear();
662 }

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

664  :(std::unique_ptr<flutter::SurfaceFrame>)background_frame
665  withIosContext:(const std::shared_ptr<flutter::IOSContext>&)iosContext {
666  TRACE_EVENT0("flutter", "PlatformViewsController::SubmitFrame");
667 
668  // No platform views to render; we're done.
669  if (self.flutterView == nil || (self.compositionOrder.empty() && !self.hadPlatformViews)) {
670  self.hadPlatformViews = NO;
671  return background_frame->Submit();
672  }
673  self.hadPlatformViews = !self.compositionOrder.empty();
674 
675  bool didEncode = true;
676  LayersMap platformViewLayers;
677  std::vector<std::unique_ptr<flutter::SurfaceFrame>> surfaceFrames;
678  surfaceFrames.reserve(self.compositionOrder.size());
679  std::unordered_map<int64_t, DlRect> viewRects;
680 
681  for (int64_t viewId : self.compositionOrder) {
682  viewRects[viewId] = self.currentCompositionParams[viewId].finalBoundingRect();
683  }
684 
685  std::unordered_map<int64_t, DlRect> overlayLayers =
686  SliceViews(background_frame->Canvas(), self.compositionOrder, self.slices, viewRects);
687 
688  size_t requiredOverlayLayers = 0;
689  for (int64_t viewId : self.compositionOrder) {
690  std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
691  if (overlay == overlayLayers.end()) {
692  continue;
693  }
694  requiredOverlayLayers++;
695  }
696 
697  // If there are not sufficient overlay layers, we must construct them on the platform
698  // thread, at least until we've refactored iOS surface creation to use IOSurfaces
699  // instead of CALayers.
700  [self createMissingOverlays:requiredOverlayLayers withIosContext:iosContext];
701 
702  int64_t overlayId = 0;
703  for (int64_t viewId : self.compositionOrder) {
704  std::unordered_map<int64_t, DlRect>::const_iterator overlay = overlayLayers.find(viewId);
705  if (overlay == overlayLayers.end()) {
706  continue;
707  }
708  std::shared_ptr<flutter::OverlayLayer> layer = self.nextLayerInPool;
709  if (!layer) {
710  continue;
711  }
712 
713  std::unique_ptr<flutter::SurfaceFrame> frame = layer->surface->AcquireFrame(self.frameSize);
714  // If frame is null, AcquireFrame already printed out an error message.
715  if (!frame) {
716  continue;
717  }
718  flutter::DlCanvas* overlayCanvas = frame->Canvas();
719  int restoreCount = overlayCanvas->GetSaveCount();
720  overlayCanvas->Save();
721  overlayCanvas->ClipRect(overlay->second);
722  overlayCanvas->Clear(flutter::DlColor::kTransparent());
723  self.slices[viewId]->render_into(overlayCanvas);
724  overlayCanvas->RestoreToCount(restoreCount);
725 
726  // This flutter view is never the last in a frame, since we always submit the
727  // underlay view last.
728  frame->set_submit_info({.frame_boundary = false, .present_with_transaction = true});
729  layer->did_submit_last_frame = frame->Encode();
730 
731  didEncode &= layer->did_submit_last_frame;
732  platformViewLayers[viewId] = LayerData{
733  .rect = overlay->second, //
734  .view_id = viewId, //
735  .overlay_id = overlayId, //
736  .layer = layer //
737  };
738  surfaceFrames.push_back(std::move(frame));
739  overlayId++;
740  }
741 
742  auto previousSubmitInfo = background_frame->submit_info();
743  background_frame->set_submit_info({
744  .frame_damage = previousSubmitInfo.frame_damage,
745  .buffer_damage = previousSubmitInfo.buffer_damage,
746  .present_with_transaction = true,
747  });
748  background_frame->Encode();
749  surfaceFrames.push_back(std::move(background_frame));
750 
751  // Mark all layers as available, so they can be used in the next frame.
752  std::vector<std::shared_ptr<flutter::OverlayLayer>> unusedLayers =
753  self.layerPool->RemoveUnusedLayers();
754  self.layerPool->RecycleLayers();
755 
756  auto task = [self, //
757  platformViewLayers = std::move(platformViewLayers), //
758  currentCompositionParams = self.currentCompositionParams, //
759  viewsToRecomposite = self.viewsToRecomposite, //
760  compositionOrder = self.compositionOrder, //
761  unusedLayers = std::move(unusedLayers), //
762  surfaceFrames = std::move(surfaceFrames) //
763  ]() mutable {
764  [self performSubmit:platformViewLayers
765  currentCompositionParams:currentCompositionParams
766  viewsToRecomposite:viewsToRecomposite
767  compositionOrder:compositionOrder
768  unusedLayers:unusedLayers
769  surfaceFrames:surfaceFrames];
770  };
771 
772  fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, fml::MakeCopyable(std::move(task)));
773 
774  return didEncode;
775 }
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: