Flutter Engine
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
 
(UIView *) - GetPlatformViewByID
 
(PostPrerollResult- PostPrerollAction
 
(std::vector< SkCanvas * >) - GetCurrentCanvases
 
(SkCanvas *) - CompositeEmbeddedView
 
(SkRect) - GetPlatformViewRect
 
(void) - Reset
 
(bool) - SubmitFrame
 
(void) - OnMethodCall
 

Detailed Description

Definition at line 125 of file FlutterPlatformViews_Internal.h.

Constructor & Destructor Documentation

◆ FlutterPlatformViewsController()

- FlutterPlatformViewsController:

Definition at line 26 of file FlutterPlatformViews_Internal.mm.

References ~FlutterPlatformViewsController.

27  : layer_pool_(std::make_unique<FlutterPlatformViewLayerPool>()),
28  weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)){};

◆ ~FlutterPlatformViewsController()

- FlutterPlatformViewsController:

Method Documentation

◆ BeginFrame()

- (void) FlutterPlatformViewsController: (SkISize)  frame_size

Definition at line 245 of file FlutterPlatformViews.mm.

245  {
246  ResetFrameState();
247  frame_size_ = frame_size;
248 }

◆ CancelFrame()

- (void) FlutterPlatformViewsController:

Definition at line 250 of file FlutterPlatformViews.mm.

250  {
251  ResetFrameState();
252 }

◆ CompositeEmbeddedView()

- (SkCanvas *) FlutterPlatformViewsController: (int)  view_id

Definition at line 422 of file FlutterPlatformViews.mm.

References FML_DCHECK.

422  {
423  // Any UIKit related code has to run on main thread.
424  FML_DCHECK([[NSThread currentThread] isMainThread]);
425  // Do nothing if the view doesn't need to be composited.
426  if (views_to_recomposite_.count(view_id) == 0) {
427  return picture_recorders_[view_id]->getRecordingCanvas();
428  }
429  CompositeWithParams(view_id, current_composition_params_[view_id]);
430  views_to_recomposite_.erase(view_id);
431  return picture_recorders_[view_id]->getRecordingCanvas();
432 }
#define FML_DCHECK(condition)
Definition: logging.h:86

◆ GetCurrentCanvases()

- (vector< SkCanvas * >) flutter:

Definition at line 322 of file FlutterPlatformViews.mm.

References flutter::MutatorsStack::Begin(), flutter::MutatorsStack::Bottom(), flutter::clip_path, flutter::clip_rect, flutter::clip_rrect, flutter::MutatorsStack::End(), flutter::EmbeddedViewParams::finalBoundingRect(), FML_DCHECK, flutter::GetCATransform3DFromSkMatrix(), flutter::EmbeddedViewParams::mutatorsStack(), flutter::opacity, flutter::ResetAnchor(), flutter::EmbeddedViewParams::sizePoints(), flutter::MutatorsStack::Top(), and flutter::transform.

322  {
323  std::vector<SkCanvas*> canvases;
324  for (size_t i = 0; i < composition_order_.size(); i++) {
325  int64_t view_id = composition_order_[i];
326  canvases.push_back(picture_recorders_[view_id]->getRecordingCanvas());
327  }
328  return canvases;
329 }

◆ getFlutterViewController()

- (UIViewController *) FlutterPlatformViewsController:

Definition at line 110 of file FlutterPlatformViews.mm.

110  {
111  return flutter_view_controller_.get();
112 }

◆ GetPlatformViewByID()

- (UIView *) FlutterPlatformViewsController: (int)  view_id

Definition at line 315 of file FlutterPlatformViews.mm.

315  {
316  if (views_.empty()) {
317  return nil;
318  }
319  return [touch_interceptors_[view_id].get() embeddedView];
320 }

◆ GetPlatformViewRect()

- (SkRect) FlutterPlatformViewsController: (int)  view_id

Definition at line 452 of file FlutterPlatformViews.mm.

References platform_view.

452  {
453  UIView* platform_view = GetPlatformViewByID(view_id);
454  UIScreen* screen = [UIScreen mainScreen];
455  CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds
456  toView:flutter_view_];
457  return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale, //
458  platform_view_cgrect.origin.y * screen.scale, //
459  platform_view_cgrect.size.width * screen.scale, //
460  platform_view_cgrect.size.height * screen.scale //
461  );
462 }
std::unique_ptr< flutter::PlatformViewIOS > platform_view

◆ GetWeakPtr()

- (WeakPtr<) flutter:

Definition at line 32 of file FlutterPlatformViews_Internal.mm.

32  {
33  return weak_factory_->GetWeakPtr();
34 }

◆ OnMethodCall()

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

Definition at line 114 of file FlutterPlatformViews.mm.

