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: (SkISize)  frameSize

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

Definition at line 409 of file FlutterPlatformViewsController.mm.

409  :(SkISize)frameSize {
410  [self resetFrameState];
411  self.frameSize = frameSize;
412 }

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

414  {
415  [self resetFrameState];
416 }

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

645  :(int64_t)viewId {
646  FML_DCHECK(self.slices.find(viewId) != self.slices.end());
647  return self.slices[viewId]->canvas();
648 }

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

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

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

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

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

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

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

272  :(FlutterMethodCall*)call result:(FlutterResult)result {
273  if ([[call method] isEqualToString:@"create"]) {
274  [self onCreate:call result:result];
275  } else if ([[call method] isEqualToString:@"dispose"]) {
276  [self onDispose:call result:result];
277  } else if ([[call method] isEqualToString:@"acceptGesture"]) {
278  [self onAcceptGesture:call result:result];
279  } else if ([[call method] isEqualToString:@"rejectGesture"]) {
280  [self onRejectGesture:call result:result];
281  } else {
283  }
284 }

References 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 418 of file FlutterPlatformViewsController.mm.

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

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

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

◆ previousCompositionOrder

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

◆ pushFilterToVisitedPlatformViews:withRect:

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

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

Definition at line 427 of file FlutterPlatformViewsController.mm.

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

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

958  :(int64_t)viewId {
959  self.visitedPlatformViews.push_back(viewId);
960 }

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

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

◆ reset

- (void) reset

Discards all platform views instances and auxiliary resources.

Called from the raster thread.

Definition at line 650 of file FlutterPlatformViewsController.mm.

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

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

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

References LayerData::rect.

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:
FlutterMethodNotImplemented
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
LayersMap
std::unordered_map< int64_t, LayerData > LayersMap
Definition: FlutterPlatformViewsController.mm:31
LayerData
Definition: FlutterPlatformViewsController.mm:25
FlutterMethodCall
Definition: FlutterCodecs.h:220
FlutterPlatformViewsController::flutterView
UIView *_Nullable flutterView
The flutter view.
Definition: FlutterPlatformViewsController.h:38
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:194
FlutterPlatformViewGestureRecognizersBlockingPolicy
FlutterPlatformViewGestureRecognizersBlockingPolicy
Definition: FlutterPlugin.h:252
LayerData::rect
SkRect rect
Definition: FlutterPlatformViewsController.mm:26