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) - SetFrameSize
 
(void) - CancelFrame
 
(void) - PrerollCompositeEmbeddedView
 
(NSObject< FlutterPlatformView > *) - GetPlatformViewByID
 
(PostPrerollResult- PostPrerollAction
 
(std::vector< SkCanvas * >) - GetCurrentCanvases
 
(SkCanvas *) - CompositeEmbeddedView
 
(SkRect) - GetPlatformViewRect
 
(void) - Reset
 
(bool) - SubmitFrame
 
(void) - EndFrame
 
(void) - OnMethodCall
 

Detailed Description

Definition at line 124 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

◆ CancelFrame()

- (void) FlutterPlatformViewsController:

Definition at line 248 of file FlutterPlatformViews.mm.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

248  {
249  picture_recorders_.clear();
250  composition_order_.clear();
251 }

◆ CompositeEmbeddedView()

- (SkCanvas *) FlutterPlatformViewsController: (int)  view_id

Definition at line 420 of file FlutterPlatformViews.mm.

References FML_DCHECK.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

420  {
421  FML_DCHECK(flutter_view_);
422  // TODO(amirh): assert that this is running on the platform thread once we support the iOS
423  // embedded views thread configuration.
424 
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

◆ EndFrame()

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

Definition at line 593 of file FlutterPlatformViews.mm.

References FML_DCHECK.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

595  {}

◆ GetCurrentCanvases()

- (vector< SkCanvas * >) flutter:

Definition at line 321 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.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

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

◆ getFlutterViewController()

- (UIViewController *) FlutterPlatformViewsController:

Definition at line 109 of file FlutterPlatformViews.mm.

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

◆ GetPlatformViewByID()

- (NSObject< FlutterPlatformView > *) FlutterPlatformViewsController: (int)  view_id

Definition at line 314 of file FlutterPlatformViews.mm.

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

◆ GetPlatformViewRect()

- (SkRect) FlutterPlatformViewsController: (int)  view_id

Definition at line 450 of file FlutterPlatformViews.mm.

450  {
451  UIView* platform_view = [views_[view_id].get() view];
452  UIScreen* screen = [UIScreen mainScreen];
453  CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds
454  toView:flutter_view_];
455  return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale, //
456  platform_view_cgrect.origin.y * screen.scale, //
457  platform_view_cgrect.size.width * screen.scale, //
458  platform_view_cgrect.size.height * screen.scale //
459  );
460 }

◆ 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 113 of file FlutterPlatformViews.mm.

References args, FlutterStandardTypedData::data, and FlutterMethodNotImplemented.

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

◆ PostPrerollAction()

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

Definition at line 262 of file FlutterPlatformViews.mm.

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

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

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

References FML_DCHECK.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

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

◆ RegisterViewFactory()

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

Definition at line 233 of file FlutterPlatformViews.mm.

References FML_CHECK.

236  {
237  std::string idString([factoryId UTF8String]);
238  FML_CHECK(factories_.count(idString) == 0);
239  factories_[idString] =
241  gesture_recognizers_blocking_policies[idString] = gestureRecognizerBlockingPolicy;
242 }
#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  views_.clear();
440  composition_order_.clear();
441  active_composition_order_.clear();
442  picture_recorders_.clear();
443  platform_view_rtrees_.clear();
444  current_composition_params_.clear();
445  clip_count_.clear();
446  views_to_recomposite_.clear();
447  layer_pool_->RecycleLayers();
448 }

◆ SetFlutterView()

- (void) FlutterPlatformViewsController: (UIView *)  flutter_view

Definition at line 100 of file FlutterPlatformViews.mm.

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

◆ SetFlutterViewController()

- (void) FlutterPlatformViewsController: (UIViewController *)  flutter_view_controller

Definition at line 104 of file FlutterPlatformViews.mm.

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

◆ SetFrameSize()

- (void) FlutterPlatformViewsController: (SkISize)  frame_size

Definition at line 244 of file FlutterPlatformViews.mm.

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

244  {
245  frame_size_ = frame_size;
246 }

◆ SubmitFrame()

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

Definition at line 462 of file FlutterPlatformViews.mm.

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

Referenced by flutter::IOSExternalViewEmbedder::IOSExternalViewEmbedder().

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

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