References args, FlutterStandardTypedData::data, FlutterMethodNotImplemented, platform_view, result, and view.

114  {
115  if ([[call method] isEqualToString:@"create"]) {
116  OnCreate(call, result);
117  } else if ([[call method] isEqualToString:@"dispose"]) {
118  OnDispose(call, result);
119  } else if ([[call method] isEqualToString:@"acceptGesture"]) {
120  OnAcceptGesture(call, result);
121  } else if ([[call method] isEqualToString:@"rejectGesture"]) {
122  OnRejectGesture(call, result);
123  } else {
125  }
126 }
GAsyncResult * result
FLUTTER_DARWIN_EXPORT NSObject const * FlutterMethodNotImplemented

◆ PostPrerollAction()

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

Definition at line 263 of file FlutterPlatformViews.mm.

References fml::RasterThreadMerger::ExtendLeaseTo(), fml::RasterThreadMerger::IsMerged(), flutter::kSkipAndRetryFrame, flutter::kSuccess, and fml::RasterThreadMerger::MergeWithLease().

264  {
265  // TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474
266  // Rename `has_platform_view` to `view_mutated` when the above issue is resolved.
267  if (!HasPlatformViewThisOrNextFrame()) {
269  }
270  if (!raster_thread_merger->IsMerged()) {
271  // The raster thread merger may be disabled if the rasterizer is being
272  // created or teared down.
273  //
274  // In such cases, the current frame is dropped, and a new frame is attempted
275  // with the same layer tree.
276  //
277  // Eventually, the frame is submitted once this method returns `kSuccess`.
278  // At that point, the raster tasks are handled on the platform thread.
279  CancelFrame();
280  raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
282  }
283  // If the post preroll action is successful, we will display platform views in the current frame.
284  // In order to sync the rendering of the platform views (quartz) with skia's rendering,
285  // We need to begin an explicit CATransaction. This transaction needs to be submitted
286  // after the current frame is submitted.
287  BeginCATransaction();
288  raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
290 }
void MergeWithLease(size_t lease_term)
void ExtendLeaseTo(size_t lease_term)

◆ PrerollCompositeEmbeddedView()

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

Definition at line 292 of file FlutterPlatformViews.mm.

References FML_DCHECK.

294  {
295  // All the CATransactions should be committed by the end of the last frame,
296  // so catransaction_added_ must be false.
297  FML_DCHECK(!catransaction_added_);
298  picture_recorders_[view_id] = std::make_unique<SkPictureRecorder>();
299 
300  auto rtree_factory = RTreeFactory();
301  platform_view_rtrees_[view_id] = rtree_factory.getInstance();
302  picture_recorders_[view_id]->beginRecording(SkRect::Make(frame_size_), &rtree_factory);
303 
304  composition_order_.push_back(view_id);
305 
306  if (current_composition_params_.count(view_id) == 1 &&
307  current_composition_params_[view_id] == *params.get()) {
308  // Do nothing if the params didn't change.
309  return;
310  }
311  current_composition_params_[view_id] = EmbeddedViewParams(*params.get());
312  views_to_recomposite_.insert(view_id);
313 }
#define FML_DCHECK(condition)
Definition: logging.h:86

◆ RegisterViewFactory()

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

Definition at line 234 of file FlutterPlatformViews.mm.

References FML_CHECK.

237  {
238  std::string idString([factoryId UTF8String]);
239  FML_CHECK(factories_.count(idString) == 0);
240  factories_[idString] =
242  gesture_recognizers_blocking_policies[idString] = gestureRecognizerBlockingPolicy;
243 }
#define FML_CHECK(condition)
Definition: logging.h:68

◆ Reset()

- (void) FlutterPlatformViewsController:

Definition at line 434 of file FlutterPlatformViews.mm.

434  {
435  UIView* flutter_view = flutter_view_.get();
436  for (UIView* sub_view in [flutter_view subviews]) {
437  [sub_view removeFromSuperview];
438  }
439  root_views_.clear();
440  touch_interceptors_.clear();
441  views_.clear();
442  composition_order_.clear();
443  active_composition_order_.clear();
444  picture_recorders_.clear();
445  platform_view_rtrees_.clear();
446  current_composition_params_.clear();
447  clip_count_.clear();
448  views_to_recomposite_.clear();
449  layer_pool_->RecycleLayers();
450 }

◆ SetFlutterView()

- (void) FlutterPlatformViewsController: (UIView *)  flutter_view

Definition at line 101 of file FlutterPlatformViews.mm.

101  {
102  flutter_view_.reset([flutter_view retain]);
103 }
void reset(NST object=nil)

◆ SetFlutterViewController()

- (void) FlutterPlatformViewsController: (UIViewController *)  flutter_view_controller

