diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h index aad527a3785df..8d2e5c6b33ed8 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h @@ -7,6 +7,7 @@ #include #include +#include #include "flutter/fml/macros.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h" @@ -34,9 +35,9 @@ class FlutterCompositor { // The view_provider is used to query FlutterViews from view IDs, // which are used for presenting and creating backing stores. // It must not be null, and is typically FlutterViewEngineProvider. - explicit FlutterCompositor(id view_provider, - FlutterTimeConverter* time_converter, - FlutterPlatformViewController* platform_views_controller); + FlutterCompositor(id view_provider, + FlutterTimeConverter* time_converter, + FlutterPlatformViewController* platform_views_controller); ~FlutterCompositor() = default; @@ -56,19 +57,34 @@ class FlutterCompositor { FlutterBackingStore* backing_store_out); // Presents the FlutterLayers by updating the FlutterView specified by - // `view_id` using the layer content. Sets frame_started_ to false. + // `view_id` using the layer content. bool Present(FlutterViewId view_id, const FlutterLayer** layers, size_t layers_count); private: - void PresentPlatformViews(FlutterView* default_base_view, - const std::vector& platform_views_layers); - - // Presents the platform view layer represented by `layer`. `layer_index` is - // used to position the layer in the z-axis. If the layer does not have a - // superview, it will become subview of `default_base_view`. - FlutterMutatorView* PresentPlatformView(FlutterView* default_base_view, - const PlatformViewLayer& layer, - size_t index); + // A class that contains the information for a view to be presented. + class ViewPresenter { + public: + ViewPresenter(); + + void PresentPlatformViews(FlutterView* default_base_view, + const std::vector& platform_views, + const FlutterPlatformViewController* platform_views_controller); + + private: + // Platform view to FlutterMutatorView that contains it. + NSMapTable* mutator_views_; + + // Presents the platform view layer represented by `layer`. `layer_index` is + // used to position the layer in the z-axis. If the layer does not have a + // superview, it will become subview of `default_base_view`. + FlutterMutatorView* PresentPlatformView( + FlutterView* default_base_view, + const PlatformViewLayer& layer, + size_t layer_position, + const FlutterPlatformViewController* platform_views_controller); + + FML_DISALLOW_COPY_AND_ASSIGN(ViewPresenter); + }; // Where the compositor can query FlutterViews. Must not be null. id const view_provider_; @@ -79,8 +95,7 @@ class FlutterCompositor { // The controller used to manage creation and deletion of platform views. const FlutterPlatformViewController* platform_view_controller_; - // Platform view to FlutterMutatorView that contains it. - NSMapTable* mutator_views_; + std::unordered_map presenters_; FML_DISALLOW_COPY_AND_ASSIGN(FlutterCompositor); }; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm index 890a4c0cfca3b..e7749ca0e539b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm @@ -27,8 +27,7 @@ FlutterPlatformViewController* platform_view_controller) : view_provider_(view_provider), time_converter_(time_converter), - platform_view_controller_(platform_view_controller), - mutator_views_([NSMapTable strongToStrongObjectsMapTable]) { + platform_view_controller_(platform_view_controller) { FML_CHECK(view_provider != nullptr) << "view_provider cannot be nullptr"; } @@ -55,6 +54,10 @@ bool FlutterCompositor::Present(FlutterViewId view_id, const FlutterLayer** layers, size_t layers_count) { + // TODO(dkwingsmt): The macOS embedder only supports rendering to the implicit + // view for now. As it supports adding more views, this assertion should be + // lifted. https://github.com/flutter/flutter/issues/142845 + FML_DCHECK(view_id == kFlutterImplicitViewId); FlutterView* view = [view_provider_ viewForId:view_id]; if (!view) { return false; @@ -98,15 +101,22 @@ [view.surfaceManager presentSurfaces:surfaces atTime:presentation_time notify:^{ - PresentPlatformViews(view, *platform_views_layers); + // Gets a presenter or create a new one for the view. + ViewPresenter& presenter = presenters_[view_id]; + presenter.PresentPlatformViews(view, *platform_views_layers, + platform_view_controller_); }]; return true; } -void FlutterCompositor::PresentPlatformViews( +FlutterCompositor::ViewPresenter::ViewPresenter() + : mutator_views_([NSMapTable strongToStrongObjectsMapTable]) {} + +void FlutterCompositor::ViewPresenter::PresentPlatformViews( FlutterView* default_base_view, - const std::vector& platform_views) { + const std::vector& platform_views, + const FlutterPlatformViewController* platform_view_controller) { FML_DCHECK([[NSThread currentThread] isMainThread]) << "Must be on the main thread to present platform views"; @@ -114,8 +124,9 @@ NSMutableArray* present_mutators = [NSMutableArray array]; for (const auto& platform_view : platform_views) { - [present_mutators addObject:PresentPlatformView(default_base_view, platform_view.first, - platform_view.second)]; + FlutterMutatorView* container = PresentPlatformView( + default_base_view, platform_view.first, platform_view.second, platform_view_controller); + [present_mutators addObject:container]; } NSMutableArray* obsolete_mutators = @@ -127,17 +138,19 @@ [mutator removeFromSuperview]; } - [platform_view_controller_ disposePlatformViews]; + [platform_view_controller disposePlatformViews]; } -FlutterMutatorView* FlutterCompositor::PresentPlatformView(FlutterView* default_base_view, - const PlatformViewLayer& layer, - size_t index) { +FlutterMutatorView* FlutterCompositor::ViewPresenter::PresentPlatformView( + FlutterView* default_base_view, + const PlatformViewLayer& layer, + size_t index, + const FlutterPlatformViewController* platform_view_controller) { FML_DCHECK([[NSThread currentThread] isMainThread]) << "Must be on the main thread to present platform views"; int64_t platform_view_id = layer.identifier(); - NSView* platform_view = [platform_view_controller_ platformViewWithID:platform_view_id]; + NSView* platform_view = [platform_view_controller platformViewWithID:platform_view_id]; FML_DCHECK(platform_view) << "Platform view not found for id: " << platform_view_id;