| Flutter iOS Embedder |

Instance Methods | Properties | List of all members
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 the`FlutterTouchInterceptingView` 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

Provided by category FlutterPlatformViewsController(Testing).

## ◆ compositionParamsForView:

- (const EmbeddedViewParams& FlutterPlatformViewsController(Testing)): |  | (int64_t) | viewId |

Provided by category FlutterPlatformViewsController(Testing).

## ◆ embeddedViewCount

- (size_t) embeddedViewCount |  |  |

Provided by category FlutterPlatformViewsController(Testing).

## ◆ 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 the`FlutterTouchInterceptingView` 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 {
279 result(FlutterMethodNotImplemented);
280 }
281 }
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:194
FlutterMethodNotImplemented
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
FlutterMethodCall
Definition: FlutterCodecs.h:221

## ◆ platformViewForId:

- (UIView* _Nullable) platformViewForId: |  | (int64_t) | viewId |

Provided by category FlutterPlatformViewsController(Testing).

## ◆ 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)): |  |  |

Provided by category 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
FlutterPlatformViewGestureRecognizersBlockingPolicy
Definition: FlutterPlugin.h:253

## ◆ 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 }
LayersMap
std::unordered_map< int64_t, LayerData > LayersMap
Definition: FlutterPlatformViewsController.mm:31
FlutterPlatformViewsController
Definition: FlutterPlatformViewsController.h:31
FlutterPlatformViewsController::flutterView
UIView *_Nullable flutterView
The flutter view.
Definition: FlutterPlatformViewsController.h:38
LayerData
Definition: FlutterPlatformViewsController.mm:25
LayerData::rect
DlRect rect
Definition: FlutterPlatformViewsController.mm:26

## Property Documentation

## ◆ flutterView

- (UIView* _Nullable) flutterView
| read write nonatomic weak

The flutter view.

Definition at line 38 of file FlutterPlatformViewsController.h.

## ◆ flutterViewController

- (UIViewController<FlutterViewResponder>* _Nullable) flutterViewController
| read write nonatomic weak

The flutter view controller.

Definition at line 41 of file FlutterPlatformViewsController.h.

## ◆ taskRunner

- (const RefPtr<) fml:
| read write nonatomic assign

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:

- shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h
- shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm