Flutter Engine
The Flutter Engine
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< FlutterViewResponder > *) - 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 205 of file FlutterPlatformViews_Internal.h.

Constructor & Destructor Documentation

◆ FlutterPlatformViewsController

- FlutterPlatformViewsController:

Definition at line 30 of file FlutterPlatformViews_Internal.mm.

31 : layer_pool_(std::make_unique<FlutterPlatformViewLayerPool>()),
32 weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)) {
33 mask_view_pool_.reset(
35};
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity
void reset(NST *object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)

◆ ~FlutterPlatformViewsController

- FlutterPlatformViewsController:

Method Documentation

◆ BeginFrame

- (void) FlutterPlatformViewsController: (SkISize frame_size

Definition at line 314 of file FlutterPlatformViews.mm.

314 {
315 ResetFrameState();
316 frame_size_ = frame_size;
317}

◆ CancelFrame

- (void) FlutterPlatformViewsController:

Definition at line 319 of file FlutterPlatformViews.mm.

319 {
320 ResetFrameState();
321}

◆ CompositeEmbeddedView

- (DlCanvas *) FlutterPlatformViewsController: (int64_t)  view_id

Definition at line 618 of file FlutterPlatformViews.mm.

618 {
619 // Any UIKit related code has to run on main thread.
620 FML_DCHECK([[NSThread currentThread] isMainThread]);
621 // Do nothing if the view doesn't need to be composited.
622 if (views_to_recomposite_.count(view_id) == 0) {
623 return slices_[view_id]->canvas();
624 }
625 CompositeWithParams(view_id, current_composition_params_[view_id]);
626 views_to_recomposite_.erase(view_id);
627 return slices_[view_id]->canvas();
628}
#define FML_DCHECK(condition)
Definition: logging.h:103

◆ EmbeddedViewCount

- (size_t) FlutterPlatformViewsController:

Definition at line 401 of file FlutterPlatformViews.mm.

401 {
402 return composition_order_.size();
403}

◆ EndFrame

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

Definition at line 360 of file FlutterPlatformViews.mm.

362 {
363 if (should_resubmit_frame) {
364 raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
365 }
366}
void MergeWithLease(size_t lease_term)

◆ FindFirstResponderPlatformViewId

- (long) FlutterPlatformViewsController:

Definition at line 417 of file FlutterPlatformViews.mm.

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

◆ GetFlutterTouchInterceptingViewByID

- (FlutterTouchInterceptingView *) FlutterPlatformViewsController: (int64_t)  view_id

Definition at line 409 of file FlutterPlatformViews.mm.

410 {
411 if (views_.empty()) {
412 return nil;
413 }
414 return touch_interceptors_[view_id].get();
415}

◆ getFlutterViewController

- (UIViewController< FlutterViewResponder > *) 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 405 of file FlutterPlatformViews.mm.

405 {
406 return [GetFlutterTouchInterceptingViewByID(view_id) embeddedView];
407}

◆ GetPlatformViewRect

- (SkRect) FlutterPlatformViewsController: (int64_t)  view_id

Definition at line 648 of file FlutterPlatformViews.mm.

648 {
649 UIView* platform_view = GetPlatformViewByID(view_id);
650 UIScreen* screen = [UIScreen mainScreen];
651 CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds
652 toView:flutter_view_];
653 return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale, //
654 platform_view_cgrect.origin.y * screen.scale, //
655 platform_view_cgrect.size.width * screen.scale, //
656 platform_view_cgrect.size.height * screen.scale //
657 );
658}
std::unique_ptr< flutter::PlatformViewIOS > platform_view
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ GetWeakPtr

- (WeakPtr<) flutter:

Definition at line 39 of file FlutterPlatformViews_Internal.mm.

39 {
40 return weak_factory_->GetWeakPtr();
41}

◆ 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 {
187 }
188}
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented
GAsyncResult * result
def call(args)
Definition: dom.py:159

◆ PostPrerollAction

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

Definition at line 332 of file FlutterPlatformViews.mm.

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

◆ PrerollCompositeEmbeddedView

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

Definition at line 378 of file FlutterPlatformViews.mm.

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

◆ PushFilterToVisitedPlatformViews

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

Definition at line 368 of file FlutterPlatformViews.mm.

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

◆ PushVisitedPlatformView

- (void) FlutterPlatformViewsController: (int64_t)  view_id

Definition at line 284 of file FlutterPlatformViews_Internal.h.

284{ visited_platform_views_.push_back(view_id); }

◆ RegisterViewFactory

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

Definition at line 304 of file FlutterPlatformViews.mm.

307 {
308 std::string idString([factoryId UTF8String]);
309 FML_CHECK(factories_.count(idString) == 0);
310 factories_[idString] = fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>(factory);
311 gesture_recognizers_blocking_policies_[idString] = gestureRecognizerBlockingPolicy;
312}
#define FML_CHECK(condition)
Definition: logging.h:85

◆ Reset

- (void) FlutterPlatformViewsController:

Definition at line 630 of file FlutterPlatformViews.mm.

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

◆ SetFlutterView

- (void) FlutterPlatformViewsController: (UIView *)  flutter_view

Definition at line 163 of file FlutterPlatformViews.mm.

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

◆ SetFlutterViewController

- (void) FlutterPlatformViewsController: (UIViewController< FlutterViewResponder > *)  flutter_view_controller

Definition at line 167 of file FlutterPlatformViews.mm.

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

◆ SubmitFrame

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

Definition at line 660 of file FlutterPlatformViews.mm.

