| Flutter iOS Embedder |

Instance Methods | List of all members
flutter::FlutterPlatformViewsController Class Reference

`#import <FlutterPlatformViews_Internal.h>`

## Instance Methods
() | - FlutterPlatformViewsController
() | - ~FlutterPlatformViewsController
(fml::WeakPtr< flutter::FlutterPlatformViewsController >) | - GetWeakPtr
(void) | - SetFlutterView
(void) | - SetFlutterViewController
(UIViewController *) | - getFlutterViewController
(void) | - RegisterViewFactory
(void) | - BeginFrame
(void) | - CancelFrame
(void) | - PrerollCompositeEmbeddedView
(size_t) | - EmbeddedViewCount
(UIView *) | - GetPlatformViewByID
(FlutterTouchInterceptingView *) | - GetFlutterTouchInterceptingViewByID
(PostPrerollResult) | - PostPrerollAction
(void) | - EndFrame
(DlCanvas *) | - CompositeEmbeddedView
(SkRect) | - GetPlatformViewRect
(void) | - Reset
(bool) | - SubmitFrame
(void) | - OnMethodCall
(long) | - FindFirstResponderPlatformViewId
(void) | - PushFilterToVisitedPlatformViews
(void) | - PushVisitedPlatformView

## Detailed Description

Definition at line 200 of file FlutterPlatformViews_Internal.h.

## Constructor & Destructor Documentation

## ◆ FlutterPlatformViewsController

- FlutterPlatformViewsController: |  |  |

Definition at line 28 of file FlutterPlatformViews_Internal.mm.

29 : layer_pool_(std::make_unique<FlutterPlatformViewLayerPool>()),
30 weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)) {
31 mask_view_pool_.reset(
32 [[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity]);
33 };

References kFlutterClippingMaskViewPoolCapacity.

## ◆ ~FlutterPlatformViewsController

- FlutterPlatformViewsController: |  |  |

## Method Documentation

## ◆ BeginFrame

- (void) FlutterPlatformViewsController: |  | (SkISize) | frame_size |

Definition at line 317 of file FlutterPlatformViews.mm.

317 {
318 ResetFrameState();
319 frame_size_ = frame_size;
320 }

## ◆ CancelFrame

- (void) FlutterPlatformViewsController: |  |  |

Definition at line 322 of file FlutterPlatformViews.mm.

322 {
323 ResetFrameState();
324 }

## ◆ CompositeEmbeddedView

- (DlCanvas *) FlutterPlatformViewsController: |  | (int64_t) | view_id |

Definition at line 622 of file FlutterPlatformViews.mm.

622 {
623 // Any UIKit related code has to run on main thread.
624 FML_DCHECK([[NSThread currentThread] isMainThread]);
625 // Do nothing if the view doesn't need to be composited.
626 if (views_to_recomposite_.count(view_id) == 0) {
627 return slices_[view_id]->canvas();
628 }
629 CompositeWithParams(view_id, current_composition_params_[view_id]);
630 views_to_recomposite_.erase(view_id);
631 return slices_[view_id]->canvas();
632 }

## ◆ EmbeddedViewCount

- (size_t) FlutterPlatformViewsController: |  |  |

Definition at line 404 of file FlutterPlatformViews.mm.

404 {
405 return composition_order_.size();
406 }

## ◆ EndFrame

- (void) FlutterPlatformViewsController: |  | (bool) | should_resubmit_frame
|  | (const fml::RefPtr< fml::RasterThreadMerger > &) | raster_thread_merger

Definition at line 363 of file FlutterPlatformViews.mm.

365 {
366 if (should_resubmit_frame) {
367 raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
368 }
369 }

## ◆ FindFirstResponderPlatformViewId

- (long) FlutterPlatformViewsController: |  |  |

Definition at line 420 of file FlutterPlatformViews.mm.

420 {
421 for (auto const& [id, root_view] : root_views_) {
422 if ((UIView*)(root_view.get()).flt_hasFirstResponderInViewHierarchySubtree) {
423 return id;
424 }
425 }
426 return -1;
427 }

References id.

## ◆ GetFlutterTouchInterceptingViewByID

- (FlutterTouchInterceptingView *) FlutterPlatformViewsController: |  | (int64_t) | view_id |

Definition at line 412 of file FlutterPlatformViews.mm.

413 {
414 if (views_.empty()) {
415 return nil;
416 }
417 return touch_interceptors_[view_id].get();
418 }

Referenced by GetPlatformViewByID.

## ◆ getFlutterViewController

- (UIViewController *) FlutterPlatformViewsController: |  |  |

Definition at line 172 of file FlutterPlatformViews.mm.

172 {
173 return flutter_view_controller_.get();
174 }

## ◆ GetPlatformViewByID

- (UIView *) FlutterPlatformViewsController: |  | (int64_t) | view_id |

Definition at line 408 of file FlutterPlatformViews.mm.

408 {
409 return [GetFlutterTouchInterceptingViewByID(view_id) embeddedView];
410 }

References FlutterTouchInterceptingView::embeddedView, and GetFlutterTouchInterceptingViewByID.

## ◆ GetPlatformViewRect

- (SkRect) FlutterPlatformViewsController: |  | (int64_t) | view_id |

Definition at line 652 of file FlutterPlatformViews.mm.

652 {
653 UIView* platform_view = GetPlatformViewByID(view_id);
654 UIScreen* screen = [UIScreen mainScreen];
655 CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds
656 toView:flutter_view_];
657 return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale, //
658 platform_view_cgrect.origin.y * screen.scale, //
659 platform_view_cgrect.size.width * screen.scale, //
660 platform_view_cgrect.size.height * screen.scale //
661 );
662 }

