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

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

Definition at line 248 of file FlutterPlatformViewsController.mm.

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

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

412 {
413 [self resetFrameState];
414 }

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

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

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

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

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

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

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

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

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

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

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

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

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

## ◆ previousCompositionOrder

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

Provided by category 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 248 of file FlutterPlatformViewsController.mm.

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

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

952 :(int64_t)viewId {
953 self.visitedPlatformViews.push_back(viewId);
954 }

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

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

## ◆ reset

- (void) reset |  |  |

Discards all platform views instances and auxiliary resources.

Called from the raster thread.

Definition at line 248 of file FlutterPlatformViewsController.mm.

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

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

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

## 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