662 {
663 TRACE_EVENT0("flutter", "FlutterPlatformViewsController::SubmitFrame");
664
665 // Any UIKit related code has to run on main thread.
666 FML_DCHECK([[NSThread currentThread] isMainThread]);
667 if (flutter_view_ == nullptr) {
668 return frame->Submit();
669 }
670
671 DisposeViews();
672
673 DlCanvas* background_canvas = frame->Canvas();
674
675 // Resolve all pending GPU operations before allocating a new surface.
676 background_canvas->Flush();
677
678 // Clipping the background canvas before drawing the picture recorders requires
679 // saving and restoring the clip context.
680 DlAutoCanvasRestore save(background_canvas, /*do_save=*/true);
681
682 // Maps a platform view id to a vector of `FlutterPlatformViewLayer`.
683 LayersMap platform_view_layers;
684
685 auto did_submit = true;
686 auto num_platform_views = composition_order_.size();
687
688 // TODO(hellohuanlin) this double for-loop is expensive with wasted computations.
689 // See: https://github.com/flutter/flutter/issues/145802
690 for (size_t i = 0; i < num_platform_views; i++) {
691 int64_t platform_view_id = composition_order_[i];
692 EmbedderViewSlice* slice = slices_[platform_view_id].get();
693 slice->end_recording();
694
695 // Check if the current picture contains overlays that intersect with the
696 // current platform view or any of the previous platform views.
697 for (size_t j = i + 1; j > 0; j--) {
698 int64_t current_platform_view_id = composition_order_[j - 1];
699 SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
700 std::vector<SkIRect> intersection_rects = slice->region(platform_view_rect).getRects();
701 const SkIRect rounded_in_platform_view_rect = platform_view_rect.roundIn();
702 // Ignore intersections of single width/height on the edge of the platform view.
703 // This is to address the following performance issue when interleaving adjacent
704 // platform views and layers:
705 // Since we `roundOut` both platform view rects and the layer rects, as long as
706 // the coordinate is fractional, there will be an intersection of a single pixel width
707 // (or height) after rounding out, even if they do not intersect before rounding out.
708 // We have to round out both platform view rect and the layer rect.
709 // Rounding in platform view rect will result in missing pixel on the intersection edge.
710 // Rounding in layer rect will result in missing pixel on the edge of the layer on top
711 // of the platform view.
712 for (auto it = intersection_rects.begin(); it != intersection_rects.end(); /*no-op*/) {
713 // If intersection_rect does not intersect with the *rounded in* platform
714 // view rect, then the intersection must be a single pixel width (or height) on edge.
715 if (!SkIRect::Intersects(*it, rounded_in_platform_view_rect)) {
716 it = intersection_rects.erase(it);
717 } else {
718 ++it;
719 }
720 }
721
722 auto allocation_size = intersection_rects.size();
723
724 // For testing purposes, the overlay id is used to find the overlay view.
725 // This is the index of the layer for the current platform view.
726 auto overlay_id = platform_view_layers[current_platform_view_id].size();
727
728 // If the max number of allocations per platform view is exceeded,
729 // then join all the rects into a single one.
730 //
731 // TODO(egarciad): Consider making this configurable.
732 // https://github.com/flutter/flutter/issues/52510
733 if (allocation_size > kMaxLayerAllocations) {
734 SkIRect joined_rect = SkIRect::MakeEmpty();
735 for (const SkIRect& rect : intersection_rects) {
736 joined_rect.join(rect);
737 }
738 // Replace the rects in the intersection rects list for a single rect that is
739 // the union of all the rects in the list.
740 intersection_rects.clear();
741 intersection_rects.push_back(joined_rect);
742 }
743 for (SkIRect& joined_rect : intersection_rects) {
744 // Get the intersection rect between the current rect
745 // and the platform view rect.
746 joined_rect.intersect(platform_view_rect.roundOut());
747 // Clip the background canvas, so it doesn't contain any of the pixels drawn
748 // on the overlay layer.
749 background_canvas->ClipRect(SkRect::Make(joined_rect), DlCanvas::ClipOp::kDifference);
750 // Get a new host layer.
751 std::shared_ptr<FlutterPlatformViewLayer> layer =
752 GetLayer(gr_context, //
753 ios_context, //
754 slice, //
755 joined_rect, //
756 current_platform_view_id, //
757 overlay_id, //
758 ((FlutterView*)flutter_view_.get()).pixelFormat //
759 );
760 did_submit &= layer->did_submit_last_frame;
761 platform_view_layers[current_platform_view_id].push_back(layer);
762 overlay_id++;
763 }
764 }
765 slice->render_into(background_canvas);
766 }
767
768 // Manually trigger the SkAutoCanvasRestore before we submit the frame
769 save.Restore();
770
771 // If a layer was allocated in the previous frame, but it's not used in the current frame,
772 // then it can be removed from the scene.
773 RemoveUnusedLayers();
774 // Organize the layers by their z indexes.
775 BringLayersIntoView(platform_view_layers);
776 // Mark all layers as available, so they can be used in the next frame.
777 layer_pool_->RecycleLayers();
778
779 did_submit &= frame->Submit();
780
781 // If the frame is submitted with embedded platform views,
782 // there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
783 // If that case, we need to commit the transaction.
784 CommitCATransactionIfNeeded();
785 return did_submit;
786}
T get() const __attribute((ns_returns_not_retained))
double frame
Definition: examples.cpp:31
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
flutter::DlCanvas DlCanvas
Definition: SkRect.h:32
bool intersect(const SkIRect &r)
Definition: SkRect.h:513
static bool Intersects(const SkIRect &a, const SkIRect &b)
Definition: SkRect.h:535
void join(const SkIRect &r)
Definition: SkRect.cpp:31
static constexpr SkIRect MakeEmpty()
Definition: SkRect.h:45
void roundIn(SkIRect *dst) const
Definition: SkRect.h:1266
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131

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