References platform_view.

## ◆ GetWeakPtr

- (WeakPtr<) flutter: |  |  |

Definition at line 37 of file FlutterPlatformViews_Internal.mm.

37 {
38 return weak_factory_->GetWeakPtr();
39 }

## ◆ OnMethodCall

- (void) FlutterPlatformViewsController: |  | (FlutterMethodCall *) | call
|  | (FlutterResult &) | result

Definition at line 176 of file FlutterPlatformViews.mm.

176 {
177 if ([[call method] isEqualToString:@"create"]) {
178 OnCreate(call, result);
179 } else if ([[call method] isEqualToString:@"dispose"]) {
180 OnDispose(call, result);
181 } else if ([[call method] isEqualToString:@"acceptGesture"]) {
182 OnAcceptGesture(call, result);
183 } else if ([[call method] isEqualToString:@"rejectGesture"]) {
184 OnRejectGesture(call, result);
185 } else {
186 result(FlutterMethodNotImplemented);
187 }
188 }

References FlutterMethodNotImplemented.

## ◆ PostPrerollAction

- (PostPrerollResult) FlutterPlatformViewsController: |  | (const fml::RefPtr< fml::RasterThreadMerger > &) | raster_thread_merger |

Definition at line 335 of file FlutterPlatformViews.mm.

336 {
337 // TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474
338 // Rename `has_platform_view` to `view_mutated` when the above issue is resolved.
339 if (!HasPlatformViewThisOrNextFrame()) {
340 return PostPrerollResult::kSuccess;
341 }
342 if (!raster_thread_merger->IsMerged()) {
343 // The raster thread merger may be disabled if the rasterizer is being
344 // created or teared down.
345 //
346 // In such cases, the current frame is dropped, and a new frame is attempted
347 // with the same layer tree.
348 //
349 // Eventually, the frame is submitted once this method returns `kSuccess`.
350 // At that point, the raster tasks are handled on the platform thread.
351 CancelFrame();
352 return PostPrerollResult::kSkipAndRetryFrame;
353 }
354 // If the post preroll action is successful, we will display platform views in the current frame.
355 // In order to sync the rendering of the platform views (quartz) with skia's rendering,
356 // We need to begin an explicit CATransaction. This transaction needs to be submitted
357 // after the current frame is submitted.
358 BeginCATransaction();
359 raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
360 return PostPrerollResult::kSuccess;
361 }

## ◆ PrerollCompositeEmbeddedView

- (void) FlutterPlatformViewsController: |  | (int64_t) | view_id
|  | (std::unique_ptr< flutter::EmbeddedViewParams >) | params

Definition at line 381 of file FlutterPlatformViews.mm.

383 {
384 // All the CATransactions should be committed by the end of the last frame,
385 // so catransaction_added_ must be false.
386 FML_DCHECK(!catransaction_added_);
387
388 SkRect view_bounds = SkRect::Make(frame_size_);
389 std::unique_ptr<EmbedderViewSlice> view;
390 view = std::make_unique<DisplayListEmbedderViewSlice>(view_bounds);
391 slices_.insert_or_assign(view_id, std::move(view));
392
393 composition_order_.push_back(view_id);
394
395 if (current_composition_params_.count(view_id) == 1 &&
396 current_composition_params_[view_id] == *params.get()) {
397 // Do nothing if the params didn't change.
398 return;
399 }
400 current_composition_params_[view_id] = EmbeddedViewParams(*params.get());
401 views_to_recomposite_.insert(view_id);
402 }

