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.

971  :(int64_t)viewId {
972  self.visitedPlatformViews.push_back(viewId);
973 }

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