Definition at line 105 of file FlutterPlatformViews.mm.

106  {
107  flutter_view_controller_.reset([flutter_view_controller retain]);
108 }
void reset(NST object=nil)

◆ SubmitFrame()

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

Definition at line 464 of file FlutterPlatformViews.mm.

References FML_DCHECK, and flutter::FlutterPlatformViewLayerPool::GetLayer.

466  {
467  // Any UIKit related code has to run on main thread.
468  FML_DCHECK([[NSThread currentThread] isMainThread]);
469  if (flutter_view_ == nullptr) {
470  return frame->Submit();
471  }
472 
473  DisposeViews();
474 
475  SkCanvas* background_canvas = frame->SkiaCanvas();
476 
477  // Resolve all pending GPU operations before allocating a new surface.
478  background_canvas->flush();
479  // Clipping the background canvas before drawing the picture recorders requires to
480  // save and restore the clip context.
481  SkAutoCanvasRestore save(background_canvas, /*doSave=*/true);
482  // Maps a platform view id to a vector of `FlutterPlatformViewLayer`.
483  LayersMap platform_view_layers;
484 
485  auto did_submit = true;
486  auto num_platform_views = composition_order_.size();
487 
488  for (size_t i = 0; i < num_platform_views; i++) {
489  int64_t platform_view_id = composition_order_[i];
490  sk_sp<RTree> rtree = platform_view_rtrees_[platform_view_id];
491  sk_sp<SkPicture> picture = picture_recorders_[platform_view_id]->finishRecordingAsPicture();
492 
493  // Check if the current picture contains overlays that intersect with the
494  // current platform view or any of the previous platform views.
495  for (size_t j = i + 1; j > 0; j--) {
496  int64_t current_platform_view_id = composition_order_[j - 1];
497  SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
498  std::list<SkRect> intersection_rects =
499  rtree->searchNonOverlappingDrawnRects(platform_view_rect);
500  auto allocation_size = intersection_rects.size();
501 
502  // For testing purposes, the overlay id is used to find the overlay view.
503  // This is the index of the layer for the current platform view.
504  auto overlay_id = platform_view_layers[current_platform_view_id].size();
505 
506  // If the max number of allocations per platform view is exceeded,
507  // then join all the rects into a single one.
508  //
509  // TODO(egarciad): Consider making this configurable.
510  // https://github.com/flutter/flutter/issues/52510
511  if (allocation_size > kMaxLayerAllocations) {
512  SkRect joined_rect;
513  for (const SkRect& rect : intersection_rects) {
514  joined_rect.join(rect);
515  }
516  // Replace the rects in the intersection rects list for a single rect that is
517  // the union of all the rects in the list.
518  intersection_rects.clear();
519  intersection_rects.push_back(joined_rect);
520  }
521  for (SkRect& joined_rect : intersection_rects) {
522  // Get the intersection rect between the current rect
523  // and the platform view rect.
524  joined_rect.intersect(platform_view_rect);
525  // Subpixels in the platform may not align with the canvas subpixels.
526  // To workaround it, round the floating point bounds and make the rect slightly larger.
527  // For example, {0.3, 0.5, 3.1, 4.7} becomes {0, 0, 4, 5}.
528  joined_rect.setLTRB(std::floor(joined_rect.left()), std::floor(joined_rect.top()),
529  std::ceil(joined_rect.right()), std::ceil(joined_rect.bottom()));
530  // Clip the background canvas, so it doesn't contain any of the pixels drawn
531  // on the overlay layer.
532  background_canvas->clipRect(joined_rect, SkClipOp::kDifference);
533  // Get a new host layer.
534  std::shared_ptr<FlutterPlatformViewLayer> layer = GetLayer(gr_context, //
535  ios_context, //
536  picture, //
537  joined_rect, //
538  current_platform_view_id, //
539  overlay_id //
540  );
541  did_submit &= layer->did_submit_last_frame;
542  platform_view_layers[current_platform_view_id].push_back(layer);
543  overlay_id++;
544  }
545  }
546  background_canvas->drawPicture(picture);
547  }
548  // If a layer was allocated in the previous frame, but it's not used in the current frame,
549  // then it can be removed from the scene.
550  RemoveUnusedLayers();
551  // Organize the layers by their z indexes.
552  BringLayersIntoView(platform_view_layers);
553  // Mark all layers as available, so they can be used in the next frame.
554  layer_pool_->RecycleLayers();
555 
556  did_submit &= frame->Submit();
557 
558  // If the frame is submitted with embedded platform views,
559  // there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
560  // If that case, we need to commit the transaction.
561  CommitCATransactionIfNeeded();
562  return did_submit;
563 }
#define FML_DCHECK(condition)
Definition: logging.h:86

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