## ◆ PushFilterToVisitedPlatformViews

- (void) FlutterPlatformViewsController: |  | (const std::shared_ptr< const DlImageFilter > &) | filter
|  | (const SkRect &) | filter_rect

Definition at line 371 of file FlutterPlatformViews.mm.

373 {
374 for (int64_t id : visited_platform_views_) {
375 EmbeddedViewParams params = current_composition_params_[id];
376 params.PushImageFilter(filter, filter_rect);
377 current_composition_params_[id] = params;
378 }
379 }

## ◆ PushVisitedPlatformView

- (void) FlutterPlatformViewsController: |  | (int64_t) | view_id |

Definition at line 275 of file FlutterPlatformViews_Internal.h.

275 { visited_platform_views_.push_back(view_id); }

## ◆ RegisterViewFactory

- (void) FlutterPlatformViewsController: |  | (NSObject< FlutterPlatformViewFactory > *) | factory
|  | (NSString *) | factoryId
|  | (FlutterPlatformViewGestureRecognizersBlockingPolicy) | gestureRecognizerBlockingPolicy

Definition at line 306 of file FlutterPlatformViews.mm.

309 {
310 std::string idString([factoryId UTF8String]);
311 FML_CHECK(factories_.count(idString) == 0);
312 factories_[idString] =
313 fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>([factory retain]);
314 gesture_recognizers_blocking_policies[idString] = gestureRecognizerBlockingPolicy;
315 }

## ◆ Reset

- (void) FlutterPlatformViewsController: |  |  |

Definition at line 634 of file FlutterPlatformViews.mm.

634 {
635 for (int64_t view_id : active_composition_order_) {
636 UIView* sub_view = root_views_[view_id].get();
637 [sub_view removeFromSuperview];
638 }
639 root_views_.clear();
640 touch_interceptors_.clear();
641 views_.clear();
642 composition_order_.clear();
643 active_composition_order_.clear();
644 slices_.clear();
645 current_composition_params_.clear();
646 clip_count_.clear();
647 views_to_recomposite_.clear();
648 layer_pool_->RecycleLayers();
649 visited_platform_views_.clear();
650 }

## ◆ SetFlutterView

- (void) FlutterPlatformViewsController: |  | (UIView *) | flutter_view |

Definition at line 163 of file FlutterPlatformViews.mm.

163 {
164 flutter_view_.reset([flutter_view retain]);
165 }

## ◆ SetFlutterViewController

- (void) FlutterPlatformViewsController: |  | (UIViewController *) | flutter_view_controller |

Definition at line 167 of file FlutterPlatformViews.mm.

168 {
169 flutter_view_controller_.reset([flutter_view_controller retain]);
170 }

## ◆ SubmitFrame

- (bool) FlutterPlatformViewsController: |  | (GrDirectContext *) | gr_context
|  | (const std::shared_ptr< IOSContext > &) | ios_context
|  | (std::unique_ptr< SurfaceFrame >) | frame

Definition at line 664 of file FlutterPlatformViews.mm.

666 {
667 TRACE_EVENT0("flutter", "FlutterPlatformViewsController::SubmitFrame");
668
669 // Any UIKit related code has to run on main thread.
670 FML_DCHECK([[NSThread currentThread] isMainThread]);
671 if (flutter_view_ == nullptr) {
672 return frame->Submit();
673 }
674
675 DisposeViews();
676
677 DlCanvas* background_canvas = frame->Canvas();
678
679 // Resolve all pending GPU operations before allocating a new surface.
680 background_canvas->Flush();
681
682 // Clipping the background canvas before drawing the picture recorders requires
683 // saving and restoring the clip context.
684 DlAutoCanvasRestore save(background_canvas, /*doSave=*/true);
685
686 // Maps a platform view id to a vector of `FlutterPlatformViewLayer`.
687 LayersMap platform_view_layers;
688
689 auto did_submit = true;
690 auto num_platform_views = composition_order_.size();
691
692 for (size_t i = 0; i < num_platform_views; i++) {
693 int64_t platform_view_id = composition_order_[i];
694 EmbedderViewSlice* slice = slices_[platform_view_id].get();
695 slice->end_recording();
696
697 // Check if the current picture contains overlays that intersect with the
698 // current platform view or any of the previous platform views.
699 for (size_t j = i + 1; j > 0; j--) {
700 int64_t current_platform_view_id = composition_order_[j - 1];
701 SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
702 std::list<SkRect> intersection_rects =
703 slice->searchNonOverlappingDrawnRects(platform_view_rect);
704 auto allocation_size = intersection_rects.size();
705
706 // For testing purposes, the overlay id is used to find the overlay view.
707 // This is the index of the layer for the current platform view.
708 auto overlay_id = platform_view_layers[current_platform_view_id].size();
709
710 // If the max number of allocations per platform view is exceeded,
711 // then join all the rects into a single one.
712 //
713 // TODO(egarciad): Consider making this configurable.
714 // https://github.com/flutter/flutter/issues/52510
715 if (allocation_size > kMaxLayerAllocations) {
716 SkRect joined_rect = SkRect::MakeEmpty();
717 for (const SkRect& rect : intersection_rects) {
718 joined_rect.join(rect);
719 }
720 // Replace the rects in the intersection rects list for a single rect that is
721 // the union of all the rects in the list.
722 intersection_rects.clear();
723 intersection_rects.push_back(joined_rect);
724 }
725 for (SkRect& joined_rect : intersection_rects) {
726 // Get the intersection rect between the current rect
727 // and the platform view rect.
728 joined_rect.intersect(platform_view_rect);
729 // Subpixels in the platform may not align with the canvas subpixels.
730 // To workaround it, round the floating point bounds and make the rect slightly larger.
731 // For example, {0.3, 0.5, 3.1, 4.7} becomes {0, 0, 4, 5}.
732 joined_rect.setLTRB(std::floor(joined_rect.left()), std::floor(joined_rect.top()),
733 std::ceil(joined_rect.right()), std::ceil(joined_rect.bottom()));
734 // Clip the background canvas, so it doesn't contain any of the pixels drawn
735 // on the overlay layer.
736 background_canvas->ClipRect(joined_rect, DlCanvas::ClipOp::kDifference);
737 // Get a new host layer.
738 std::shared_ptr<FlutterPlatformViewLayer> layer = GetLayer(gr_context, //
739 ios_context, //
740 slice, //
741 joined_rect, //
742 current_platform_view_id, //
743 overlay_id //
744 );
745 did_submit &= layer->did_submit_last_frame;
746 platform_view_layers[current_platform_view_id].push_back(layer);
747 overlay_id++;
748 }
749 }
750 slice->render_into(background_canvas);
751 }
752
753 // Manually trigger the SkAutoCanvasRestore before we submit the frame
754 save.Restore();
755
756 // If a layer was allocated in the previous frame, but it's not used in the current frame,
757 // then it can be removed from the scene.
758 RemoveUnusedLayers();
759 // Organize the layers by their z indexes.
760 BringLayersIntoView(platform_view_layers);
761 // Mark all layers as available, so they can be used in the next frame.
762 layer_pool_->RecycleLayers();
763
764 did_submit &= frame->Submit();
765
766 // If the frame is submitted with embedded platform views,
767 // there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
768 // If that case, we need to commit the transaction.
769 CommitCATransactionIfNeeded();
770 return did_submit;
771 }

The documentation for this class was generated from the following files:

- shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h
- shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
- shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm

-[flutter::FlutterPlatformViewsController GetPlatformViewByID]
UIView * GetPlatformViewByID(int64_t view_id)
Definition: FlutterPlatformViews.mm:408
FlutterMethodNotImplemented
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
kFlutterClippingMaskViewPoolCapacity
static const NSUInteger kFlutterClippingMaskViewPoolCapacity
Definition: FlutterPlatformViews_Internal.mm:12
-[flutter::FlutterPlatformViewsController GetPlatformViewRect]
SkRect GetPlatformViewRect(int64_t view_id)
Definition: FlutterPlatformViews.mm:652
platform_view
std::unique_ptr< flutter::PlatformViewIOS > platform_view
Definition: FlutterEnginePlatformViewTest.mm:61
FlutterClippingMaskViewPool
Definition: FlutterPlatformViews_Internal.h:59
id
int32_t id
Definition: SemanticsObjectTestMocks.h:20
-[flutter::FlutterPlatformViewsController CancelFrame]
void CancelFrame()
Definition: FlutterPlatformViews.mm:322