From d36a55d51220eef1f0ff2c5ffc0dfcda048bf2e5 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 29 Jun 2023 23:26:45 -0700 Subject: [PATCH 01/46] Rebase --- common/settings.h | 4 + lib/ui/dart_ui.cc | 9 +- lib/ui/hooks.dart | 14 +++ lib/ui/natives.dart | 4 + lib/ui/platform_dispatcher.dart | 38 ++++-- lib/ui/window/platform_configuration.cc | 68 ++++++++--- lib/ui/window/platform_configuration.h | 25 +++- lib/ui/window/window.cc | 11 +- lib/ui/window/window.h | 6 +- runtime/runtime_controller.cc | 35 +++++- runtime/runtime_controller.h | 6 +- shell/common/engine.cc | 13 ++- shell/common/engine.h | 6 +- shell/common/engine_unittests.cc | 5 +- shell/common/platform_view.cc | 5 +- shell/common/platform_view.h | 3 +- shell/common/rasterizer.cc | 19 ++- shell/common/rasterizer.h | 15 ++- shell/common/rasterizer_unittests.cc | 49 +++++--- shell/common/shell.cc | 110 ++++++++++++++++-- shell/common/shell.h | 22 +++- shell/common/shell_test.cc | 6 +- .../common/shell_test_platform_view_vulkan.h | 1 + shell/common/shell_unittests.cc | 55 +++++---- .../android/platform_view_android_jni_impl.cc | 5 +- .../ios/framework/Source/FlutterEngine.mm | 4 +- .../Source/FlutterEnginePlatformViewTest.mm | 2 +- .../Source/FlutterPlatformViewsTest.mm | 2 +- .../Source/accessibility_bridge_test.mm | 2 +- shell/platform/embedder/embedder.cc | 9 +- shell/platform/embedder/embedder_engine.cc | 3 +- shell/platform/embedder/embedder_engine.h | 3 +- .../platform_view_embedder_unittests.cc | 4 +- .../fuchsia/flutter/flatland_platform_view.cc | 51 ++++---- .../fuchsia/flutter/gfx_platform_view.cc | 48 ++++---- .../tests/flatland_platform_view_unittest.cc | 1 + shell/testing/tester_main.cc | 4 +- 37 files changed, 506 insertions(+), 161 deletions(-) diff --git a/common/settings.h b/common/settings.h index d9df7e707b172..1a97c2d00c4c9 100644 --- a/common/settings.h +++ b/common/settings.h @@ -224,6 +224,10 @@ struct Settings { // must be available to the application. bool enable_vulkan_validation = false; + // Enable the implicit view, so that the shell should create a view with + // kFlutterImplicitViewId without the platform calling FlutterEngineAddView. + bool enable_implicit_view = true; + // Data set by platform-specific embedders for use in font initialization. uint32_t font_initialization_data = 0; diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 77b126d797346..97fbfae0a0814 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -96,7 +96,6 @@ typedef CanvasPath Path; V(IsolateNameServerNatives::RemovePortNameMapping, 1) \ V(NativeStringAttribute::initLocaleStringAttribute, 4) \ V(NativeStringAttribute::initSpellOutStringAttribute, 3) \ - V(PlatformConfigurationNativeApi::ImplicitViewEnabled, 0) \ V(PlatformConfigurationNativeApi::DefaultRouteName, 0) \ V(PlatformConfigurationNativeApi::ScheduleFrame, 0) \ V(PlatformConfigurationNativeApi::Render, 1) \ @@ -381,6 +380,14 @@ void DartUI::InitForIsolate(const Settings& settings) { Dart_PropagateError(result); } } + + if (settings.enable_implicit_view) { + result = + Dart_SetField(dart_ui, ToDart("_implicitViewEnabled"), Dart_True()); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + } + } } } // namespace flutter diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index c391d273e1e59..f21733f914d7b 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -4,6 +4,20 @@ part of dart.ui; +@pragma('vm:entry-point') +void _addView( + int id, +) { + PlatformDispatcher.instance._addView(id); +} + +@pragma('vm:entry-point') +void _removeView( + int id, +) { + PlatformDispatcher.instance._removeView(id); +} + @pragma('vm:entry-point') void _updateDisplays( List ids, diff --git a/lib/ui/natives.dart b/lib/ui/natives.dart index ed32d16668b12..ed11f11322adb 100644 --- a/lib/ui/natives.dart +++ b/lib/ui/natives.dart @@ -135,3 +135,7 @@ _ScheduleImmediateClosure _getScheduleMicrotaskClosure() => _scheduleMicrotask; // rendering. @pragma('vm:entry-point') bool _impellerEnabled = false; + +// Used internally to indicate whether the platform uses the implicit view. +@pragma('vm:entry-point') +bool _implicitViewEnabled = false; diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 47eb65cab3363..5ad1a60e15c09 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -66,6 +66,8 @@ typedef ErrorCallback = bool Function(Object exception, StackTrace stackTrace); // A gesture setting value that indicates it has not been set by the engine. const double _kUnsetGestureSetting = -1.0; +const int _kImplicitViewId = 0; + // A message channel to receive KeyData from the platform. // // See embedder.cc::kFlutterKeyDataChannel for more information. @@ -116,6 +118,9 @@ class PlatformDispatcher { /// these. Use [instance] to access the singleton. PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; + if (_implicitViewEnabled) { + _doAddView(_kImplicitViewId); + } } /// The [PlatformDispatcher] singleton. @@ -213,10 +218,9 @@ class PlatformDispatcher { /// * [View.of], for accessing the current view. /// * [PlatformDispatcher.views] for a list of all [FlutterView]s provided /// by the platform. - FlutterView? get implicitView => _implicitViewEnabled() ? _views[0] : null; - - @Native(symbol: 'PlatformConfigurationNativeApi::ImplicitViewEnabled') - external static bool _implicitViewEnabled(); + FlutterView? get implicitView { + return _views[_kImplicitViewId]; + } /// A callback that is invoked whenever the [ViewConfiguration] of any of the /// [views] changes. @@ -244,6 +248,28 @@ class PlatformDispatcher { _onMetricsChangedZone = Zone.current; } + FlutterView _createView(int id) { + return FlutterView._(id, this); + } + + void _addView(int id) { + assert(id != _kImplicitViewId, 'The implicit view #$id can not be added.'); + _doAddView(id); + } + + void _doAddView(int id) { + assert(!_views.containsKey(id), 'View ID $id already exists.'); + _views[id] = _createView(id); + _viewConfigurations[id] = const _ViewConfiguration(); + } + + void _removeView(int id) { + assert(id != _kImplicitViewId, 'The implicit view #$id can not be removed.'); + assert(_views.containsKey(id), 'View ID $id does not exist.'); + _views.remove(id); + _viewConfigurations.remove(id); + } + // Called from the engine, via hooks.dart. // // Updates the available displays. @@ -283,9 +309,7 @@ class PlatformDispatcher { ) { final _ViewConfiguration previousConfiguration = _viewConfigurations[id] ?? const _ViewConfiguration(); - if (!_views.containsKey(id)) { - _views[id] = FlutterView._(id, this); - } + _views.putIfAbsent(id, () => _createView(id)); _viewConfigurations[id] = previousConfiguration.copyWith( view: _views[id], devicePixelRatio: devicePixelRatio, diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index b1cd11fad30e7..2ec993a4272fc 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -22,7 +22,7 @@ namespace flutter { namespace { -constexpr int kImplicitViewId = 0; +static constexpr int64_t kFlutterImplicitViewId = 0ll; Dart_Handle ToByteData(const fml::Mapping& buffer) { return tonic::DartByteData::Create(buffer.GetMapping(), buffer.GetSize()); @@ -34,7 +34,11 @@ PlatformConfigurationClient::~PlatformConfigurationClient() {} PlatformConfiguration::PlatformConfiguration( PlatformConfigurationClient* client) - : client_(client) {} + : client_(client) { + if (client_->ImplicitViewEnabled()) { + DoAddView(kFlutterImplicitViewId); + } +} PlatformConfiguration::~PlatformConfiguration() {} @@ -43,6 +47,10 @@ void PlatformConfiguration::DidCreateIsolate() { on_error_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_onError"))); + add_view_.Set(tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_addView"))); + remove_view_.Set(tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_removeView"))); update_displays_.Set( tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_updateDisplays"))); @@ -76,12 +84,46 @@ void PlatformConfiguration::DidCreateIsolate() { report_timings_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_reportTimings"))); - // TODO(loicsharma): This should only be created if the embedder enables the - // implicit view. - // See: https://github.com/flutter/flutter/issues/120306 - windows_.emplace(kImplicitViewId, - std::make_unique( - kImplicitViewId, ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); + library_.Set(tonic::DartState::Current(), + Dart_LookupLibrary(tonic::ToDart("dart:ui"))); +} + +void PlatformConfiguration::AddView(int64_t view_id) { + FML_DCHECK(view_id != kFlutterImplicitViewId); + DoAddView(view_id); +} + +void PlatformConfiguration::DoAddView(int64_t view_id) { + windows_.emplace( + view_id, std::make_unique(library_, view_id, + ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); + if (view_id == kFlutterImplicitViewId) { + return; + } + std::shared_ptr dart_state = add_view_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError( + tonic::DartInvoke(add_view_.Get(), { + tonic::ToDart(view_id), + })); +} + +void PlatformConfiguration::RemoveView(int64_t view_id) { + FML_DCHECK(view_id != kFlutterImplicitViewId); + windows_.erase(view_id); + std::shared_ptr dart_state = + remove_view_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError( + tonic::DartInvoke(remove_view_.Get(), { + tonic::ToDart(view_id), + })); } void PlatformConfiguration::UpdateDisplays( @@ -492,16 +534,6 @@ Dart_Handle PlatformConfigurationNativeApi::ComputePlatformResolvedLocale( return tonic::DartConverter>::ToDart(results); } -Dart_Handle PlatformConfigurationNativeApi::ImplicitViewEnabled() { - UIDartState::ThrowIfUIOperationsProhibited(); - bool enabled = UIDartState::Current() - ->platform_configuration() - ->client() - ->ImplicitViewEnabled(); - - return Dart_NewBoolean(enabled); -} - std::string PlatformConfigurationNativeApi::DefaultRouteName() { UIDartState::ThrowIfUIOperationsProhibited(); return UIDartState::Current() diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index c03f38194bf50..5d099f5a1bc65 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -268,6 +268,10 @@ class PlatformConfiguration final { /// void DidCreateIsolate(); + void AddView(int64_t view_id); + + void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Update the specified display data in the framework. /// @@ -415,7 +419,14 @@ class PlatformConfiguration final { /// /// @return a pointer to the Window. /// - Window* get_window(int window_id) { return windows_[window_id].get(); } + Window* get_window(int window_id) { + auto found = windows_.find(window_id); + if (found != windows_.end()) { + return found->second.get(); + } else { + return nullptr; + } + } //---------------------------------------------------------------------------- /// @brief Responds to a previous platform message to the engine from the @@ -442,6 +453,8 @@ class PlatformConfiguration final { private: PlatformConfigurationClient* client_; tonic::DartPersistentValue on_error_; + tonic::DartPersistentValue add_view_; + tonic::DartPersistentValue remove_view_; tonic::DartPersistentValue update_displays_; tonic::DartPersistentValue update_locales_; tonic::DartPersistentValue update_user_settings_data_; @@ -455,12 +468,20 @@ class PlatformConfiguration final { tonic::DartPersistentValue draw_frame_; tonic::DartPersistentValue report_timings_; + tonic::DartPersistentValue library_; + + // All *actual* views that the app has. + // + // This means that, if implicit view is enabled but the implicit view is + // currently closed, `windows_` will not have an entry for ID 0. std::unordered_map> windows_; // ID starts at 1 because an ID of 0 indicates that no response is expected. int next_response_id_ = 1; std::unordered_map> pending_responses_; + + void DoAddView(int64_t view_id); }; //---------------------------------------------------------------------------- @@ -489,8 +510,6 @@ class PlatformMessageHandlerStorage { //---------------------------------------------------------------------------- class PlatformConfigurationNativeApi { public: - static Dart_Handle ImplicitViewEnabled(); - static std::string DefaultRouteName(); static void ScheduleFrame(); diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc index f3866f2ebc56a..45c8c2693190d 100644 --- a/lib/ui/window/window.cc +++ b/lib/ui/window/window.cc @@ -13,11 +13,12 @@ namespace flutter { -Window::Window(int64_t window_id, ViewportMetrics metrics) - : window_id_(window_id), viewport_metrics_(std::move(metrics)) { - library_.Set(tonic::DartState::Current(), - Dart_LookupLibrary(tonic::ToDart("dart:ui"))); -} +Window::Window(tonic::DartPersistentValue& library, + int64_t window_id, + ViewportMetrics metrics) + : library_(library), + window_id_(window_id), + viewport_metrics_(std::move(metrics)) {} Window::~Window() {} diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h index 95153f6559b7b..67ef8198fe800 100644 --- a/lib/ui/window/window.h +++ b/lib/ui/window/window.h @@ -20,7 +20,9 @@ namespace flutter { class Window final { public: - Window(int64_t window_id, ViewportMetrics metrics); + Window(tonic::DartPersistentValue& library, + int64_t window_id, + ViewportMetrics metrics); ~Window(); @@ -31,7 +33,7 @@ class Window final { void UpdateWindowMetrics(const ViewportMetrics& metrics); private: - tonic::DartPersistentValue library_; + tonic::DartPersistentValue& library_; int64_t window_id_; ViewportMetrics viewport_metrics_; }; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 5ffd02d099139..fb922cb9a8646 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -20,7 +20,7 @@ namespace flutter { -const uint64_t kFlutterDefaultViewId = 0llu; +constexpr uint64_t kFlutterDefaultViewId = 0ll; RuntimeController::RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners) @@ -115,7 +115,10 @@ std::unique_ptr RuntimeController::Clone() const { } bool RuntimeController::FlushRuntimeStateToIsolate() { - return SetViewportMetrics(platform_data_.viewport_metrics) && + // TODO(dkwingsmt): Needs a view ID here (or platform_data should probably + // have multiple view metrics). + return SetViewportMetrics(kFlutterDefaultViewId, + platform_data_.viewport_metrics) && SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && SetAccessibilityFeatures( @@ -125,13 +128,35 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { SetDisplays(platform_data_.displays); } -bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) { +bool RuntimeController::AddView(int64_t view_id) { + if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { + platform_configuration->AddView(view_id); + return true; + } + + return false; +} + +bool RuntimeController::RemoveView(int64_t view_id) { + if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { + platform_configuration->RemoveView(view_id); + return true; + } + + return false; +} + +bool RuntimeController::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { TRACE_EVENT0("flutter", "SetViewportMetrics"); platform_data_.viewport_metrics = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { - platform_configuration->get_window(0)->UpdateWindowMetrics(metrics); - return true; + Window* window = platform_configuration->get_window(view_id); + if (window) { + window->UpdateWindowMetrics(metrics); + return true; + } } return false; diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 1df085262f605..6ecb74d8d277e 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -163,6 +163,10 @@ class RuntimeController : public PlatformConfigurationClient { /// std::unique_ptr Clone() const; + bool AddView(int64_t view_id); + + bool RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Forward the specified viewport metrics to the running isolate. /// If the isolate is not running, these metrics will be saved and @@ -172,7 +176,7 @@ class RuntimeController : public PlatformConfigurationClient { /// /// @return If the window metrics were forwarded to the running isolate. /// - bool SetViewportMetrics(const ViewportMetrics& metrics); + bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Forward the specified display metrics to the running isolate. diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 2c0b22d1863f8..9f50236002241 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -292,8 +292,17 @@ tonic::DartErrorHandleType Engine::GetUIIsolateLastError() { return runtime_controller_->GetLastError(); } -void Engine::SetViewportMetrics(const ViewportMetrics& metrics) { - runtime_controller_->SetViewportMetrics(metrics); +void Engine::AddView(int64_t view_id) { + runtime_controller_->AddView(view_id); +} + +void Engine::RemoveView(int64_t view_id) { + runtime_controller_->RemoveView(view_id); +} + +void Engine::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { + runtime_controller_->SetViewportMetrics(view_id, metrics); ScheduleFrame(); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 1890589729b04..5b1c4ca6a7311 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -676,6 +676,10 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// std::optional GetUIIsolateReturnCode(); + void AddView(int64_t view_id); + + void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Updates the viewport metrics for the currently running Flutter /// application. The viewport metrics detail the size of the @@ -686,7 +690,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// /// @param[in] metrics The metrics /// - void SetViewportMetrics(const ViewportMetrics& metrics); + void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Updates the display metrics for the currently running Flutter diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 5011f266557c8..995c408247ef4 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -21,6 +21,8 @@ namespace flutter { namespace { +constexpr int64_t kDefaultViewId = 0ll; + class MockDelegate : public Engine::Delegate { public: MOCK_METHOD2(OnEngineUpdateSemantics, @@ -330,7 +332,8 @@ TEST_F(EngineTest, SpawnResetsViewportMetrics) { const double kViewHeight = 1024; old_viewport_metrics.physical_width = kViewWidth; old_viewport_metrics.physical_height = kViewHeight; - mock_runtime_controller->SetViewportMetrics(old_viewport_metrics); + mock_runtime_controller->SetViewportMetrics(kDefaultViewId, + old_viewport_metrics); auto engine = std::make_unique( /*delegate=*/delegate_, /*dispatcher_maker=*/dispatcher_maker_, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 7cb0b091d5bcd..77a33bfb76e2a 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -51,8 +51,9 @@ void PlatformView::SetAccessibilityFeatures(int32_t flags) { delegate_.OnPlatformViewSetAccessibilityFeatures(flags); } -void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) { - delegate_.OnPlatformViewSetViewportMetrics(metrics); +void PlatformView::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { + delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics); } void PlatformView::NotifyCreated() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 9ec848e34568d..3e5aab515ccd8 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -112,6 +112,7 @@ class PlatformView { /// @param[in] metrics The updated viewport metrics. /// virtual void OnPlatformViewSetViewportMetrics( + int64_t view_id, const ViewportMetrics& metrics) = 0; //-------------------------------------------------------------------------- @@ -474,7 +475,7 @@ class PlatformView { /// /// @param[in] metrics The updated viewport metrics. /// - void SetViewportMetrics(const ViewportMetrics& metrics); + void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Used by embedders to notify the shell that a platform view diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 163e7aa36e131..16091f9fc0f15 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -36,6 +36,8 @@ namespace flutter { // used within this interval. static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000); +static constexpr int64_t kFlutterDefaultViewId = 0; + Rasterizer::Rasterizer(Delegate& delegate, MakeGpuImageBehavior gpu_image_behavior) : delegate_(delegate), @@ -156,6 +158,18 @@ void Rasterizer::NotifyLowMemoryWarning() const { context->performDeferredCleanup(std::chrono::milliseconds(0)); } +void Rasterizer::AddView(int64_t view_id) { + FML_DCHECK(view_id == kFlutterDefaultViewId); + // TODO(dkwingsmt): Support proper view management after Rasterizer supports + // multi-view. +} + +void Rasterizer::RemoveSurface(int64_t view_id) { + FML_DCHECK(view_id == kFlutterDefaultViewId); + // TODO(dkwingsmt): Support proper view management after Rasterizer supports + // multi-view. +} + std::shared_ptr Rasterizer::GetTextureRegistry() { return compositor_context_->texture_registry(); } @@ -201,11 +215,14 @@ RasterStatus Rasterizer::Draw( RasterStatus raster_status = RasterStatus::kFailed; LayerTreePipeline::Consumer consumer = [&](std::unique_ptr item) { + // TODO(dkwingsmt): Use a proper view ID when Rasterizer supports + // multi-view. + int64_t view_id = kFlutterDefaultViewId; std::unique_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); float device_pixel_ratio = item->device_pixel_ratio; - if (discard_callback(*layer_tree.get())) { + if (discard_callback(view_id, *layer_tree.get())) { raster_status = RasterStatus::kDiscarded; } else { raster_status = DoDraw(std::move(frame_timings_recorder), diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index b17242342c084..898510c1f8007 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -204,6 +204,14 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; + //---------------------------------------------------------------------------- + /// @brief Add a view, implicit or not. + void AddView(int64_t view_id); + + //---------------------------------------------------------------------------- + /// @brief Remove a view, implicit or not. + void RemoveSurface(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Sometimes, it may be necessary to render the same frame again /// without having to wait for the framework to build a whole new @@ -240,7 +248,8 @@ class Rasterizer final : public SnapshotDelegate, std::shared_ptr GetTextureRegistry() override; - using LayerTreeDiscardCallback = std::function; + using LayerTreeDiscardCallback = + std::function; //---------------------------------------------------------------------------- /// @brief Takes the next item from the layer tree pipeline and executes @@ -569,7 +578,9 @@ class Rasterizer final : public SnapshotDelegate, void FireNextFrameCallbackIfPresent(); - static bool NoDiscard(const flutter::LayerTree& layer_tree) { return false; } + static bool NoDiscard(int64_t view_id, const flutter::LayerTree& layer_tree) { + return false; + } static bool ShouldResubmitFrame(const RasterStatus& raster_status); Delegate& delegate_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index daf36364851b1..b550a1265c32a 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -29,6 +29,8 @@ using testing::ReturnRef; namespace flutter { namespace { + +constexpr int64_t kDefaultViewId = 0; constexpr float kDevicePixelRatio = 2.0f; class MockDelegate : public Rasterizer::Delegate { @@ -41,7 +43,6 @@ class MockDelegate : public Rasterizer::Delegate { const fml::RefPtr()); MOCK_CONST_METHOD0(GetIsGpuDisabledSyncSwitch, std::shared_ptr()); - MOCK_METHOD0(CreateSnapshotSurface, std::unique_ptr()); MOCK_CONST_METHOD0(GetSettings, const Settings&()); }; @@ -126,6 +127,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -187,6 +189,7 @@ TEST(RasterizerTest, .Times(1); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -199,7 +202,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -254,6 +257,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -265,7 +269,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -327,6 +331,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -336,7 +341,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); } @@ -401,6 +406,7 @@ TEST(RasterizerTest, .Times(2); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -410,7 +416,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // The Draw() will respectively call BeginFrame(), SubmitFrame() and // EndFrame() one time. @@ -460,7 +466,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -492,6 +498,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -517,7 +524,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); // Always discard the layer tree. - auto discard_callback = [](LayerTree&) { return true; }; + auto discard_callback = [](int64_t, LayerTree&) { return true; }; RasterStatus status = rasterizer->Draw(pipeline, discard_callback); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); @@ -550,6 +557,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); EXPECT_CALL( *external_view_embedder, @@ -561,7 +569,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); @@ -608,6 +616,7 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -619,7 +628,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -666,6 +675,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -677,7 +687,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); @@ -724,6 +734,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -735,7 +746,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); @@ -781,6 +792,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -792,7 +804,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); @@ -837,6 +849,7 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -848,7 +861,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); @@ -917,6 +930,7 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -929,7 +943,7 @@ TEST(RasterizerTest, EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. rasterizer->Draw(pipeline, no_discard); @@ -971,6 +985,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1088,6 +1103,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -1100,7 +1116,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. rasterizer->Draw(pipeline, no_discard); @@ -1169,6 +1185,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); + rasterizer->AddView(kDefaultViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); @@ -1179,7 +1196,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, true); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); }); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 859a2668c3762..d6fc863286bb8 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -775,6 +775,8 @@ DartVM* Shell::GetDartVM() { return &vm_; } +static constexpr int64_t kFlutterDefaultViewId = 0ll; + // |PlatformView::Delegate| void Shell::OnPlatformViewCreated(std::unique_ptr surface) { TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated"); @@ -806,15 +808,20 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { !task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread(); fml::AutoResetWaitableEvent latch; - auto raster_task = - fml::MakeCopyable([&waiting_for_first_frame = waiting_for_first_frame_, - rasterizer = rasterizer_->GetWeakPtr(), // - surface = std::move(surface)]() mutable { + auto raster_task = fml::MakeCopyable( + [&waiting_for_first_frame = waiting_for_first_frame_, // + rasterizer = rasterizer_->GetWeakPtr(), // + surface = std::move(surface), // + enable_implicit_view = settings_.enable_implicit_view // + ]() mutable { if (rasterizer) { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); rasterizer->Setup(std::move(surface)); + if (enable_implicit_view) { + rasterizer->AddView(kFlutterDefaultViewId); + } } waiting_for_first_frame.store(true); @@ -822,6 +829,9 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { auto ui_task = [engine = engine_->GetWeakPtr()] { if (engine) { + // Don't call engine->AddView(implicitView) here, because the runtime has + // not been initialized anyway. The runtime has its own way to initialize + // the implitic view. engine->ScheduleFrame(); } }; @@ -954,7 +964,8 @@ void Shell::OnPlatformViewScheduleFrame() { } // |PlatformView::Delegate| -void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { +void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); @@ -978,15 +989,15 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { }); task_runners_.GetUITaskRunner()->PostTask( - [engine = engine_->GetWeakPtr(), metrics]() { + [engine = engine_->GetWeakPtr(), metrics, view_id]() { if (engine) { - engine->SetViewportMetrics(metrics); + engine->SetViewportMetrics(view_id, metrics); } }); { std::scoped_lock lock(resize_mutex_); - expected_frame_size_ = + expected_frame_sizes_[view_id] = SkISize::Make(metrics.physical_width, metrics.physical_height); device_pixel_ratio_ = metrics.device_pixel_ratio; } @@ -1210,10 +1221,11 @@ void Shell::OnAnimatorUpdateLatestFrameTargetTime( void Shell::OnAnimatorDraw(std::shared_ptr pipeline) { FML_DCHECK(is_setup_); - auto discard_callback = [this](flutter::LayerTree& tree) { + auto discard_callback = [this](int64_t view_id, flutter::LayerTree& tree) { std::scoped_lock lock(resize_mutex_); - return !expected_frame_size_.isEmpty() && - tree.frame_size() != expected_frame_size_; + auto expected_frame_size = ExpectedFrameSize(view_id); + return !expected_frame_size.isEmpty() && + tree.frame_size() != expected_frame_size; }; task_runners_.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( @@ -1966,7 +1978,9 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( response->AddMember("snapshots", snapshots, allocator); - const auto& frame_size = expected_frame_size_; + // TODO(dkwingsmt): Not sure what these fields are supposed to be after + // multi-view. For now it sends the implicit view's dimension as before. + const auto& frame_size = ExpectedFrameSize(kFlutterDefaultViewId); response->AddMember("frame_width", frame_size.width(), allocator); response->AddMember("frame_height", frame_size.height(), allocator); @@ -2022,6 +2036,70 @@ bool Shell::OnServiceProtocolReloadAssetFonts( return true; } +void Shell::AddView(int64_t view_id) { + TRACE_EVENT0("flutter", "Shell::AddView"); + FML_DCHECK(is_setup_); + FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + if (view_id == kFlutterDefaultViewId) { + FML_DLOG(WARNING) + << "Unexpected request to add the implicit view #" + << kFlutterDefaultViewId + << ". This view should never be added. This call is no-op."; + return; + } + + task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // + view_id // + ] { + if (engine) { + engine->AddView(view_id); + } + }); + + task_runners_.GetRasterTaskRunner()->PostTask( + [rasterizer = rasterizer_->GetWeakPtr(), // + view_id // + ]() { + if (rasterizer) { + rasterizer->AddView(view_id); + } + }); +} + +void Shell::RemoveView(int64_t view_id) { + TRACE_EVENT0("flutter", "Shell::RemoveView"); + FML_DCHECK(is_setup_); + FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + if (view_id == kFlutterDefaultViewId) { + FML_DLOG(WARNING) + << "Unexpected request to remove the implicit view #" + << kFlutterDefaultViewId + << ". This view should never be removed. This call is no-op."; + return; + } + + fml::AutoResetWaitableEvent latch; + task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // + view_id // + ] { + if (engine) { + engine->RemoveView(view_id); + } + }); + + task_runners_.GetRasterTaskRunner()->PostTask( + [&latch, // + rasterizer = rasterizer_->GetWeakPtr(), // + view_id // + ]() { + if (rasterizer) { + rasterizer->RemoveSurface(view_id); + } + latch.Signal(); + }); + latch.Wait(); +} + Rasterizer::Screenshot Shell::Screenshot( Rasterizer::ScreenshotType screenshot_type, bool base64_encode) { @@ -2162,4 +2240,12 @@ Shell::GetConcurrentWorkerTaskRunner() const { return vm_->GetConcurrentWorkerTaskRunner(); } +SkISize Shell::ExpectedFrameSize(int64_t view_id) { + auto found = expected_frame_sizes_.find(view_id); + if (found == expected_frame_sizes_.end()) { + return SkISize::MakeEmpty(); + } + return found->second; +} + } // namespace flutter diff --git a/shell/common/shell.h b/shell/common/shell.h index d913c3e9c84a6..8de8b219eb12f 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,6 +298,23 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; + /// @brief Add a non-implicit render surface. The implicit render surface + /// is created in OnPlatformViewCreated. + /// + /// This method returns immediately and does not wait for the tasks + /// on the rasterizer thread and the UI thread to finish. This is + /// because the rasterizer thread can be blocked by the platform + /// thread to render platform views. + /// @param view_id + void AddView(int64_t view_id); + + /// @brief Remove a non-implicit render surface. The implicit render surface + /// should never be removed. + /// + /// This method waits for the tasks on the rasterizer thread and the + /// UI thread to finish before returning. + void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Captures a screenshot and optionally Base64 encodes the data /// of the last layer tree rendered by the rasterizer in this @@ -479,7 +496,7 @@ class Shell final : public PlatformView::Delegate, std::mutex resize_mutex_; // used to discard wrong size layer tree produced during interactive resizing - SkISize expected_frame_size_ = SkISize::MakeEmpty(); + std::unordered_map expected_frame_sizes_; // Used to communicate the right frame bounds via service protocol. double device_pixel_ratio_ = 0.0; @@ -544,6 +561,7 @@ class Shell final : public PlatformView::Delegate, // |PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( + int64_t view_id, const ViewportMetrics& metrics) override; // |PlatformView::Delegate| @@ -740,6 +758,8 @@ class Shell final : public PlatformView::Delegate, // directory. std::unique_ptr RestoreOriginalAssetResolver(); + SkISize ExpectedFrameSize(int64_t view_id); + // For accessing the Shell via the raster thread, necessary for various // rasterizer callbacks. std::unique_ptr> weak_factory_gpu_; diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 5e5d38d2b2b94..b892faefcef84 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -20,6 +20,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0; + ShellTest::ShellTest() : thread_host_("io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::IO | @@ -144,7 +146,7 @@ void ShellTest::SetViewportMetrics(Shell* shell, double width, double height) { shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { if (engine) { - engine->SetViewportMetrics(viewport_metrics); + engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); @@ -186,7 +188,7 @@ void ShellTest::PumpOneFrame(Shell* shell, fml::AutoResetWaitableEvent latch; shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { - engine->SetViewportMetrics(viewport_metrics); + engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 718f7fe6dec06..e617ea3f7f9e2 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -43,6 +43,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |Surface| std::unique_ptr AcquireFrame(const SkISize& size) override; + // |Surface| SkMatrix GetRootTransformation() const override; // |Surface| diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 16abef0dbc0f3..959d9e14a3c1d 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -60,6 +60,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0ll; + using ::testing::_; using ::testing::Return; @@ -74,8 +76,8 @@ class MockPlatformViewDelegate : public PlatformView::Delegate { MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD1(OnPlatformViewSetViewportMetrics, - void(const ViewportMetrics& metrics)); + MOCK_METHOD2(OnPlatformViewSetViewportMetrics, + void(int64_t view_id, const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); @@ -151,6 +153,7 @@ class TestPlatformView : public PlatformView { TestPlatformView(Shell& shell, const TaskRunners& task_runners) : PlatformView(shell, task_runners) {} MOCK_METHOD0(CreateRenderingSurface, std::unique_ptr()); + MOCK_CONST_METHOD0(ImplicitViewEnabled, bool()); }; class MockPlatformMessageHandler : public PlatformMessageHandler { @@ -1637,7 +1640,8 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { RunEngine(shell.get(), std::move(configuration)); PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 100, 100, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 100, 100, 22, 0}); }); // first cache bytes @@ -1666,7 +1670,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 100, 22, 0}); + kDefaultViewId, {1.0, 100, 100, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1675,7 +1679,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 300, 22, 0}); + kDefaultViewId, {1.0, 100, 300, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1686,7 +1690,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { third_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 400, 100, 22, 0}); + kDefaultViewId, {1.0, 400, 100, 22, 0}); }); // first cache bytes + second cache bytes + third cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1695,7 +1699,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { third_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 800, 100, 22, 0}); + kDefaultViewId, {1.0, 800, 100, 22, 0}); }); // max bytes threshold EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1708,7 +1712,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 100, 22, 0}); + kDefaultViewId, {1.0, 100, 100, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1752,7 +1756,8 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1772,7 +1777,8 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 400, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 800, 400, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1789,7 +1795,8 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1816,7 +1823,8 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -2683,6 +2691,7 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &expected_size]() { shell->GetPlatformView()->SetViewportMetrics( + kDefaultViewId, {1.0, static_cast(expected_size.width()), static_cast(expected_size.height()), 22, 0}); }); @@ -2760,8 +2769,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &origin_size]() { shell->GetPlatformView()->SetViewportMetrics( - {1.0, static_cast(origin_size.width()), - static_cast(origin_size.height()), 22, 0}); + kDefaultViewId, {1.0, static_cast(origin_size.width()), + static_cast(origin_size.height()), 22, 0}); }); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -2779,8 +2788,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &new_size, &resize_latch]() { shell->GetPlatformView()->SetViewportMetrics( - {1.0, static_cast(new_size.width()), - static_cast(new_size.height()), 22, 0}); + kDefaultViewId, {1.0, static_cast(new_size.width()), + static_cast(new_size.height()), 22, 0}); resize_latch.Signal(); }); @@ -2843,14 +2852,17 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { RunEngine(shell.get(), std::move(configuration)); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.0, 400, 200, 22, 0}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.8, 0.0, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.8, 0.0, 200, 22, 0}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 0.0, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.8, 400, 0.0, 22, 0}); task_runner->PostTask([&]() { shell->GetPlatformView()->SetViewportMetrics( - {0.8, 400, 200.0, 22, 0}); + kDefaultViewId, {0.8, 400, 200.0, 22, 0}); }); }); }); @@ -2862,7 +2874,8 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { latch.Reset(); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({1.2, 600, 300, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.2, 600, 300, 22, 0}); }); latch.Wait(); ASSERT_EQ(last_device_pixel_ratio, 1.2); diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index c4580bc0562d7..05637727521f8 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,6 +37,8 @@ namespace flutter { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + static fml::jni::ScopedJavaGlobalRef* g_flutter_callback_info_class = nullptr; @@ -338,7 +340,8 @@ static void SetViewportMetrics(JNIEnv* env, 0, // Display ID }; - ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(metrics); + ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics( + kFlutterDefaultViewId, metrics); } static void UpdateDisplayMetrics(JNIEnv* env, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 52e6af116b079..98587ddbec773 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -38,6 +38,8 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" +static constexpr int64_t kFlutterDefaultViewId = 0ll; + /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) { @@ -308,7 +310,7 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(viewportMetrics); + self.platformView->SetViewportMetrics(kFlutterDefaultViewId, viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index e4341a065c2af..0b5526a5341a2 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -24,7 +24,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 974eb31de9f44..bba450217747a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -93,7 +93,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 40995c9111284..283d4fe02decd 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -77,7 +77,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index c9d1ce9866744..6edc43c407696 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -83,6 +83,8 @@ extern const intptr_t kPlatformStrongDillSize; const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1; +static constexpr int64_t kFlutterDefaultViewId = 0; + // A message channel to send platform-independent FlutterKeyData to the // framework. // @@ -1801,6 +1803,9 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, settings.assets_path = args->assets_path; settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false); settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1); + // TODO(dkwingsmt): Add a switch for this to FlutterProjectArgs so that + // platforms can configure whether to use the implicit view. + settings.enable_implicit_view = true; if (!flutter::DartVM::IsRunningPrecompiledCode()) { // Verify the assets path contains Dart 2 kernel assets. @@ -2186,6 +2191,8 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( if (engine == nullptr || flutter_metrics == nullptr) { return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); } + // TODO(dkwingsmt): Use a real view ID when multiview is supported. + int64_t view_id = kFlutterDefaultViewId; flutter::ViewportMetrics metrics; @@ -2227,7 +2234,7 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( } return reinterpret_cast(engine)->SetViewportMetrics( - metrics) + view_id, metrics) ? kSuccess : LOG_EMBEDDER_ERROR(kInvalidArguments, "Viewport metrics were invalid."); diff --git a/shell/platform/embedder/embedder_engine.cc b/shell/platform/embedder/embedder_engine.cc index cc4da738f72fc..b34da8a287f4e 100644 --- a/shell/platform/embedder/embedder_engine.cc +++ b/shell/platform/embedder/embedder_engine.cc @@ -100,6 +100,7 @@ bool EmbedderEngine::NotifyDestroyed() { } bool EmbedderEngine::SetViewportMetrics( + int64_t view_id, const flutter::ViewportMetrics& metrics) { if (!IsValid()) { return false; @@ -109,7 +110,7 @@ bool EmbedderEngine::SetViewportMetrics( if (!platform_view) { return false; } - platform_view->SetViewportMetrics(metrics); + platform_view->SetViewportMetrics(view_id, metrics); return true; } diff --git a/shell/platform/embedder/embedder_engine.h b/shell/platform/embedder/embedder_engine.h index 60d33ba76e652..a587eeb3eaa74 100644 --- a/shell/platform/embedder/embedder_engine.h +++ b/shell/platform/embedder/embedder_engine.h @@ -48,7 +48,8 @@ class EmbedderEngine { bool IsValid() const; - bool SetViewportMetrics(const flutter::ViewportMetrics& metrics); + bool SetViewportMetrics(int64_t view_id, + const flutter::ViewportMetrics& metrics); bool DispatchPointerDataPacket( std::unique_ptr packet); diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index 3e795f1fb530f..d22dc030e7292 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -21,8 +21,8 @@ class MockDelegate : public PlatformView::Delegate { MOCK_METHOD0(OnPlatformViewScheduleFrame, void()); MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD1(OnPlatformViewSetViewportMetrics, - void(const ViewportMetrics& metrics)); + MOCK_METHOD2(OnPlatformViewSetViewportMetrics, + void(int64_t view_id, const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket, diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index cbadf9d47b6e0..e9c55f87f539e 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -8,6 +8,8 @@ namespace flutter_runner { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + FlatlandPlatformView::FlatlandPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -85,30 +87,31 @@ void FlatlandPlatformView::OnGetLayout( float pixel_ratio = view_pixel_ratio_ ? *view_pixel_ratio_ : 1.0f; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(view_logical_size_.value()[0] * - pixel_ratio), // physical_width - std::round(view_logical_size_.value()[1] * - pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - 0, // p_display_id - }); + SetViewportMetrics(kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(view_logical_size_.value()[0] * + pixel_ratio), // physical_width + std::round(view_logical_size_.value()[1] * + pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // p_display_id + }); parent_viewport_watcher_->GetLayout( fit::bind_member(this, &FlatlandPlatformView::OnGetLayout)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index df0e9906caf50..149e91d7135af 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -8,6 +8,8 @@ namespace flutter_runner { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + GfxPlatformView::GfxPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -213,28 +215,30 @@ void GfxPlatformView::OnScenicEvent( metrics_changed) { const float pixel_ratio = *view_pixel_ratio_; const std::array logical_size = *view_logical_size_; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(logical_size[0] * pixel_ratio), // physical_width - std::round(logical_size[1] * pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - 0, // pdisplay_id - }); + SetViewportMetrics( + kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(logical_size[0] * pixel_ratio), // physical_width + std::round(logical_size[1] * pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // pdisplay_id + }); } } diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index 78f6f9588958a..ff4347015eb49 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -89,6 +89,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( + int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 342b4ea7aebe9..a6719ede8ffdf 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -39,6 +39,8 @@ namespace flutter { +static constexpr int64_t kDefaultViewId = 0ll; + class TesterExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override { return nullptr; } @@ -353,7 +355,7 @@ int RunTester(const flutter::Settings& settings, metrics.physical_width = physical_width; metrics.physical_height = physical_height; metrics.display_id = 0; - shell->GetPlatformView()->SetViewportMetrics(metrics); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, metrics); // Run the message loop and wait for the script to do its thing. fml::MessageLoop::GetCurrent().Run(); From 381262114e49e8182178a842261f12cf141d53ba Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 29 Jun 2023 23:41:21 -0700 Subject: [PATCH 02/46] Rename vars and fix fuchsia compile --- lib/ui/window/platform_configuration.h | 5 +--- runtime/runtime_controller.cc | 6 ++-- shell/common/rasterizer.cc | 8 +++--- shell/common/shell.cc | 14 +++++----- shell/common/shell.h | 13 ++++++--- .../android/platform_view_android_jni_impl.cc | 4 +-- .../ios/framework/Source/FlutterEngine.mm | 4 +-- .../framework/Source/FlutterCompositor.mm | 2 +- .../framework/Source/FlutterCompositorTest.mm | 4 +-- .../macos/framework/Source/FlutterEngine.mm | 28 +++++++++---------- .../framework/Source/FlutterEngine_Internal.h | 2 +- .../macos/framework/Source/FlutterView.h | 2 +- .../Source/FlutterViewEngineProviderTest.mm | 2 +- shell/platform/embedder/embedder.cc | 4 +-- .../fuchsia/flutter/platform_view_unittest.cc | 1 + 15 files changed, 51 insertions(+), 48 deletions(-) diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 5d099f5a1bc65..42095a4de4ec4 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -470,10 +470,7 @@ class PlatformConfiguration final { tonic::DartPersistentValue library_; - // All *actual* views that the app has. - // - // This means that, if implicit view is enabled but the implicit view is - // currently closed, `windows_` will not have an entry for ID 0. + // All current views mapped from view IDs. std::unordered_map> windows_; // ID starts at 1 because an ID of 0 indicates that no response is expected. diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index fb922cb9a8646..6dc2afc76695a 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -20,7 +20,7 @@ namespace flutter { -constexpr uint64_t kFlutterDefaultViewId = 0ll; +constexpr uint64_t kFlutterImplicitViewId = 0ll; RuntimeController::RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners) @@ -117,7 +117,7 @@ std::unique_ptr RuntimeController::Clone() const { bool RuntimeController::FlushRuntimeStateToIsolate() { // TODO(dkwingsmt): Needs a view ID here (or platform_data should probably // have multiple view metrics). - return SetViewportMetrics(kFlutterDefaultViewId, + return SetViewportMetrics(kFlutterImplicitViewId, platform_data_.viewport_metrics) && SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && @@ -345,7 +345,7 @@ void RuntimeController::ScheduleFrame() { // |PlatformConfigurationClient| void RuntimeController::Render(Scene* scene) { // TODO(dkwingsmt): Currently only supports a single window. - int64_t view_id = kFlutterDefaultViewId; + int64_t view_id = kFlutterImplicitViewId; auto window = UIDartState::Current()->platform_configuration()->get_window(view_id); if (window == nullptr) { diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 16091f9fc0f15..1a85db26d95aa 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -36,7 +36,7 @@ namespace flutter { // used within this interval. static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000); -static constexpr int64_t kFlutterDefaultViewId = 0; +static constexpr int64_t kFlutterImplicitViewId = 0; Rasterizer::Rasterizer(Delegate& delegate, MakeGpuImageBehavior gpu_image_behavior) @@ -159,13 +159,13 @@ void Rasterizer::NotifyLowMemoryWarning() const { } void Rasterizer::AddView(int64_t view_id) { - FML_DCHECK(view_id == kFlutterDefaultViewId); + FML_DCHECK(view_id == kFlutterImplicitViewId); // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } void Rasterizer::RemoveSurface(int64_t view_id) { - FML_DCHECK(view_id == kFlutterDefaultViewId); + FML_DCHECK(view_id == kFlutterImplicitViewId); // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } @@ -217,7 +217,7 @@ RasterStatus Rasterizer::Draw( [&](std::unique_ptr item) { // TODO(dkwingsmt): Use a proper view ID when Rasterizer supports // multi-view. - int64_t view_id = kFlutterDefaultViewId; + int64_t view_id = kFlutterImplicitViewId; std::unique_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index d6fc863286bb8..1dc3db615db38 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -775,7 +775,7 @@ DartVM* Shell::GetDartVM() { return &vm_; } -static constexpr int64_t kFlutterDefaultViewId = 0ll; +static constexpr int64_t kFlutterImplicitViewId = 0ll; // |PlatformView::Delegate| void Shell::OnPlatformViewCreated(std::unique_ptr surface) { @@ -820,7 +820,7 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { rasterizer->EnableThreadMergerIfNeeded(); rasterizer->Setup(std::move(surface)); if (enable_implicit_view) { - rasterizer->AddView(kFlutterDefaultViewId); + rasterizer->AddView(kFlutterImplicitViewId); } } @@ -1980,7 +1980,7 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( // TODO(dkwingsmt): Not sure what these fields are supposed to be after // multi-view. For now it sends the implicit view's dimension as before. - const auto& frame_size = ExpectedFrameSize(kFlutterDefaultViewId); + const auto& frame_size = ExpectedFrameSize(kFlutterImplicitViewId); response->AddMember("frame_width", frame_size.width(), allocator); response->AddMember("frame_height", frame_size.height(), allocator); @@ -2040,10 +2040,10 @@ void Shell::AddView(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::AddView"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - if (view_id == kFlutterDefaultViewId) { + if (view_id == kFlutterImplicitViewId) { FML_DLOG(WARNING) << "Unexpected request to add the implicit view #" - << kFlutterDefaultViewId + << kFlutterImplicitViewId << ". This view should never be added. This call is no-op."; return; } @@ -2070,10 +2070,10 @@ void Shell::RemoveView(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::RemoveView"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - if (view_id == kFlutterDefaultViewId) { + if (view_id == kFlutterImplicitViewId) { FML_DLOG(WARNING) << "Unexpected request to remove the implicit view #" - << kFlutterDefaultViewId + << kFlutterImplicitViewId << ". This view should never be removed. This call is no-op."; return; } diff --git a/shell/common/shell.h b/shell/common/shell.h index 8de8b219eb12f..a128caa1f1768 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,21 +298,26 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; - /// @brief Add a non-implicit render surface. The implicit render surface - /// is created in OnPlatformViewCreated. + /// @brief Add a non-implicit view. /// /// This method returns immediately and does not wait for the tasks /// on the rasterizer thread and the UI thread to finish. This is /// because the rasterizer thread can be blocked by the platform /// thread to render platform views. + /// + /// The implicit view is added internally on Shell initialization + /// depending on `Settings.enable_implicit_view`. Trying to add + /// `kFlutterImplicitViewId` is a no-op with warning. /// @param view_id void AddView(int64_t view_id); - /// @brief Remove a non-implicit render surface. The implicit render surface - /// should never be removed. + /// @brief Remove a non-implicit view. /// /// This method waits for the tasks on the rasterizer thread and the /// UI thread to finish before returning. + /// + /// The implicit view should never be removed. Trying to remove + /// `kFlutterImplicitViewId` is a no-op with warning. void RemoveView(int64_t view_id); //---------------------------------------------------------------------------- diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 05637727521f8..72abd446061b0 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,7 +37,7 @@ namespace flutter { -static constexpr int64_t kFlutterDefaultViewId = 0ll; +static constexpr int64_t kFlutterImplicitViewId = 0ll; static fml::jni::ScopedJavaGlobalRef* g_flutter_callback_info_class = nullptr; @@ -341,7 +341,7 @@ static void SetViewportMetrics(JNIEnv* env, }; ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics( - kFlutterDefaultViewId, metrics); + kFlutterImplicitViewId, metrics); } static void UpdateDisplayMetrics(JNIEnv* env, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 98587ddbec773..1130dcccf7efe 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -38,7 +38,7 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" -static constexpr int64_t kFlutterDefaultViewId = 0ll; +static constexpr int64_t kFlutterImplicitViewId = 0ll; /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority @@ -310,7 +310,7 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(kFlutterDefaultViewId, viewportMetrics); + self.platformView->SetViewportMetrics(kFlutterImplicitViewId, viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm index 3da1c44edf0c4..b40234c5b3bc8 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm @@ -22,7 +22,7 @@ // TODO(dkwingsmt): This class only supports single-view for now. As more // classes are gradually converted to multi-view, it should get the view ID // from somewhere. - FlutterView* view = [view_provider_ viewForId:kFlutterDefaultViewId]; + FlutterView* view = [view_provider_ viewForId:kFlutterImplicitViewId]; if (!view) { return false; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm index f7ac37e01be68..18518cee1c5b6 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm @@ -31,7 +31,7 @@ - (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view { } - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { - if (viewId == kFlutterDefaultViewId) { + if (viewId == kFlutterImplicitViewId) { return _defaultView; } return nil; @@ -131,7 +131,7 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { }}; const FlutterLayer* layers_ptr = layers; - macos_compositor->Present(kFlutterDefaultViewId, &layers_ptr, 1); + macos_compositor->Present(kFlutterImplicitViewId, &layers_ptr, 1); ASSERT_EQ(presentedSurfaces.count, 1ul); } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 138ebdc1c6be7..9c0a945e8d99e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -296,7 +296,7 @@ - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine } - (NSView*)view { - return [self viewForId:kFlutterDefaultViewId]; + return [self viewForId:kFlutterImplicitViewId]; } - (NSView*)viewForId:(FlutterViewId)viewId { @@ -422,9 +422,9 @@ - (instancetype)initWithName:(NSString*)labelPrefix [_isResponseValid addObject:@YES]; _terminationHandler = [[FlutterEngineTerminationHandler alloc] initWithEngine:self terminator:nil]; - // kFlutterDefaultViewId is reserved for the default view. + // kFlutterImplicitViewId is reserved for the default view. // All IDs above it are for regular views. - _nextViewId = kFlutterDefaultViewId + 1; + _nextViewId = kFlutterImplicitViewId + 1; _embedderAPI.struct_size = sizeof(FlutterEngineProcTable); FlutterEngineGetProcAddresses(&_embedderAPI); @@ -509,7 +509,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { // only operates on the default view. To support multi-view, we need a // way to pass in the ID (probably through FlutterSemanticsUpdate). FlutterEngine* engine = (__bridge FlutterEngine*)user_data; - [[engine viewControllerForId:kFlutterDefaultViewId] updateSemantics:update]; + [[engine viewControllerForId:kFlutterImplicitViewId] updateSemantics:update]; }; flutterArguments.custom_dart_entrypoint = entrypoint.UTF8String; flutterArguments.shutdown_dart_vm_when_done = true; @@ -645,7 +645,7 @@ - (FlutterViewController*)viewControllerForId:(FlutterViewId)viewId { - (void)setViewController:(FlutterViewController*)controller { FlutterViewController* currentController = - [_viewControllers objectForKey:@(kFlutterDefaultViewId)]; + [_viewControllers objectForKey:@(kFlutterImplicitViewId)]; if (currentController == controller) { // From nil to nil, or from non-nil to the same controller. return; @@ -658,12 +658,12 @@ - (void)setViewController:(FlutterViewController*)controller { @"If you wanted to create an FlutterViewController and set it to an existing engine, " @"you should use FlutterViewController#init(engine:, nibName, bundle:) instead.", controller.engine); - [self registerViewController:controller forId:kFlutterDefaultViewId]; + [self registerViewController:controller forId:kFlutterImplicitViewId]; } else if (currentController != nil && controller == nil) { - NSAssert(currentController.viewId == kFlutterDefaultViewId, + NSAssert(currentController.viewId == kFlutterImplicitViewId, @"The default controller has an unexpected ID %llu", currentController.viewId); // From non-nil to nil. - [self deregisterViewControllerForId:kFlutterDefaultViewId]; + [self deregisterViewControllerForId:kFlutterImplicitViewId]; [self shutDownIfNeeded]; } else { // From non-nil to a different non-nil view controller. @@ -672,12 +672,12 @@ - (void)setViewController:(FlutterViewController*)controller { @"The engine already has a default view controller %@. " @"If you wanted to make the default view render in a different window, " @"you should attach the current view controller to the window instead.", - [_viewControllers objectForKey:@(kFlutterDefaultViewId)]); + [_viewControllers objectForKey:@(kFlutterImplicitViewId)]); } } - (FlutterViewController*)viewController { - return [self viewControllerForId:kFlutterDefaultViewId]; + return [self viewControllerForId:kFlutterImplicitViewId]; } - (FlutterCompositor*)createFlutterCompositor { @@ -707,7 +707,7 @@ - (FlutterCompositor*)createFlutterCompositor { // TODO(dkwingsmt): This callback only supports single-view, therefore it // only operates on the default view. To support multi-view, we need a new // callback that also receives a view ID. - return reinterpret_cast(user_data)->Present(kFlutterDefaultViewId, + return reinterpret_cast(user_data)->Present(kFlutterImplicitViewId, layers, layers_count); }; @@ -725,7 +725,7 @@ - (FlutterCompositor*)createFlutterCompositor { #pragma mark - Framework-internal methods - (void)addViewController:(FlutterViewController*)controller { - [self registerViewController:controller forId:kFlutterDefaultViewId]; + [self registerViewController:controller forId:kFlutterImplicitViewId]; } - (void)removeViewController:(nonnull FlutterViewController*)viewController { @@ -812,7 +812,7 @@ - (nonnull NSString*)executableName { } - (void)updateWindowMetricsForViewController:(FlutterViewController*)viewController { - if (viewController.viewId != kFlutterDefaultViewId) { + if (viewController.viewId != kFlutterImplicitViewId) { // TODO(dkwingsmt): The embedder API only supports single-view for now. As // embedder APIs are converted to multi-view, this method should support any // views. @@ -1078,7 +1078,7 @@ - (void)handleAccessibilityEvent:(NSDictionary*)annotatedEvent { - (void)announceAccessibilityMessage:(NSString*)message withPriority:(NSAccessibilityPriorityLevel)priority { NSAccessibilityPostNotificationWithUserInfo( - [self viewControllerForId:kFlutterDefaultViewId].flutterView, + [self viewControllerForId:kFlutterImplicitViewId].flutterView, NSAccessibilityAnnouncementRequestedNotification, @{NSAccessibilityAnnouncementKey : message, NSAccessibilityPriorityKey : @(priority)}); } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h index 71fe5481cf72b..313ac988846a4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h @@ -115,7 +115,7 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) { * * Practically, since FlutterEngine can only be attached with one controller, * the given controller, if successfully attached, will always have the default - * view ID kFlutterDefaultViewId. + * view ID kFlutterImplicitViewId. * * The engine holds a weak reference to the attached view controller. * diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index 0c468d4c58d08..6948b880fcf9b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -20,7 +20,7 @@ typedef int64_t FlutterViewId; * backward compatibility, single-view APIs will always operate on the view with * this ID. Also, the first view assigned to the engine will also have this ID. */ -constexpr FlutterViewId kFlutterDefaultViewId = 0ll; +constexpr FlutterViewId kFlutterImplicitViewId = 0ll; /** * Listener for view resizing. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderTest.mm index 403639b79e62a..aa14b70fc4b2b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderTest.mm @@ -27,7 +27,7 @@ .andDo(^(NSInvocation* invocation) { FlutterViewId viewId; [invocation getArgument:&viewId atIndex:2]; - if (viewId == kFlutterDefaultViewId) { + if (viewId == kFlutterImplicitViewId) { if (mockFlutterViewController != nil) { [invocation setReturnValue:&mockFlutterViewController]; } diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 6edc43c407696..00c58a9b943ab 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -83,7 +83,7 @@ extern const intptr_t kPlatformStrongDillSize; const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1; -static constexpr int64_t kFlutterDefaultViewId = 0; +static constexpr int64_t kFlutterImplicitViewId = 0; // A message channel to send platform-independent FlutterKeyData to the // framework. @@ -2192,7 +2192,7 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); } // TODO(dkwingsmt): Use a real view ID when multiview is supported. - int64_t view_id = kFlutterDefaultViewId; + int64_t view_id = kFlutterImplicitViewId; flutter::ViewportMetrics metrics; diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index c0aa42e0a5dbf..54a9c7a593f3b 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -90,6 +90,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( + int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } From b1b68eb1eaad009f1cb7fdb0f2195928158d5171 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 5 Jul 2023 08:41:22 -0700 Subject: [PATCH 03/46] Revert window metric changes --- runtime/runtime_controller.cc | 15 ++--- runtime/runtime_controller.h | 2 +- shell/common/engine.cc | 5 +- shell/common/engine.h | 2 +- shell/common/engine_unittests.cc | 5 +- shell/common/platform_view.cc | 5 +- shell/common/platform_view.h | 3 +- shell/common/shell.cc | 10 ++-- shell/common/shell.h | 1 - shell/common/shell_test.cc | 6 +- shell/common/shell_unittests.cc | 55 +++++++------------ .../android/platform_view_android_jni_impl.cc | 5 +- .../ios/framework/Source/FlutterEngine.mm | 4 +- .../Source/FlutterEnginePlatformViewTest.mm | 2 +- .../Source/FlutterPlatformViewsTest.mm | 2 +- .../Source/accessibility_bridge_test.mm | 2 +- shell/platform/embedder/embedder.cc | 6 +- shell/platform/embedder/embedder_engine.cc | 3 +- shell/platform/embedder/embedder_engine.h | 3 +- .../platform_view_embedder_unittests.cc | 4 +- .../fuchsia/flutter/flatland_platform_view.cc | 51 ++++++++--------- .../fuchsia/flutter/gfx_platform_view.cc | 48 ++++++++-------- .../fuchsia/flutter/platform_view_unittest.cc | 1 - .../tests/flatland_platform_view_unittest.cc | 1 - shell/testing/tester_main.cc | 4 +- 25 files changed, 98 insertions(+), 147 deletions(-) diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 6dc2afc76695a..2acc2ae2e1ead 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -115,10 +115,7 @@ std::unique_ptr RuntimeController::Clone() const { } bool RuntimeController::FlushRuntimeStateToIsolate() { - // TODO(dkwingsmt): Needs a view ID here (or platform_data should probably - // have multiple view metrics). - return SetViewportMetrics(kFlutterImplicitViewId, - platform_data_.viewport_metrics) && + return SetViewportMetrics(platform_data_.viewport_metrics) && SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && SetAccessibilityFeatures( @@ -146,17 +143,13 @@ bool RuntimeController::RemoveView(int64_t view_id) { return false; } -bool RuntimeController::SetViewportMetrics(int64_t view_id, - const ViewportMetrics& metrics) { +bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) { TRACE_EVENT0("flutter", "SetViewportMetrics"); platform_data_.viewport_metrics = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { - Window* window = platform_configuration->get_window(view_id); - if (window) { - window->UpdateWindowMetrics(metrics); - return true; - } + platform_configuration->get_window(0)->UpdateWindowMetrics(metrics); + return true; } return false; diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 6ecb74d8d277e..c17b0de1d542d 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -176,7 +176,7 @@ class RuntimeController : public PlatformConfigurationClient { /// /// @return If the window metrics were forwarded to the running isolate. /// - bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); + bool SetViewportMetrics(const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Forward the specified display metrics to the running isolate. diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 9f50236002241..a753be2a940ec 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -300,9 +300,8 @@ void Engine::RemoveView(int64_t view_id) { runtime_controller_->RemoveView(view_id); } -void Engine::SetViewportMetrics(int64_t view_id, - const ViewportMetrics& metrics) { - runtime_controller_->SetViewportMetrics(view_id, metrics); +void Engine::SetViewportMetrics(const ViewportMetrics& metrics) { + runtime_controller_->SetViewportMetrics(metrics); ScheduleFrame(); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 5b1c4ca6a7311..da9a2b145f276 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -690,7 +690,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// /// @param[in] metrics The metrics /// - void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); + void SetViewportMetrics(const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Updates the display metrics for the currently running Flutter diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 995c408247ef4..5011f266557c8 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -21,8 +21,6 @@ namespace flutter { namespace { -constexpr int64_t kDefaultViewId = 0ll; - class MockDelegate : public Engine::Delegate { public: MOCK_METHOD2(OnEngineUpdateSemantics, @@ -332,8 +330,7 @@ TEST_F(EngineTest, SpawnResetsViewportMetrics) { const double kViewHeight = 1024; old_viewport_metrics.physical_width = kViewWidth; old_viewport_metrics.physical_height = kViewHeight; - mock_runtime_controller->SetViewportMetrics(kDefaultViewId, - old_viewport_metrics); + mock_runtime_controller->SetViewportMetrics(old_viewport_metrics); auto engine = std::make_unique( /*delegate=*/delegate_, /*dispatcher_maker=*/dispatcher_maker_, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 77a33bfb76e2a..7cb0b091d5bcd 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -51,9 +51,8 @@ void PlatformView::SetAccessibilityFeatures(int32_t flags) { delegate_.OnPlatformViewSetAccessibilityFeatures(flags); } -void PlatformView::SetViewportMetrics(int64_t view_id, - const ViewportMetrics& metrics) { - delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics); +void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) { + delegate_.OnPlatformViewSetViewportMetrics(metrics); } void PlatformView::NotifyCreated() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 3e5aab515ccd8..9ec848e34568d 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -112,7 +112,6 @@ class PlatformView { /// @param[in] metrics The updated viewport metrics. /// virtual void OnPlatformViewSetViewportMetrics( - int64_t view_id, const ViewportMetrics& metrics) = 0; //-------------------------------------------------------------------------- @@ -475,7 +474,7 @@ class PlatformView { /// /// @param[in] metrics The updated viewport metrics. /// - void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); + void SetViewportMetrics(const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Used by embedders to notify the shell that a platform view diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1dc3db615db38..f0fb841c1bac9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -964,8 +964,7 @@ void Shell::OnPlatformViewScheduleFrame() { } // |PlatformView::Delegate| -void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id, - const ViewportMetrics& metrics) { +void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); @@ -989,13 +988,16 @@ void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id, }); task_runners_.GetUITaskRunner()->PostTask( - [engine = engine_->GetWeakPtr(), metrics, view_id]() { + [engine = engine_->GetWeakPtr(), metrics]() { if (engine) { - engine->SetViewportMetrics(view_id, metrics); + engine->SetViewportMetrics(metrics); } }); { + // TODO(dkwingsmt): Use the correct view ID when this method supports + // multi-view. + int64_t view_id = kFlutterImplicitViewId; std::scoped_lock lock(resize_mutex_); expected_frame_sizes_[view_id] = SkISize::Make(metrics.physical_width, metrics.physical_height); diff --git a/shell/common/shell.h b/shell/common/shell.h index a128caa1f1768..649339c42deed 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -566,7 +566,6 @@ class Shell final : public PlatformView::Delegate, // |PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - int64_t view_id, const ViewportMetrics& metrics) override; // |PlatformView::Delegate| diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index b892faefcef84..5e5d38d2b2b94 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -20,8 +20,6 @@ namespace flutter { namespace testing { -constexpr int64_t kDefaultViewId = 0; - ShellTest::ShellTest() : thread_host_("io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::IO | @@ -146,7 +144,7 @@ void ShellTest::SetViewportMetrics(Shell* shell, double width, double height) { shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { if (engine) { - engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); + engine->SetViewportMetrics(viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); @@ -188,7 +186,7 @@ void ShellTest::PumpOneFrame(Shell* shell, fml::AutoResetWaitableEvent latch; shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { - engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); + engine->SetViewportMetrics(viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 959d9e14a3c1d..16abef0dbc0f3 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -60,8 +60,6 @@ namespace flutter { namespace testing { -constexpr int64_t kDefaultViewId = 0ll; - using ::testing::_; using ::testing::Return; @@ -76,8 +74,8 @@ class MockPlatformViewDelegate : public PlatformView::Delegate { MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD2(OnPlatformViewSetViewportMetrics, - void(int64_t view_id, const ViewportMetrics& metrics)); + MOCK_METHOD1(OnPlatformViewSetViewportMetrics, + void(const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); @@ -153,7 +151,6 @@ class TestPlatformView : public PlatformView { TestPlatformView(Shell& shell, const TaskRunners& task_runners) : PlatformView(shell, task_runners) {} MOCK_METHOD0(CreateRenderingSurface, std::unique_ptr()); - MOCK_CONST_METHOD0(ImplicitViewEnabled, bool()); }; class MockPlatformMessageHandler : public PlatformMessageHandler { @@ -1640,8 +1637,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { RunEngine(shell.get(), std::move(configuration)); PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.0, 100, 100, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.0, 100, 100, 22, 0}); }); // first cache bytes @@ -1670,7 +1666,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, 100, 100, 22, 0}); + {1.0, 100, 100, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1679,7 +1675,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, 100, 300, 22, 0}); + {1.0, 100, 300, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1690,7 +1686,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { third_shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, 400, 100, 22, 0}); + {1.0, 400, 100, 22, 0}); }); // first cache bytes + second cache bytes + third cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1699,7 +1695,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { third_shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, 800, 100, 22, 0}); + {1.0, 800, 100, 22, 0}); }); // max bytes threshold EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1712,7 +1708,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, 100, 100, 22, 0}); + {1.0, 100, 100, 22, 0}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1756,8 +1752,7 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1777,8 +1772,7 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.0, 800, 400, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 400, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1795,8 +1789,7 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -1823,8 +1816,7 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0}); }); PumpOneFrame(shell.get()); @@ -2691,7 +2683,6 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &expected_size]() { shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, static_cast(expected_size.width()), static_cast(expected_size.height()), 22, 0}); }); @@ -2769,8 +2760,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &origin_size]() { shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, static_cast(origin_size.width()), - static_cast(origin_size.height()), 22, 0}); + {1.0, static_cast(origin_size.width()), + static_cast(origin_size.height()), 22, 0}); }); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -2788,8 +2779,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &new_size, &resize_latch]() { shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {1.0, static_cast(new_size.width()), - static_cast(new_size.height()), 22, 0}); + {1.0, static_cast(new_size.width()), + static_cast(new_size.height()), 22, 0}); resize_latch.Signal(); }); @@ -2852,17 +2843,14 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { RunEngine(shell.get(), std::move(configuration)); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {0.0, 400, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({0.0, 400, 200, 22, 0}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {0.8, 0.0, 200, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({0.8, 0.0, 200, 22, 0}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {0.8, 400, 0.0, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 0.0, 22, 0}); task_runner->PostTask([&]() { shell->GetPlatformView()->SetViewportMetrics( - kDefaultViewId, {0.8, 400, 200.0, 22, 0}); + {0.8, 400, 200.0, 22, 0}); }); }); }); @@ -2874,8 +2862,7 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { latch.Reset(); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, - {1.2, 600, 300, 22, 0}); + shell->GetPlatformView()->SetViewportMetrics({1.2, 600, 300, 22, 0}); }); latch.Wait(); ASSERT_EQ(last_device_pixel_ratio, 1.2); diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 72abd446061b0..c4580bc0562d7 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,8 +37,6 @@ namespace flutter { -static constexpr int64_t kFlutterImplicitViewId = 0ll; - static fml::jni::ScopedJavaGlobalRef* g_flutter_callback_info_class = nullptr; @@ -340,8 +338,7 @@ static void SetViewportMetrics(JNIEnv* env, 0, // Display ID }; - ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics( - kFlutterImplicitViewId, metrics); + ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(metrics); } static void UpdateDisplayMetrics(JNIEnv* env, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 1130dcccf7efe..52e6af116b079 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -38,8 +38,6 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" -static constexpr int64_t kFlutterImplicitViewId = 0ll; - /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) { @@ -310,7 +308,7 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(kFlutterImplicitViewId, viewportMetrics); + self.platformView->SetViewportMetrics(viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index 0b5526a5341a2..e4341a065c2af 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -24,7 +24,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index bba450217747a..974eb31de9f44 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -93,7 +93,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 283d4fe02decd..40995c9111284 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -77,7 +77,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 00c58a9b943ab..723efc2c5ab90 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -83,8 +83,6 @@ extern const intptr_t kPlatformStrongDillSize; const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1; -static constexpr int64_t kFlutterImplicitViewId = 0; - // A message channel to send platform-independent FlutterKeyData to the // framework. // @@ -2191,8 +2189,6 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( if (engine == nullptr || flutter_metrics == nullptr) { return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); } - // TODO(dkwingsmt): Use a real view ID when multiview is supported. - int64_t view_id = kFlutterImplicitViewId; flutter::ViewportMetrics metrics; @@ -2234,7 +2230,7 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( } return reinterpret_cast(engine)->SetViewportMetrics( - view_id, metrics) + metrics) ? kSuccess : LOG_EMBEDDER_ERROR(kInvalidArguments, "Viewport metrics were invalid."); diff --git a/shell/platform/embedder/embedder_engine.cc b/shell/platform/embedder/embedder_engine.cc index b34da8a287f4e..cc4da738f72fc 100644 --- a/shell/platform/embedder/embedder_engine.cc +++ b/shell/platform/embedder/embedder_engine.cc @@ -100,7 +100,6 @@ bool EmbedderEngine::NotifyDestroyed() { } bool EmbedderEngine::SetViewportMetrics( - int64_t view_id, const flutter::ViewportMetrics& metrics) { if (!IsValid()) { return false; @@ -110,7 +109,7 @@ bool EmbedderEngine::SetViewportMetrics( if (!platform_view) { return false; } - platform_view->SetViewportMetrics(view_id, metrics); + platform_view->SetViewportMetrics(metrics); return true; } diff --git a/shell/platform/embedder/embedder_engine.h b/shell/platform/embedder/embedder_engine.h index a587eeb3eaa74..60d33ba76e652 100644 --- a/shell/platform/embedder/embedder_engine.h +++ b/shell/platform/embedder/embedder_engine.h @@ -48,8 +48,7 @@ class EmbedderEngine { bool IsValid() const; - bool SetViewportMetrics(int64_t view_id, - const flutter::ViewportMetrics& metrics); + bool SetViewportMetrics(const flutter::ViewportMetrics& metrics); bool DispatchPointerDataPacket( std::unique_ptr packet); diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index d22dc030e7292..3e795f1fb530f 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -21,8 +21,8 @@ class MockDelegate : public PlatformView::Delegate { MOCK_METHOD0(OnPlatformViewScheduleFrame, void()); MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD2(OnPlatformViewSetViewportMetrics, - void(int64_t view_id, const ViewportMetrics& metrics)); + MOCK_METHOD1(OnPlatformViewSetViewportMetrics, + void(const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket, diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index e9c55f87f539e..cbadf9d47b6e0 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -8,8 +8,6 @@ namespace flutter_runner { -static constexpr int64_t kFlutterDefaultViewId = 0ll; - FlatlandPlatformView::FlatlandPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -87,31 +85,30 @@ void FlatlandPlatformView::OnGetLayout( float pixel_ratio = view_pixel_ratio_ ? *view_pixel_ratio_ : 1.0f; - SetViewportMetrics(kFlutterDefaultViewId, - { - pixel_ratio, // device_pixel_ratio - std::round(view_logical_size_.value()[0] * - pixel_ratio), // physical_width - std::round(view_logical_size_.value()[1] * - pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - 0, // p_display_id - }); + SetViewportMetrics({ + pixel_ratio, // device_pixel_ratio + std::round(view_logical_size_.value()[0] * + pixel_ratio), // physical_width + std::round(view_logical_size_.value()[1] * + pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // p_display_id + }); parent_viewport_watcher_->GetLayout( fit::bind_member(this, &FlatlandPlatformView::OnGetLayout)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index 149e91d7135af..df0e9906caf50 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -8,8 +8,6 @@ namespace flutter_runner { -static constexpr int64_t kFlutterDefaultViewId = 0ll; - GfxPlatformView::GfxPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -215,30 +213,28 @@ void GfxPlatformView::OnScenicEvent( metrics_changed) { const float pixel_ratio = *view_pixel_ratio_; const std::array logical_size = *view_logical_size_; - SetViewportMetrics( - kFlutterDefaultViewId, - { - pixel_ratio, // device_pixel_ratio - std::round(logical_size[0] * pixel_ratio), // physical_width - std::round(logical_size[1] * pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - 0, // pdisplay_id - }); + SetViewportMetrics({ + pixel_ratio, // device_pixel_ratio + std::round(logical_size[0] * pixel_ratio), // physical_width + std::round(logical_size[1] * pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // pdisplay_id + }); } } diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 54a9c7a593f3b..c0aa42e0a5dbf 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -90,7 +90,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index ff4347015eb49..78f6f9588958a 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -89,7 +89,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index a6719ede8ffdf..342b4ea7aebe9 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -39,8 +39,6 @@ namespace flutter { -static constexpr int64_t kDefaultViewId = 0ll; - class TesterExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override { return nullptr; } @@ -355,7 +353,7 @@ int RunTester(const flutter::Settings& settings, metrics.physical_width = physical_width; metrics.physical_height = physical_height; metrics.display_id = 0; - shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, metrics); + shell->GetPlatformView()->SetViewportMetrics(metrics); // Run the message loop and wait for the script to do its thing. fml::MessageLoop::GetCurrent().Run(); From 5e036d850707df89f83dd9b50e6b592b62e50064 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 6 Jul 2023 10:26:45 -0700 Subject: [PATCH 04/46] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com> --- lib/ui/hooks.dart | 8 ++------ lib/ui/natives.dart | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index f21733f914d7b..16015c319d44c 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -5,16 +5,12 @@ part of dart.ui; @pragma('vm:entry-point') -void _addView( - int id, -) { +void _addView(int id) { PlatformDispatcher.instance._addView(id); } @pragma('vm:entry-point') -void _removeView( - int id, -) { +void _removeView(int id) { PlatformDispatcher.instance._removeView(id); } diff --git a/lib/ui/natives.dart b/lib/ui/natives.dart index ed11f11322adb..59f54611249a9 100644 --- a/lib/ui/natives.dart +++ b/lib/ui/natives.dart @@ -136,6 +136,6 @@ _ScheduleImmediateClosure _getScheduleMicrotaskClosure() => _scheduleMicrotask; @pragma('vm:entry-point') bool _impellerEnabled = false; -// Used internally to indicate whether the platform uses the implicit view. +// Used internally to indicate whether the embedder enables the implicit view. @pragma('vm:entry-point') bool _implicitViewEnabled = false; From fba2c7ce10e5459f35ff76bc690bc1c04c23c8b6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 6 Jul 2023 12:38:16 -0700 Subject: [PATCH 05/46] Doc enable_implicit_view --- common/settings.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/common/settings.h b/common/settings.h index 1a97c2d00c4c9..4b771607e31cd 100644 --- a/common/settings.h +++ b/common/settings.h @@ -224,8 +224,30 @@ struct Settings { // must be available to the application. bool enable_vulkan_validation = false; - // Enable the implicit view, so that the shell should create a view with - // kFlutterImplicitViewId without the platform calling FlutterEngineAddView. + // Enable the implicit view. + // + // The implicit view is a compatibility mode to help the transition from + // single-view APIs to multi-view APIs, which use different models for views. + // Although single-view APIs will eventually be replaced by their multi-view + // variants, during the deprecation period, the single-view APIs will coexist + // with and work with the multi-view APIs as if the other views don't exist. + // To achieve this, the platform can enable "implicit view", which is a + // special view that keeps all behaviors of "the view" in a legacy + // single-view Flutter app, allowing single-view APIs to continue working, + // while new-style "regular" views created by new ways must be operated by + // multi-view APIs. + // + // If implicit view is disabled, then all views should be created by + // Shell::AddView before being used, and removed by Shell::RemoveView after + // they are gone. + // + // If implicit view is enabled, in addition to the "regular views" as above, + // the shell (including the engine and the dart:ui library) will implicitly + // create a view upon initialization without `Shell::AddView` (hence the + // name). This view will have a view ID of kFlutterImplicitViewId, and + // can never be removed, even if the window that shows the view is closed. + // The caller should adjust accordingly by providing contents and operations + // to the view without calling Shell::AddView or Shell::RemoveView. bool enable_implicit_view = true; // Data set by platform-specific embedders for use in font initialization. From d7c65104d5d8222afd898a7ab5f3d91473f77a7e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 6 Jul 2023 12:52:02 -0700 Subject: [PATCH 06/46] Better platConfig structure for adding window --- lib/ui/window/platform_configuration.cc | 21 +++++++++++---------- lib/ui/window/platform_configuration.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 2ec993a4272fc..048c8a5e45088 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -36,7 +36,11 @@ PlatformConfiguration::PlatformConfiguration( PlatformConfigurationClient* client) : client_(client) { if (client_->ImplicitViewEnabled()) { - DoAddView(kFlutterImplicitViewId); + // Add PlatformConfiguration's window now, but don't add dart:ui's View + // here. The dart:ui needs another way to add the implicit view + // synchronously so that the view is available before the main function. + // See _implicitViewEnabled in natives.dart. + AddWindowRecord(kFlutterImplicitViewId); } } @@ -88,18 +92,15 @@ void PlatformConfiguration::DidCreateIsolate() { Dart_LookupLibrary(tonic::ToDart("dart:ui"))); } -void PlatformConfiguration::AddView(int64_t view_id) { - FML_DCHECK(view_id != kFlutterImplicitViewId); - DoAddView(view_id); -} - -void PlatformConfiguration::DoAddView(int64_t view_id) { +void PlatformConfiguration::AddWindowRecord(int64_t view_id) { windows_.emplace( view_id, std::make_unique(library_, view_id, ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); - if (view_id == kFlutterImplicitViewId) { - return; - } +} + +void PlatformConfiguration::AddView(int64_t view_id) { + FML_DCHECK(view_id != kFlutterImplicitViewId); + AddWindowRecord(view_id); std::shared_ptr dart_state = add_view_.dart_state().lock(); if (!dart_state) { return; diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 42095a4de4ec4..976d48524831c 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -478,7 +478,7 @@ class PlatformConfiguration final { std::unordered_map> pending_responses_; - void DoAddView(int64_t view_id); + void AddWindowRecord(int64_t view_id); }; //---------------------------------------------------------------------------- From 2a87664f6371f77bb579b9d0dd3659dd437cc3b2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 23 Jul 2023 15:48:37 -0700 Subject: [PATCH 07/46] Fix compile --- lib/ui/platform_dispatcher.dart | 4 +--- lib/ui/window/platform_configuration.cc | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index ca70eea7137cb..92cae4c8aaf39 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -257,7 +257,7 @@ class PlatformDispatcher { } FlutterView _createView(int id) { - return FlutterView._(id, this); + return FlutterView._(id, this, const _ViewConfiguration()); } void _addView(int id) { @@ -268,14 +268,12 @@ class PlatformDispatcher { void _doAddView(int id) { assert(!_views.containsKey(id), 'View ID $id already exists.'); _views[id] = _createView(id); - _viewConfigurations[id] = const _ViewConfiguration(); } void _removeView(int id) { assert(id != _kImplicitViewId, 'The implicit view #$id can not be removed.'); assert(_views.containsKey(id), 'View ID $id does not exist.'); _views.remove(id); - _viewConfigurations.remove(id); } // Called from the engine, via hooks.dart. diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 3ee7c2e0e45ba..ae9e9ffbf8806 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -23,7 +23,7 @@ namespace flutter { namespace { // Keep this in sync with _kImplicitViewId in ../platform_dispatcher.dart. -static constexpr int kImplicitViewId = 0; +static constexpr int kFlutterImplicitViewId = 0; Dart_Handle ToByteData(const fml::Mapping& buffer) { return tonic::DartByteData::Create(buffer.GetMapping(), buffer.GetSize()); From adf5b8f219797e00da2b1485c8a55a199ad7cb35 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 23 Jul 2023 16:14:20 -0700 Subject: [PATCH 08/46] Doc for implicit view --- common/settings.h | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/common/settings.h b/common/settings.h index 4b771607e31cd..141c54af28449 100644 --- a/common/settings.h +++ b/common/settings.h @@ -227,27 +227,30 @@ struct Settings { // Enable the implicit view. // // The implicit view is a compatibility mode to help the transition from - // single-view APIs to multi-view APIs, which use different models for views. - // Although single-view APIs will eventually be replaced by their multi-view - // variants, during the deprecation period, the single-view APIs will coexist - // with and work with the multi-view APIs as if the other views don't exist. - // To achieve this, the platform can enable "implicit view", which is a - // special view that keeps all behaviors of "the view" in a legacy - // single-view Flutter app, allowing single-view APIs to continue working, - // while new-style "regular" views created by new ways must be operated by - // multi-view APIs. + // single-view APIs to multi-view APIs, which use different models for view + // management. Although single-view APIs will eventually be replaced by their + // multi-view variants, during the deprecation period, the single-view APIs + // will coexist with and work with the multi-view APIs. To achieve this, the + // platform can enable "implicit view", so that the shell will not only have + // the regular views, but also a a special view that keeps the legacy + // behavior, which can be operated by legacy single-view APIs as if the other + // views don't exist. // - // If implicit view is disabled, then all views should be created by - // Shell::AddView before being used, and removed by Shell::RemoveView after - // they are gone. + // Normally, all views should be created by Shell::AddView before being used, + // and removed by Shell::RemoveView after they are gone. If a view is added + // or removed, the framework will be notified. No view IDs are reused. + // Operating an non-existing view is an error. // // If implicit view is enabled, in addition to the "regular views" as above, - // the shell (including the engine and the dart:ui library) will implicitly - // create a view upon initialization without `Shell::AddView` (hence the - // name). This view will have a view ID of kFlutterImplicitViewId, and - // can never be removed, even if the window that shows the view is closed. - // The caller should adjust accordingly by providing contents and operations - // to the view without calling Shell::AddView or Shell::RemoveView. + // the shell will start up with a special view with a fixed view ID of + // kFlutterImplicitViewId. This view does not support adding or removing. + // Even when the window that shows the view is closed, the framework is + // unaware and might continue render into or operate this view. + // + // Unless specified otherwise, all multi-view APIs can also operate the + // implicit view using its ID (kFlutterImplicitViewId). + // + // The enable_implicit_view defaults to true. bool enable_implicit_view = true; // Data set by platform-specific embedders for use in font initialization. From f1a497bf0e21b0955bb3e9a3704e2d6d53cf0163 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 23 Jul 2023 22:12:47 -0700 Subject: [PATCH 09/46] Two tests --- lib/ui/platform_dispatcher.dart | 1 + shell/common/fixtures/shell_test.dart | 11 ++++ shell/common/shell_unittests.cc | 83 +++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 92cae4c8aaf39..506aff6519e4e 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -313,6 +313,7 @@ class PlatformDispatcher { List displayFeaturesState, int displayId, ) { + assert(_views.containsKey(id), 'View $id does not exist.'); final _ViewConfiguration viewConfiguration = _ViewConfiguration( devicePixelRatio: devicePixelRatio, geometry: Rect.fromLTWH(0.0, 0.0, width, height), diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index ea7361915d7c7..10c3a9b3e4b1e 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -482,3 +482,14 @@ Future testThatAssetLoadingHappensOnWorkerThread() async { } catch (err) { /* Do nothing */ } notifyNative(); } + +@pragma('vm:external-name', 'NativeReportViewIdsCallback') +external void nativeReportViewIdsCallback(bool hasImplicitView, List viewIds); + +@pragma('vm:entry-point') +void testReportViewIds() { + final List viewIds = PlatformDispatcher.instance.views + .map((FlutterView view) => view.viewId) + .toList(); + nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds); +} diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 4c4c85f8b768b..efe8762d39a97 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4342,6 +4342,89 @@ TEST_F(ShellTest, PrintsErrorWhenPlatformMessageSentFromWrongThread) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); } +TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { + Settings settings = CreateSettingsForFixture(); + settings.enable_implicit_view = true; + + auto task_runner = CreateNewThread(); + TaskRunners task_runners("test", task_runner, task_runner, task_runner, + task_runner); + std::unique_ptr shell = CreateShell(settings, task_runners); + ASSERT_TRUE(shell); + + bool hasImplicitView; + std::vector viewIds; + fml::AutoResetWaitableEvent reportLatch; + auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, + &viewIds](Dart_NativeArguments args) { + Dart_Handle exception = nullptr; + ASSERT_EQ(viewIds.size(), 0ul); + hasImplicitView = + tonic::DartConverter::FromArguments(args, 0, exception); + ASSERT_EQ(exception, nullptr); + viewIds = tonic::DartConverter>::FromArguments( + args, 1, exception); + ASSERT_EQ(exception, nullptr); + reportLatch.Signal(); + }; + AddNativeCallback("NativeReportViewIdsCallback", + CREATE_NATIVE_ENTRY(nativeViewIdsCallback)); + + PlatformViewNotifyCreated(shell.get()); + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("testReportViewIds"); + RunEngine(shell.get(), std::move(configuration)); + reportLatch.Wait(); + + ASSERT_TRUE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 1u); + ASSERT_EQ(viewIds[0], 0ll); + + PlatformViewNotifyDestroyed(shell.get()); + DestroyShell(std::move(shell), task_runners); +} + +TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { + Settings settings = CreateSettingsForFixture(); + settings.enable_implicit_view = false; + + auto task_runner = CreateNewThread(); + TaskRunners task_runners("test", task_runner, task_runner, task_runner, + task_runner); + std::unique_ptr shell = CreateShell(settings, task_runners); + ASSERT_TRUE(shell); + + bool hasImplicitView; + std::vector viewIds; + fml::AutoResetWaitableEvent reportLatch; + auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, + &viewIds](Dart_NativeArguments args) { + Dart_Handle exception = nullptr; + ASSERT_EQ(viewIds.size(), 0ul); + hasImplicitView = + tonic::DartConverter::FromArguments(args, 0, exception); + ASSERT_EQ(exception, nullptr); + viewIds = tonic::DartConverter>::FromArguments( + args, 1, exception); + ASSERT_EQ(exception, nullptr); + reportLatch.Signal(); + }; + AddNativeCallback("NativeReportViewIdsCallback", + CREATE_NATIVE_ENTRY(nativeViewIdsCallback)); + + PlatformViewNotifyCreated(shell.get()); + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("testReportViewIds"); + RunEngine(shell.get(), std::move(configuration)); + reportLatch.Wait(); + + ASSERT_FALSE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 0u); + + PlatformViewNotifyDestroyed(shell.get()); + DestroyShell(std::move(shell), task_runners); +} + } // namespace testing } // namespace flutter From f31f60c55a26964edd6c98d9bb8ed9134a5fab77 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 23 Jul 2023 22:24:50 -0700 Subject: [PATCH 10/46] Remove platform data view metrics --- runtime/platform_data.h | 1 - runtime/runtime_controller.cc | 8 +----- shell/common/engine_unittests.cc | 43 -------------------------------- 3 files changed, 1 insertion(+), 51 deletions(-) diff --git a/runtime/platform_data.h b/runtime/platform_data.h index b6d4c65f94d19..65e7bbb8c942c 100644 --- a/runtime/platform_data.h +++ b/runtime/platform_data.h @@ -32,7 +32,6 @@ struct PlatformData { ~PlatformData(); - ViewportMetrics viewport_metrics; std::string language_code; std::string country_code; std::string script_code; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 887eae52f3cce..d0648483111cc 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -76,7 +76,6 @@ std::unique_ptr RuntimeController::Spawn( p_persistent_isolate_data, // spawned_context); // result->spawning_isolate_ = root_isolate_; - result->platform_data_.viewport_metrics = ViewportMetrics(); return result; } @@ -115,11 +114,7 @@ std::unique_ptr RuntimeController::Clone() const { } bool RuntimeController::FlushRuntimeStateToIsolate() { - // TODO(dkwingsmt): Needs a view ID here (or platform_data should probably - // have multiple view metrics). - return SetViewportMetrics(kFlutterImplicitViewId, - platform_data_.viewport_metrics) && - SetLocales(platform_data_.locale_data) && + return SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && SetAccessibilityFeatures( platform_data_.accessibility_feature_flags_) && @@ -149,7 +144,6 @@ bool RuntimeController::RemoveView(int64_t view_id) { bool RuntimeController::SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) { TRACE_EVENT0("flutter", "SetViewportMetrics"); - platform_data_.viewport_metrics = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { Window* window = platform_configuration->get_window(view_id); diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index d1a7d24d39cbc..a6bbc12adb644 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -21,7 +21,6 @@ namespace flutter { namespace { -constexpr int64_t kImplicitViewId = 0ll; class MockDelegate : public Engine::Delegate { public: @@ -319,48 +318,6 @@ TEST_F(EngineTest, SpawnWithCustomInitialRoute) { }); } -TEST_F(EngineTest, SpawnResetsViewportMetrics) { - PostUITaskSync([this] { - MockRuntimeDelegate client; - auto mock_runtime_controller = - std::make_unique(client, task_runners_); - auto vm_ref = DartVMRef::Create(settings_); - EXPECT_CALL(*mock_runtime_controller, GetDartVM()) - .WillRepeatedly(::testing::Return(vm_ref.get())); - ViewportMetrics old_viewport_metrics = ViewportMetrics(); - const double kViewWidth = 768; - const double kViewHeight = 1024; - old_viewport_metrics.physical_width = kViewWidth; - old_viewport_metrics.physical_height = kViewHeight; - mock_runtime_controller->SetViewportMetrics(kImplicitViewId, - old_viewport_metrics); - auto engine = std::make_unique( - /*delegate=*/delegate_, - /*dispatcher_maker=*/dispatcher_maker_, - /*image_decoder_task_runner=*/image_decoder_task_runner_, - /*task_runners=*/task_runners_, - /*settings=*/settings_, - /*animator=*/std::move(animator_), - /*io_manager=*/io_manager_, - /*font_collection=*/std::make_shared(), - /*runtime_controller=*/std::move(mock_runtime_controller), - /*gpu_disabled_switch=*/std::make_shared()); - - auto& old_platform_data = engine->GetRuntimeController()->GetPlatformData(); - EXPECT_EQ(old_platform_data.viewport_metrics.physical_width, kViewWidth); - EXPECT_EQ(old_platform_data.viewport_metrics.physical_height, kViewHeight); - - auto spawn = - engine->Spawn(delegate_, dispatcher_maker_, settings_, nullptr, - std::string(), io_manager_, snapshot_delegate_, nullptr); - EXPECT_TRUE(spawn != nullptr); - auto& new_viewport_metrics = - spawn->GetRuntimeController()->GetPlatformData().viewport_metrics; - EXPECT_EQ(new_viewport_metrics.physical_width, 0); - EXPECT_EQ(new_viewport_metrics.physical_height, 0); - }); -} - TEST_F(EngineTest, SpawnWithCustomSettings) { PostUITaskSync([this] { MockRuntimeDelegate client; From 9d68f3ca4c153371de13589d24f11faeab7b25b1 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 23 Jul 2023 22:52:34 -0700 Subject: [PATCH 11/46] Extract function --- shell/common/shell_unittests.cc | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index efe8762d39a97..9d1aa885ffc68 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4342,6 +4342,19 @@ TEST_F(ShellTest, PrintsErrorWhenPlatformMessageSentFromWrongThread) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); } +static void parseViewIdsCallback(const Dart_NativeArguments& args, + bool* hasImplicitView, + std::vector* viewIds) { + Dart_Handle exception = nullptr; + viewIds->clear(); + *hasImplicitView = + tonic::DartConverter::FromArguments(args, 0, exception); + ASSERT_EQ(exception, nullptr); + *viewIds = tonic::DartConverter>::FromArguments( + args, 1, exception); + ASSERT_EQ(exception, nullptr); +} + TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { Settings settings = CreateSettingsForFixture(); settings.enable_implicit_view = true; @@ -4357,14 +4370,7 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { fml::AutoResetWaitableEvent reportLatch; auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, &viewIds](Dart_NativeArguments args) { - Dart_Handle exception = nullptr; - ASSERT_EQ(viewIds.size(), 0ul); - hasImplicitView = - tonic::DartConverter::FromArguments(args, 0, exception); - ASSERT_EQ(exception, nullptr); - viewIds = tonic::DartConverter>::FromArguments( - args, 1, exception); - ASSERT_EQ(exception, nullptr); + parseViewIdsCallback(args, &hasImplicitView, &viewIds); reportLatch.Signal(); }; AddNativeCallback("NativeReportViewIdsCallback", @@ -4399,14 +4405,7 @@ TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { fml::AutoResetWaitableEvent reportLatch; auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, &viewIds](Dart_NativeArguments args) { - Dart_Handle exception = nullptr; - ASSERT_EQ(viewIds.size(), 0ul); - hasImplicitView = - tonic::DartConverter::FromArguments(args, 0, exception); - ASSERT_EQ(exception, nullptr); - viewIds = tonic::DartConverter>::FromArguments( - args, 1, exception); - ASSERT_EQ(exception, nullptr); + parseViewIdsCallback(args, &hasImplicitView, &viewIds); reportLatch.Signal(); }; AddNativeCallback("NativeReportViewIdsCallback", From 7af949699a017b0a993cbb8d0f153c22e58d1ae2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 24 Jul 2023 12:53:58 -0700 Subject: [PATCH 12/46] Docs and address comments --- common/settings.h | 39 ++++++++++++++-------------- shell/common/rasterizer_unittests.cc | 34 ++++++++++++------------ shell/common/shell.h | 4 +-- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/common/settings.h b/common/settings.h index 141c54af28449..c0aefce0b4d38 100644 --- a/common/settings.h +++ b/common/settings.h @@ -226,31 +226,32 @@ struct Settings { // Enable the implicit view. // - // The implicit view is a compatibility mode to help the transition from - // single-view APIs to multi-view APIs, which use different models for view - // management. Although single-view APIs will eventually be replaced by their - // multi-view variants, during the deprecation period, the single-view APIs - // will coexist with and work with the multi-view APIs. To achieve this, the - // platform can enable "implicit view", so that the shell will not only have - // the regular views, but also a a special view that keeps the legacy - // behavior, which can be operated by legacy single-view APIs as if the other - // views don't exist. + // The implicit view mode is a compatibility mode to help the transition from + // the older single-view APIs to the newer multi-view APIs. The two sets of + // APIs use different models for view management. By enabling the implicit + // view, single-view APIs can operate a special view as if other views don't + // exist. // - // Normally, all views should be created by Shell::AddView before being used, - // and removed by Shell::RemoveView after they are gone. If a view is added - // or removed, the framework will be notified. No view IDs are reused. - // Operating an non-existing view is an error. + // In the regular multi-view model where implicit view is disabled, all views + // should be created by Shell::AddView before being used, and removed by + // Shell::RemoveView to signify that they are gone. If a view is added or + // removed, the framework (PlatformDispatcher) will be notified. New view IDs + // are always unique, never reused. Operating a non-existing view is an error. // // If implicit view is enabled, in addition to the "regular views" as above, // the shell will start up with a special view with a fixed view ID of - // kFlutterImplicitViewId. This view does not support adding or removing. - // Even when the window that shows the view is closed, the framework is - // unaware and might continue render into or operate this view. + // kFlutterImplicitViewId. Shell::AddView or RemoveView must not be called + // for this view. Even when the window that shows the view is closed, the + // framework is unaware and might continue render into or operate this view. // - // Unless specified otherwise, all multi-view APIs can also operate the - // implicit view using its ID (kFlutterImplicitViewId). + // The single-view APIs, which are APIs that do not specify view IDs, operate + // the implicit view. The multi-view APIs can operate all views, including the + // implicit view with the correct ID (kFlutterImplicitViewId), unless + // specified otherwise, // - // The enable_implicit_view defaults to true. + // The enable_implicit_view defaults to true. Multi-view apps will probably + // want to disable the implicit view eventually for the simplicity of a + // unified model. bool enable_implicit_view = true; // Data set by platform-specific embedders for use in font initialization. diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 90b844e74f17f..4ec1699326209 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -30,7 +30,7 @@ using testing::ReturnRef; namespace flutter { namespace { -constexpr int64_t kDefaultViewId = 0; +constexpr int64_t kImplicitViewId = 0; constexpr float kDevicePixelRatio = 2.0f; class MockDelegate : public Rasterizer::Delegate { @@ -127,7 +127,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -189,7 +189,7 @@ TEST(RasterizerTest, .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -257,7 +257,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -331,7 +331,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -406,7 +406,7 @@ TEST(RasterizerTest, .Times(2); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -498,7 +498,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -557,7 +557,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); EXPECT_CALL( *external_view_embedder, @@ -616,7 +616,7 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -675,7 +675,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -734,7 +734,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -792,7 +792,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -849,7 +849,7 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -930,7 +930,7 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -985,7 +985,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1102,7 +1102,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -1184,7 +1184,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kDefaultViewId); + rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); diff --git a/shell/common/shell.h b/shell/common/shell.h index a128caa1f1768..c6a9de59e31b1 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,7 +298,7 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; - /// @brief Add a non-implicit view. + /// @brief Adds a non-implicit view. /// /// This method returns immediately and does not wait for the tasks /// on the rasterizer thread and the UI thread to finish. This is @@ -311,7 +311,7 @@ class Shell final : public PlatformView::Delegate, /// @param view_id void AddView(int64_t view_id); - /// @brief Remove a non-implicit view. + /// @brief Removes a non-implicit view. /// /// This method waits for the tasks on the rasterizer thread and the /// UI thread to finish before returning. From 2e539c63840a75400b6fbceece719079ef9a45c2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 24 Jul 2023 12:57:45 -0700 Subject: [PATCH 13/46] One more sentence --- common/settings.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/settings.h b/common/settings.h index c0aefce0b4d38..6f559dfa2f5f9 100644 --- a/common/settings.h +++ b/common/settings.h @@ -240,9 +240,11 @@ struct Settings { // // If implicit view is enabled, in addition to the "regular views" as above, // the shell will start up with a special view with a fixed view ID of - // kFlutterImplicitViewId. Shell::AddView or RemoveView must not be called - // for this view. Even when the window that shows the view is closed, the - // framework is unaware and might continue render into or operate this view. + // kFlutterImplicitViewId. This view, called the implicit view, is available + // throughout the lifetime of the shell. Shell::AddView or RemoveView must not + // be called for this view. Even when the window that shows the view is + // closed, the framework is unaware and might continue render into or operate + // this view. // // The single-view APIs, which are APIs that do not specify view IDs, operate // the implicit view. The multi-view APIs can operate all views, including the From 3d5a1900a6c086916a2d79484db62ab17f0790a9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 24 Jul 2023 17:00:47 -0700 Subject: [PATCH 14/46] AddRemoveView test --- lib/ui/platform_dispatcher.dart | 2 + shell/common/fixtures/shell_test.dart | 34 ++++++++++-- shell/common/rasterizer.cc | 2 - shell/common/shell.cc | 4 +- shell/common/shell_unittests.cc | 75 +++++++++++++++++++++++++-- 5 files changed, 107 insertions(+), 10 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 506aff6519e4e..e785669bf7d73 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -263,6 +263,7 @@ class PlatformDispatcher { void _addView(int id) { assert(id != _kImplicitViewId, 'The implicit view #$id can not be added.'); _doAddView(id); + _invoke(onMetricsChanged, _onMetricsChangedZone); } void _doAddView(int id) { @@ -274,6 +275,7 @@ class PlatformDispatcher { assert(id != _kImplicitViewId, 'The implicit view #$id can not be removed.'); assert(_views.containsKey(id), 'View ID $id does not exist.'); _views.remove(id); + _invoke(onMetricsChanged, _onMetricsChangedZone); } // Called from the engine, via hooks.dart. diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index 10c3a9b3e4b1e..645331dc57c6d 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -486,10 +486,38 @@ Future testThatAssetLoadingHappensOnWorkerThread() async { @pragma('vm:external-name', 'NativeReportViewIdsCallback') external void nativeReportViewIdsCallback(bool hasImplicitView, List viewIds); +List getCurrentViewIds() { + return PlatformDispatcher.instance.views + .map((FlutterView view) => view.viewId) + .toSet() + .toList() + ..sort(); +} + +bool listEquals(List a, List b) { + if (a.length != b.length) { + return false; + } + for (int i = 0; i < a.length; i += 1) { + if (a[i] != b[i]) { + return false; + } + } + return true; +} + +// This entrypoint reports whether there's an implicit view and the list of view +// IDs using nativeReportViewIdsCallback on initialization and every time the +// list of view IDs changes. @pragma('vm:entry-point') void testReportViewIds() { - final List viewIds = PlatformDispatcher.instance.views - .map((FlutterView view) => view.viewId) - .toList(); + List viewIds = getCurrentViewIds(); nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds); + PlatformDispatcher.instance.onMetricsChanged = () { + final List newViewIds = getCurrentViewIds(); + if (!listEquals(viewIds, newViewIds)) { + viewIds = newViewIds; + nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds); + } + }; } diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 26562134d4020..0398e0cb5dfdb 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -159,13 +159,11 @@ void Rasterizer::NotifyLowMemoryWarning() const { } void Rasterizer::AddView(int64_t view_id) { - FML_DCHECK(view_id == kFlutterImplicitViewId); // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } void Rasterizer::RemoveSurface(int64_t view_id) { - FML_DCHECK(view_id == kFlutterImplicitViewId); // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 93c90dda803d8..a880821e688a4 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2041,7 +2041,7 @@ bool Shell::OnServiceProtocolReloadAssetFonts( void Shell::AddView(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::AddView"); - FML_DCHECK(is_setup_); + FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); if (view_id == kFlutterImplicitViewId) { FML_DLOG(WARNING) @@ -2071,7 +2071,7 @@ void Shell::AddView(int64_t view_id) { void Shell::RemoveView(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::RemoveView"); - FML_DCHECK(is_setup_); + FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); if (view_id == kFlutterImplicitViewId) { FML_DLOG(WARNING) diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 9d1aa885ffc68..bfcdfcdf1ab3e 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4342,7 +4342,7 @@ TEST_F(ShellTest, PrintsErrorWhenPlatformMessageSentFromWrongThread) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); } -static void parseViewIdsCallback(const Dart_NativeArguments& args, +static void ParseViewIdsCallback(const Dart_NativeArguments& args, bool* hasImplicitView, std::vector* viewIds) { Dart_Handle exception = nullptr; @@ -4355,6 +4355,16 @@ static void parseViewIdsCallback(const Dart_NativeArguments& args, ASSERT_EQ(exception, nullptr); } +static void RunOnPlatformTaskRunner(Shell& shell, const fml::closure& task) { + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + shell.GetTaskRunners().GetPlatformTaskRunner(), [&task, &latch]() { + task(); + latch.Signal(); + }); + latch.Wait(); +} + TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { Settings settings = CreateSettingsForFixture(); settings.enable_implicit_view = true; @@ -4370,7 +4380,7 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { fml::AutoResetWaitableEvent reportLatch; auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, &viewIds](Dart_NativeArguments args) { - parseViewIdsCallback(args, &hasImplicitView, &viewIds); + ParseViewIdsCallback(args, &hasImplicitView, &viewIds); reportLatch.Signal(); }; AddNativeCallback("NativeReportViewIdsCallback", @@ -4405,7 +4415,7 @@ TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { fml::AutoResetWaitableEvent reportLatch; auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, &viewIds](Dart_NativeArguments args) { - parseViewIdsCallback(args, &hasImplicitView, &viewIds); + ParseViewIdsCallback(args, &hasImplicitView, &viewIds); reportLatch.Signal(); }; AddNativeCallback("NativeReportViewIdsCallback", @@ -4424,6 +4434,65 @@ TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { DestroyShell(std::move(shell), task_runners); } +TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + Settings settings = CreateSettingsForFixture(); + settings.enable_implicit_view = true; + + ThreadHost thread_host(ThreadHost::ThreadHostConfig( + "io.flutter.test." + GetCurrentTestName() + ".", + ThreadHost::Type::Platform | ThreadHost::Type::RASTER | + ThreadHost::Type::IO | ThreadHost::Type::UI)); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + std::unique_ptr shell = CreateShell(settings, task_runners); + ASSERT_TRUE(shell); + + bool hasImplicitView; + std::vector viewIds; + fml::AutoResetWaitableEvent reportLatch; + auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, + &viewIds](Dart_NativeArguments args) { + ParseViewIdsCallback(args, &hasImplicitView, &viewIds); + reportLatch.Signal(); + }; + AddNativeCallback("NativeReportViewIdsCallback", + CREATE_NATIVE_ENTRY(nativeViewIdsCallback)); + + PlatformViewNotifyCreated(shell.get()); + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("testReportViewIds"); + RunEngine(shell.get(), std::move(configuration)); + + reportLatch.Wait(); + ASSERT_TRUE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 1u); + ASSERT_EQ(viewIds[0], 0ll); + + RunOnPlatformTaskRunner(*shell, [&shell] { shell->AddView(2); }); + reportLatch.Wait(); + ASSERT_TRUE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 2u); + ASSERT_EQ(viewIds[1], 2ll); + + RunOnPlatformTaskRunner(*shell, [&shell] { shell->RemoveView(2); }); + reportLatch.Wait(); + ASSERT_TRUE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 1u); + ASSERT_EQ(viewIds[0], 0ll); + + RunOnPlatformTaskRunner(*shell, [&shell] { shell->AddView(4); }); + reportLatch.Wait(); + ASSERT_TRUE(hasImplicitView); + ASSERT_EQ(viewIds.size(), 2u); + ASSERT_EQ(viewIds[1], 4ll); + + PlatformViewNotifyDestroyed(shell.get()); + DestroyShell(std::move(shell), task_runners); +} + } // namespace testing } // namespace flutter From 4fc49228d060f9252c4d629fa591e7faac7341bd Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 24 Jul 2023 18:55:26 -0700 Subject: [PATCH 15/46] Remove expected size on removal --- shell/common/shell.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index a880821e688a4..2ec16728cd37b 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2081,6 +2081,7 @@ void Shell::RemoveView(int64_t view_id) { return; } + expected_frame_sizes_.erase(view_id); fml::AutoResetWaitableEvent latch; task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // view_id // From db9a99cc79f6a56575e36de67f6f1184d318e3bc Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 24 Jul 2023 19:04:22 -0700 Subject: [PATCH 16/46] More docs --- shell/common/shell.h | 12 +++++++++--- shell/common/shell_unittests.cc | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/shell/common/shell.h b/shell/common/shell.h index d0f414423292e..047950065142c 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -305,10 +305,13 @@ class Shell final : public PlatformView::Delegate, /// because the rasterizer thread can be blocked by the platform /// thread to render platform views. /// - /// The implicit view is added internally on Shell initialization - /// depending on `Settings.enable_implicit_view`. Trying to add + /// The implicit view should never be added with this function. + /// Instead, it is added internally on Shell initialization depending + /// on `Settings.enable_implicit_view`. Trying to add /// `kFlutterImplicitViewId` is a no-op with warning. - /// @param view_id + /// + /// @param[in] view_id The view ID of the new view. + /// void AddView(int64_t view_id); /// @brief Removes a non-implicit view. @@ -318,6 +321,9 @@ class Shell final : public PlatformView::Delegate, /// /// The implicit view should never be removed. Trying to remove /// `kFlutterImplicitViewId` is a no-op with warning. + /// + /// @param[in] view_id The view ID of the view to be removed. + /// void RemoveView(int64_t view_id); //---------------------------------------------------------------------------- diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index bfcdfcdf1ab3e..accf1925eed7f 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4342,6 +4342,8 @@ TEST_F(ShellTest, PrintsErrorWhenPlatformMessageSentFromWrongThread) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); } +// Parse the arguments of NativeReportViewIdsCallback and +// store them in hasImplicitView and viewIds. static void ParseViewIdsCallback(const Dart_NativeArguments& args, bool* hasImplicitView, std::vector* viewIds) { @@ -4355,6 +4357,7 @@ static void ParseViewIdsCallback(const Dart_NativeArguments& args, ASSERT_EQ(exception, nullptr); } +// Run the given task in the platform runner, and blocks until its finished. static void RunOnPlatformTaskRunner(Shell& shell, const fml::closure& task) { fml::AutoResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( From 2128688cfc482760b7696b186ca1065d85cde2fe Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 25 Jul 2023 10:52:20 -0700 Subject: [PATCH 17/46] Assign viewId not bool. Move viewId to settings.h. --- common/settings.h | 2 ++ lib/ui/dart_ui.cc | 4 ++-- lib/ui/natives.dart | 9 +++++++-- lib/ui/platform_dispatcher.dart | 26 +++++++++---------------- lib/ui/window.dart | 2 +- lib/ui/window/platform_configuration.cc | 3 --- runtime/runtime_controller.cc | 3 +-- shell/common/rasterizer.cc | 2 -- shell/common/shell.cc | 2 -- 9 files changed, 22 insertions(+), 31 deletions(-) diff --git a/common/settings.h b/common/settings.h index 6f559dfa2f5f9..2e0cc53879783 100644 --- a/common/settings.h +++ b/common/settings.h @@ -22,6 +22,8 @@ namespace flutter { +constexpr int64_t kFlutterImplicitViewId = 0; + class FrameTiming { public: enum Phase { diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 438986bf8ff52..5e1929db22313 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -382,8 +382,8 @@ void DartUI::InitForIsolate(const Settings& settings) { } if (settings.enable_implicit_view) { - result = - Dart_SetField(dart_ui, ToDart("_implicitViewEnabled"), Dart_True()); + result = Dart_SetField(dart_ui, ToDart("_implicitViewId"), + Dart_NewInteger(kFlutterImplicitViewId)); if (Dart_IsError(result)) { Dart_PropagateError(result); } diff --git a/lib/ui/natives.dart b/lib/ui/natives.dart index e9d3df9eb3014..72a55ab8b7d57 100644 --- a/lib/ui/natives.dart +++ b/lib/ui/natives.dart @@ -113,6 +113,11 @@ _ScheduleImmediateClosure _getScheduleMicrotaskClosure() => _scheduleMicrotask; @pragma('vm:entry-point') bool _impellerEnabled = false; -// Used internally to indicate whether the embedder enables the implicit view. +// Used internally to indicate whether the embedder enables the implicit view, +// and the implicit view's ID if so. +// +// The exact value of this variable is an implementation detail that may change +// at any time. Apps should always use PlatformDispatcher.implicitView to +// determine the current implicit view, if any. @pragma('vm:entry-point') -bool _implicitViewEnabled = false; +int? _implicitViewId; diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index e785669bf7d73..192cc0c79f137 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -66,14 +66,6 @@ typedef ErrorCallback = bool Function(Object exception, StackTrace stackTrace); // A gesture setting value that indicates it has not been set by the engine. const double _kUnsetGestureSetting = -1.0; -// The view ID of PlatformDispatcher.implicitView. This is an -// implementation detail that may change at any time. Apps -// should always use PlatformDispatcher.implicitView to determine -// the current implicit view, if any. -// -// Keep this in sync with kImplicitViewId in window/platform_configuration.cc. -const int _kImplicitViewId = 0; - // A message channel to receive KeyData from the platform. // // See embedder.cc::kFlutterKeyDataChannel for more information. @@ -124,8 +116,8 @@ class PlatformDispatcher { /// these. Use [instance] to access the singleton. PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; - if (_implicitViewEnabled) { - _doAddView(_kImplicitViewId); + if (_implicitViewId != null) { + _doAddView(_implicitViewId!); } } @@ -222,11 +214,11 @@ class PlatformDispatcher { /// * [PlatformDispatcher.views] for a list of all [FlutterView]s provided /// by the platform. FlutterView? get implicitView { - final FlutterView? result = _views[_kImplicitViewId]; - assert((result != null) == _implicitViewEnabled, - _implicitViewEnabled ? - 'The _implicitViewEnabled is true, but the implicit view does not exist.' : - 'The _implicitViewEnabled is false, but the implicit view exists.'); + final FlutterView? result = _views[_implicitViewId]; + assert((result != null) == (_implicitViewId != null), + (_implicitViewId != null) ? + 'The implicit view ID is $_implicitViewId, but the implicit view does not exist.' : + 'The implicit view ID is null, but the implicit view exists.'); return result; } @@ -261,7 +253,7 @@ class PlatformDispatcher { } void _addView(int id) { - assert(id != _kImplicitViewId, 'The implicit view #$id can not be added.'); + assert(id != _implicitViewId, 'The implicit view #$id can not be added.'); _doAddView(id); _invoke(onMetricsChanged, _onMetricsChangedZone); } @@ -272,7 +264,7 @@ class PlatformDispatcher { } void _removeView(int id) { - assert(id != _kImplicitViewId, 'The implicit view #$id can not be removed.'); + assert(id != _implicitViewId, 'The implicit view #$id can not be removed.'); assert(_views.containsKey(id), 'View ID $id does not exist.'); _views.remove(id); _invoke(onMetricsChanged, _onMetricsChangedZone); diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 63b7f74b8b5a7..60f241ff1ccf3 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -407,7 +407,7 @@ class SingletonFlutterWindow extends FlutterView { 'This feature was deprecated after v3.7.0-32.0.pre.' ) SingletonFlutterWindow._() : super._( - _kImplicitViewId, + _implicitViewId!, PlatformDispatcher.instance, const _ViewConfiguration(), ); diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index ae9e9ffbf8806..318fca629efe0 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -22,9 +22,6 @@ namespace flutter { namespace { -// Keep this in sync with _kImplicitViewId in ../platform_dispatcher.dart. -static constexpr int kFlutterImplicitViewId = 0; - Dart_Handle ToByteData(const fml::Mapping& buffer) { return tonic::DartByteData::Create(buffer.GetMapping(), buffer.GetSize()); } diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index d0648483111cc..59944a51c7960 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -6,6 +6,7 @@ #include +#include "flutter/common/settings.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/trace_event.h" #include "flutter/lib/ui/compositing/scene.h" @@ -20,8 +21,6 @@ namespace flutter { -constexpr uint64_t kFlutterImplicitViewId = 0ll; - RuntimeController::RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners) : client_(p_client), vm_(nullptr), context_(task_runners) {} diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 0398e0cb5dfdb..0410a547d2846 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -36,8 +36,6 @@ namespace flutter { // used within this interval. static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000); -static constexpr int64_t kFlutterImplicitViewId = 0; - Rasterizer::Rasterizer(Delegate& delegate, MakeGpuImageBehavior gpu_image_behavior) : delegate_(delegate), diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 2ec16728cd37b..c030d03dc536d 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -775,8 +775,6 @@ DartVM* Shell::GetDartVM() { return &vm_; } -static constexpr int64_t kFlutterImplicitViewId = 0ll; - // |PlatformView::Delegate| void Shell::OnPlatformViewCreated(std::unique_ptr surface) { TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated"); From 4f049cd8c5a6aaeec1b7e31cfdc01d172f2c5a6c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 25 Jul 2023 11:04:03 -0700 Subject: [PATCH 18/46] Remove more implicit view ID --- shell/platform/android/platform_view_android_jni_impl.cc | 2 -- shell/platform/darwin/ios/framework/Source/FlutterEngine.mm | 3 +-- shell/platform/fuchsia/flutter/flatland_platform_view.cc | 3 +-- shell/platform/fuchsia/flutter/gfx_platform_view.cc | 3 +-- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 72abd446061b0..991f3da9062fb 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,8 +37,6 @@ namespace flutter { -static constexpr int64_t kFlutterImplicitViewId = 0ll; - static fml::jni::ScopedJavaGlobalRef* g_flutter_callback_info_class = nullptr; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 3a51f4ab3c697..018805926aa15 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -8,6 +8,7 @@ #include +#include "flutter/common/settings.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/platform/darwin/platform_version.h" #include "flutter/fml/trace_event.h" @@ -38,8 +39,6 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" -static constexpr int64_t kFlutterImplicitViewId = 0ll; - /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) { diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index 39febd8c6db64..330aa3ed233f5 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -4,12 +4,11 @@ #include "flatland_platform_view.h" +#include "flutter/common/settings.h" #include "flutter/fml/make_copyable.h" namespace flutter_runner { -static constexpr int64_t kFlutterImplicitViewId = 0ll; - FlatlandPlatformView::FlatlandPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index ddb0ce029e2a1..d8a0702d9c9df 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -4,12 +4,11 @@ #include "gfx_platform_view.h" +#include "flutter/common/settings.h" #include "flutter/fml/make_copyable.h" namespace flutter_runner { -static constexpr int64_t kFlutterImplicitViewId = 0ll; - GfxPlatformView::GfxPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, From c7950357c9f0ba197806082a93c33c721d285723 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 25 Jul 2023 13:21:13 -0700 Subject: [PATCH 19/46] Fix compile, prefix view id with flutter --- shell/platform/darwin/ios/framework/Source/FlutterEngine.mm | 2 +- shell/platform/fuchsia/flutter/flatland_platform_view.cc | 2 +- shell/platform/fuchsia/flutter/gfx_platform_view.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 018805926aa15..12feba8f12ac7 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -309,7 +309,7 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(kFlutterImplicitViewId, viewportMetrics); + self.platformView->SetViewportMetrics(flutter::kFlutterImplicitViewId, viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index 330aa3ed233f5..cca111ce5ca3c 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -109,7 +109,7 @@ void FlatlandPlatformView::OnGetLayout( {}, // p_physical_display_features_state 0, // p_display_id }; - SetViewportMetrics(kFlutterImplicitViewId, metrics); + SetViewportMetrics(flutter::kFlutterImplicitViewId, metrics); parent_viewport_watcher_->GetLayout( fit::bind_member(this, &FlatlandPlatformView::OnGetLayout)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index d8a0702d9c9df..f384a00bccdca 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -236,7 +236,7 @@ void GfxPlatformView::OnScenicEvent( {}, // p_physical_display_features_state 0, // pdisplay_id }; - SetViewportMetrics(kFlutterImplicitViewId, metrics); + SetViewportMetrics(flutter::kFlutterImplicitViewId, metrics); } } From 03520e282273dfbfa2cf2829c34c0267c8f03f23 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 26 Jul 2023 12:58:52 -0700 Subject: [PATCH 20/46] Address many comments --- common/settings.h | 12 +++++------- lib/ui/platform_dispatcher.dart | 14 +++++--------- lib/ui/window/platform_configuration.cc | 25 ++++++++++++------------- lib/ui/window/platform_configuration.h | 19 ++++++++++++++++++- runtime/runtime_controller.h | 21 +++++++++++++++++++++ shell/common/engine.h | 23 +++++++++++++++++++++++ shell/common/fixtures/shell_test.dart | 6 ++++-- shell/common/rasterizer.cc | 2 +- shell/common/rasterizer.h | 16 +++++++++++++--- shell/common/shell.cc | 11 +++++------ 10 files changed, 107 insertions(+), 42 deletions(-) diff --git a/common/settings.h b/common/settings.h index 2e0cc53879783..fe2e5d6d87820 100644 --- a/common/settings.h +++ b/common/settings.h @@ -234,14 +234,14 @@ struct Settings { // view, single-view APIs can operate a special view as if other views don't // exist. // - // In the regular multi-view model where implicit view is disabled, all views - // should be created by Shell::AddView before being used, and removed by + // In the regular multi-view model where the implicit view is disabled, all + // views should be created by Shell::AddView before being used, and removed by // Shell::RemoveView to signify that they are gone. If a view is added or // removed, the framework (PlatformDispatcher) will be notified. New view IDs // are always unique, never reused. Operating a non-existing view is an error. // - // If implicit view is enabled, in addition to the "regular views" as above, - // the shell will start up with a special view with a fixed view ID of + // If the implicit view is enabled, in addition to the "regular views" as + // above, the shell will start up with a special view with a fixed view ID of // kFlutterImplicitViewId. This view, called the implicit view, is available // throughout the lifetime of the shell. Shell::AddView or RemoveView must not // be called for this view. Even when the window that shows the view is @@ -253,9 +253,7 @@ struct Settings { // implicit view with the correct ID (kFlutterImplicitViewId), unless // specified otherwise, // - // The enable_implicit_view defaults to true. Multi-view apps will probably - // want to disable the implicit view eventually for the simplicity of a - // unified model. + // The enable_implicit_view defaults to true. bool enable_implicit_view = true; // Data set by platform-specific embedders for use in font initialization. diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 192cc0c79f137..19b02b1ec9071 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -117,7 +117,7 @@ class PlatformDispatcher { PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; if (_implicitViewId != null) { - _doAddView(_implicitViewId!); + _insertNewView(_implicitViewId!); } } @@ -248,21 +248,17 @@ class PlatformDispatcher { _onMetricsChangedZone = Zone.current; } - FlutterView _createView(int id) { - return FlutterView._(id, this, const _ViewConfiguration()); + void _insertNewView(int id) { + assert(!_views.containsKey(id), 'View ID $id already exists.'); + _views[id] = FlutterView._(id, this, const _ViewConfiguration()); } void _addView(int id) { assert(id != _implicitViewId, 'The implicit view #$id can not be added.'); - _doAddView(id); + _insertNewView(id); _invoke(onMetricsChanged, _onMetricsChangedZone); } - void _doAddView(int id) { - assert(!_views.containsKey(id), 'View ID $id already exists.'); - _views[id] = _createView(id); - } - void _removeView(int id) { assert(id != _implicitViewId, 'The implicit view #$id can not be removed.'); assert(_views.containsKey(id), 'View ID $id does not exist.'); diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 318fca629efe0..3bee82464d8e8 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -32,15 +32,7 @@ PlatformConfigurationClient::~PlatformConfigurationClient() {} PlatformConfiguration::PlatformConfiguration( PlatformConfigurationClient* client) - : client_(client) { - if (client_->ImplicitViewEnabled()) { - // Add PlatformConfiguration's window now, but don't add dart:ui's View - // here. The dart:ui needs another way to add the implicit view - // synchronously so that the view is available before the main function. - // See _implicitViewEnabled in natives.dart. - AddWindowRecord(kFlutterImplicitViewId); - } -} + : client_(client) {} PlatformConfiguration::~PlatformConfiguration() {} @@ -86,11 +78,18 @@ void PlatformConfiguration::DidCreateIsolate() { report_timings_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_reportTimings"))); - library_.Set(tonic::DartState::Current(), - Dart_LookupLibrary(tonic::ToDart("dart:ui"))); + library_.Set(tonic::DartState::Current(), library); + if (client_->ImplicitViewEnabled()) { + // Add PlatformConfiguration's window now, but don't add dart:ui's View + // here. The dart:ui needs another way to add the implicit view + // synchronously so that the view is available before the main function. + // See _implicitViewId in natives.dart. + InsertNewView(kFlutterImplicitViewId); + } } -void PlatformConfiguration::AddWindowRecord(int64_t view_id) { +void PlatformConfiguration::InsertNewView(int64_t view_id) { + FML_DCHECK(library_.value()); windows_.emplace( view_id, std::make_unique(library_, view_id, ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); @@ -98,7 +97,7 @@ void PlatformConfiguration::AddWindowRecord(int64_t view_id) { void PlatformConfiguration::AddView(int64_t view_id) { FML_DCHECK(view_id != kFlutterImplicitViewId); - AddWindowRecord(view_id); + InsertNewView(view_id); std::shared_ptr dart_state = add_view_.dart_state().lock(); if (!dart_state) { return; diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index f9714d8e93d64..2043508e1e53b 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -268,8 +268,25 @@ class PlatformConfiguration final { /// void DidCreateIsolate(); + //---------------------------------------------------------------------------- + /// @brief Notify the framework that a new view is available. + /// + /// The implicit view should not be added with this method. The + /// framework has its own way to create the implicit view on + /// initialization. + /// + /// @param[in] view_id The ID of the new view. + /// void AddView(int64_t view_id); + //---------------------------------------------------------------------------- + /// @brief Notify the framework that a view is no longer available. + /// + /// The implicit view should not be removed with this method, + /// since it should never be removed. + /// + /// @param[in] view_id The ID of the view. + /// void RemoveView(int64_t view_id); //---------------------------------------------------------------------------- @@ -472,7 +489,7 @@ class PlatformConfiguration final { std::unordered_map> pending_responses_; - void AddWindowRecord(int64_t view_id); + void InsertNewView(int64_t view_id); }; //---------------------------------------------------------------------------- diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index f0c5be0165f70..450fac24412d2 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -163,8 +163,29 @@ class RuntimeController : public PlatformConfigurationClient { /// std::unique_ptr Clone() const; + //---------------------------------------------------------------------------- + /// @brief Notify the running isolate that a new view is available. + /// + /// If the isolate has not been started, this call is a noop. + /// + /// The implicit view should not be added with this method. The + /// running isolate has its own way to create the implicit view on + /// initialization. + /// + /// @param[in] view_id The ID of the new view. + /// bool AddView(int64_t view_id); + //---------------------------------------------------------------------------- + /// @brief Notify the running isolate that a view is no longer available. + /// + /// If the isolate has not been started, this call is a noop. + /// + /// The implicit view should not be removed with this method, + /// since it should never be removed. + /// + /// @param[in] view_id The ID of the view. + /// bool RemoveView(int64_t view_id); //---------------------------------------------------------------------------- diff --git a/shell/common/engine.h b/shell/common/engine.h index 62e9835a9d72c..0580770b80fa3 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -675,8 +675,31 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// std::optional GetUIIsolateReturnCode(); + //---------------------------------------------------------------------------- + /// @brief Notify the running Flutter application that a new view is + /// available. + /// + /// If the application is not running, this call is a noop. + /// + /// The implicit view should not be added with this method. The + /// framework has its own way to create the implicit view on + /// initialization. + /// + /// @param[in] view_id The ID of the new view. + /// void AddView(int64_t view_id); + //---------------------------------------------------------------------------- + /// @brief Notify the running Flutter application that a view is no + /// longer available. + /// + /// If the application is not running, this call is a noop. + /// + /// The implicit view should not be removed with this method, + /// since it should never be removed. + /// + /// @param[in] view_id The ID of the view. + /// void RemoveView(int64_t view_id); //---------------------------------------------------------------------------- diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index 645331dc57c6d..d69a5db501332 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -487,11 +487,13 @@ Future testThatAssetLoadingHappensOnWorkerThread() async { external void nativeReportViewIdsCallback(bool hasImplicitView, List viewIds); List getCurrentViewIds() { - return PlatformDispatcher.instance.views + final List result = PlatformDispatcher.instance.views .map((FlutterView view) => view.viewId) - .toSet() .toList() ..sort(); + assert(result.toSet().length == result.length, + 'Unexpected duplicate view ID found: $result'); + return result; } bool listEquals(List a, List b) { diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 0410a547d2846..ec12231445b70 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -161,7 +161,7 @@ void Rasterizer::AddView(int64_t view_id) { // multi-view. } -void Rasterizer::RemoveSurface(int64_t view_id) { +void Rasterizer::RemoveView(int64_t view_id) { // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 898510c1f8007..7d42d49d73cc3 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -205,12 +205,22 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; //---------------------------------------------------------------------------- - /// @brief Add a view, implicit or not. + /// @brief Create the resources for displaying a view. + /// + /// This method should be called a view is added, implicit or not. + /// + /// @param[in] view_id The ID of the new view. + /// void AddView(int64_t view_id); //---------------------------------------------------------------------------- - /// @brief Remove a view, implicit or not. - void RemoveSurface(int64_t view_id); + /// @brief Destroy the resources for displaying a view. + /// + /// This method should be called a view is removed. + /// + /// @param[in] view_id The ID of the view. + /// + void RemoveView(int64_t view_id); //---------------------------------------------------------------------------- /// @brief Sometimes, it may be necessary to render the same frame again diff --git a/shell/common/shell.cc b/shell/common/shell.cc index c030d03dc536d..59e3b085b02bd 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2042,10 +2042,9 @@ void Shell::AddView(int64_t view_id) { FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); if (view_id == kFlutterImplicitViewId) { - FML_DLOG(WARNING) - << "Unexpected request to add the implicit view #" - << kFlutterImplicitViewId - << ". This view should never be added. This call is no-op."; + FML_DLOG(ERROR) << "Unexpected request to add the implicit view #" + << kFlutterImplicitViewId + << ". This view should never be added. This call is no-op."; return; } @@ -2072,7 +2071,7 @@ void Shell::RemoveView(int64_t view_id) { FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); if (view_id == kFlutterImplicitViewId) { - FML_DLOG(WARNING) + FML_DLOG(ERROR) << "Unexpected request to remove the implicit view #" << kFlutterImplicitViewId << ". This view should never be removed. This call is no-op."; @@ -2095,7 +2094,7 @@ void Shell::RemoveView(int64_t view_id) { view_id // ]() { if (rasterizer) { - rasterizer->RemoveSurface(view_id); + rasterizer->RemoveView(view_id); } latch.Signal(); }); From 285c0f6941d5203b06699d1f8bba6bda151b26fe Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Jul 2023 12:28:05 -0700 Subject: [PATCH 21/46] Correct FlushRuntimeStateToIsolate and PlatformData --- lib/ui/platform_dispatcher.dart | 6 ++++-- lib/ui/window/platform_configuration.cc | 15 +-------------- lib/ui/window/platform_configuration.h | 5 ++--- runtime/platform_data.h | 4 ++++ runtime/runtime_controller.cc | 12 ++++++++++++ shell/common/shell.cc | 10 ++++++---- 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 19b02b1ec9071..e156bd90ab3aa 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -254,8 +254,10 @@ class PlatformDispatcher { } void _addView(int id) { - assert(id != _implicitViewId, 'The implicit view #$id can not be added.'); - _insertNewView(id); + // The implicit view is added at construction. + if (id != _implicitViewId) { + _insertNewView(id); + } _invoke(onMetricsChanged, _onMetricsChangedZone); } diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 3bee82464d8e8..bea3d118089aa 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -79,25 +79,12 @@ void PlatformConfiguration::DidCreateIsolate() { Dart_GetField(library, tonic::ToDart("_reportTimings"))); library_.Set(tonic::DartState::Current(), library); - if (client_->ImplicitViewEnabled()) { - // Add PlatformConfiguration's window now, but don't add dart:ui's View - // here. The dart:ui needs another way to add the implicit view - // synchronously so that the view is available before the main function. - // See _implicitViewId in natives.dart. - InsertNewView(kFlutterImplicitViewId); - } } -void PlatformConfiguration::InsertNewView(int64_t view_id) { - FML_DCHECK(library_.value()); +void PlatformConfiguration::AddView(int64_t view_id) { windows_.emplace( view_id, std::make_unique(library_, view_id, ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); -} - -void PlatformConfiguration::AddView(int64_t view_id) { - FML_DCHECK(view_id != kFlutterImplicitViewId); - InsertNewView(view_id); std::shared_ptr dart_state = add_view_.dart_state().lock(); if (!dart_state) { return; diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 2043508e1e53b..781be7878f706 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -271,9 +271,8 @@ class PlatformConfiguration final { //---------------------------------------------------------------------------- /// @brief Notify the framework that a new view is available. /// - /// The implicit view should not be added with this method. The - /// framework has its own way to create the implicit view on - /// initialization. + /// The implicit view might be called with this method, which + /// will be a no-op. /// /// @param[in] view_id The ID of the new view. /// diff --git a/runtime/platform_data.h b/runtime/platform_data.h index 65e7bbb8c942c..a101323f83c7d 100644 --- a/runtime/platform_data.h +++ b/runtime/platform_data.h @@ -9,6 +9,7 @@ #include #include +#include "flutter/common/settings.h" #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/shell/common/display.h" @@ -32,6 +33,9 @@ struct PlatformData { ~PlatformData(); + // A map from view IDs of existing views to their viewport metrics. + std::unordered_map viewport_metrics_for_views; + std::string language_code; std::string country_code; std::string script_code; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 59944a51c7960..289279c5b76e8 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -113,6 +113,15 @@ std::unique_ptr RuntimeController::Clone() const { } bool RuntimeController::FlushRuntimeStateToIsolate() { + for (auto const& [view_id, viewport_metrics] : + platform_data_.viewport_metrics_for_views) { + if (!AddView(view_id)) { + return false; + } + if (!SetViewportMetrics(view_id, viewport_metrics)) { + return false; + } + } return SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && SetAccessibilityFeatures( @@ -123,6 +132,7 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { } bool RuntimeController::AddView(int64_t view_id) { + platform_data_.viewport_metrics_for_views[view_id] = ViewportMetrics(); if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->AddView(view_id); return true; @@ -132,6 +142,7 @@ bool RuntimeController::AddView(int64_t view_id) { } bool RuntimeController::RemoveView(int64_t view_id) { + platform_data_.viewport_metrics_for_views.erase(view_id); if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->RemoveView(view_id); return true; @@ -144,6 +155,7 @@ bool RuntimeController::SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) { TRACE_EVENT0("flutter", "SetViewportMetrics"); + platform_data_.viewport_metrics_for_views[view_id] = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { Window* window = platform_configuration->get_window(view_id); if (window) { diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 59e3b085b02bd..ea25765cd8335 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -825,12 +825,14 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { waiting_for_first_frame.store(true); }); - auto ui_task = [engine = engine_->GetWeakPtr()] { + auto ui_task = [engine = engine_->GetWeakPtr(), // + enable_implicit_view = settings_.enable_implicit_view // + ] { if (engine) { - // Don't call engine->AddView(implicitView) here, because the runtime has - // not been initialized anyway. The runtime has its own way to initialize - // the implitic view. engine->ScheduleFrame(); + if (enable_implicit_view) { + engine->AddView(kFlutterImplicitViewId); + } } }; From 9c92de23a8733892233e559cee0428d16c25ab4f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Jul 2023 14:42:08 -0700 Subject: [PATCH 22/46] AddView specifies view config --- lib/ui/hooks.dart | 147 ++++++++++++++++++++++-- lib/ui/platform_dispatcher.dart | 115 +++--------------- lib/ui/window/platform_configuration.cc | 22 ++-- lib/ui/window/platform_configuration.h | 9 +- lib/ui/window/window.cc | 73 ++++++++---- lib/ui/window/window.h | 4 + runtime/runtime_controller.cc | 12 +- runtime/runtime_controller.h | 17 +-- shell/common/engine.cc | 5 +- shell/common/engine.h | 18 +-- shell/common/shell.cc | 7 +- shell/common/shell.h | 5 +- shell/common/shell_unittests.cc | 6 +- 13 files changed, 257 insertions(+), 183 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index 16015c319d44c..5c2244d43a9ad 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -5,13 +5,57 @@ part of dart.ui; @pragma('vm:entry-point') -void _addView(int id) { - PlatformDispatcher.instance._addView(id); +void _addView( + int viewId, + double devicePixelRatio, + double width, + double height, + double viewPaddingTop, + double viewPaddingRight, + double viewPaddingBottom, + double viewPaddingLeft, + double viewInsetTop, + double viewInsetRight, + double viewInsetBottom, + double viewInsetLeft, + double systemGestureInsetTop, + double systemGestureInsetRight, + double systemGestureInsetBottom, + double systemGestureInsetLeft, + double physicalTouchSlop, + List displayFeaturesBounds, + List displayFeaturesType, + List displayFeaturesState, + int displayId, +) { + final _ViewConfiguration viewConfiguration = _buildViewConfiguration( + devicePixelRatio, + width, + height, + viewPaddingTop, + viewPaddingRight, + viewPaddingBottom, + viewPaddingLeft, + viewInsetTop, + viewInsetRight, + viewInsetBottom, + viewInsetLeft, + systemGestureInsetTop, + systemGestureInsetRight, + systemGestureInsetBottom, + systemGestureInsetLeft, + physicalTouchSlop, + displayFeaturesBounds, + displayFeaturesType, + displayFeaturesState, + displayId, + ); + PlatformDispatcher.instance._addView(viewId, viewConfiguration); } @pragma('vm:entry-point') -void _removeView(int id) { - PlatformDispatcher.instance._removeView(id); +void _removeView(int viewId) { + PlatformDispatcher.instance._removeView(viewId); } @pragma('vm:entry-point') @@ -40,9 +84,98 @@ void _updateDisplays( PlatformDispatcher.instance._updateDisplays(displays); } +List _decodeDisplayFeatures({ + required List bounds, + required List type, + required List state, + required double devicePixelRatio, +}) { + assert(bounds.length / 4 == type.length, 'Bounds are rectangles, requiring 4 measurements each'); + assert(type.length == state.length); + final List result = []; + for(int i = 0; i < type.length; i++) { + final int rectOffset = i * 4; + result.add(DisplayFeature( + bounds: Rect.fromLTRB( + bounds[rectOffset] / devicePixelRatio, + bounds[rectOffset + 1] / devicePixelRatio, + bounds[rectOffset + 2] / devicePixelRatio, + bounds[rectOffset + 3] / devicePixelRatio, + ), + type: DisplayFeatureType.values[type[i]], + state: state[i] < DisplayFeatureState.values.length + ? DisplayFeatureState.values[state[i]] + : DisplayFeatureState.unknown, + )); + } + return result; +} + +_ViewConfiguration _buildViewConfiguration( + double devicePixelRatio, + double width, + double height, + double viewPaddingTop, + double viewPaddingRight, + double viewPaddingBottom, + double viewPaddingLeft, + double viewInsetTop, + double viewInsetRight, + double viewInsetBottom, + double viewInsetLeft, + double systemGestureInsetTop, + double systemGestureInsetRight, + double systemGestureInsetBottom, + double systemGestureInsetLeft, + double physicalTouchSlop, + List displayFeaturesBounds, + List displayFeaturesType, + List displayFeaturesState, + int displayId, +) { + return _ViewConfiguration( + devicePixelRatio: devicePixelRatio, + geometry: Rect.fromLTWH(0.0, 0.0, width, height), + viewPadding: ViewPadding._( + top: viewPaddingTop, + right: viewPaddingRight, + bottom: viewPaddingBottom, + left: viewPaddingLeft, + ), + viewInsets: ViewPadding._( + top: viewInsetTop, + right: viewInsetRight, + bottom: viewInsetBottom, + left: viewInsetLeft, + ), + padding: ViewPadding._( + top: math.max(0.0, viewPaddingTop - viewInsetTop), + right: math.max(0.0, viewPaddingRight - viewInsetRight), + bottom: math.max(0.0, viewPaddingBottom - viewInsetBottom), + left: math.max(0.0, viewPaddingLeft - viewInsetLeft), + ), + systemGestureInsets: ViewPadding._( + top: math.max(0.0, systemGestureInsetTop), + right: math.max(0.0, systemGestureInsetRight), + bottom: math.max(0.0, systemGestureInsetBottom), + left: math.max(0.0, systemGestureInsetLeft), + ), + gestureSettings: GestureSettings( + physicalTouchSlop: physicalTouchSlop == _kUnsetGestureSetting ? null : physicalTouchSlop, + ), + displayFeatures: _decodeDisplayFeatures( + bounds: displayFeaturesBounds, + type: displayFeaturesType, + state: displayFeaturesState, + devicePixelRatio: devicePixelRatio, + ), + displayId: displayId, + ); +} + @pragma('vm:entry-point') void _updateWindowMetrics( - int id, + int viewId, double devicePixelRatio, double width, double height, @@ -64,8 +197,7 @@ void _updateWindowMetrics( List displayFeaturesState, int displayId, ) { - PlatformDispatcher.instance._updateWindowMetrics( - id, + final _ViewConfiguration viewConfiguration = _buildViewConfiguration( devicePixelRatio, width, height, @@ -87,6 +219,7 @@ void _updateWindowMetrics( displayFeaturesState, displayId, ); + PlatformDispatcher.instance._updateWindowMetrics(viewId, viewConfiguration); } typedef _LocaleClosure = String Function(); diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index e156bd90ab3aa..4dfb1ae119231 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -117,7 +117,7 @@ class PlatformDispatcher { PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; if (_implicitViewId != null) { - _insertNewView(_implicitViewId!); + _views[_implicitViewId!] = FlutterView._(_implicitViewId!, this, const _ViewConfiguration()); } } @@ -248,19 +248,27 @@ class PlatformDispatcher { _onMetricsChangedZone = Zone.current; } - void _insertNewView(int id) { - assert(!_views.containsKey(id), 'View ID $id already exists.'); - _views[id] = FlutterView._(id, this, const _ViewConfiguration()); - } - - void _addView(int id) { + // Called from the engine, via hooks.dart + // + // Adds a new view with the specific view configuration. If the target view is + // the implicit view, then it's equivalent to _updateWindowMetrics. + // Otherwise, the target view must not exist. + void _addView(int id, _ViewConfiguration viewConfiguration) { // The implicit view is added at construction. if (id != _implicitViewId) { - _insertNewView(id); + assert(!_views.containsKey(id), 'View ID $id already exists.'); + _views[id] = FlutterView._(id, this, viewConfiguration); + _invoke(onMetricsChanged, _onMetricsChangedZone); + } else { + _updateWindowMetrics(id, viewConfiguration); } - _invoke(onMetricsChanged, _onMetricsChangedZone); } + // Called from the engine, via hooks.dart + // + // Removes the specific view. + // + // The target view must not be the implicit view, and must exist. void _removeView(int id) { assert(id != _implicitViewId, 'The implicit view #$id can not be removed.'); assert(_views.containsKey(id), 'View ID $id does not exist.'); @@ -282,99 +290,12 @@ class PlatformDispatcher { // Called from the engine, via hooks.dart // // Updates the metrics of the window with the given id. - void _updateWindowMetrics( - int id, - double devicePixelRatio, - double width, - double height, - double viewPaddingTop, - double viewPaddingRight, - double viewPaddingBottom, - double viewPaddingLeft, - double viewInsetTop, - double viewInsetRight, - double viewInsetBottom, - double viewInsetLeft, - double systemGestureInsetTop, - double systemGestureInsetRight, - double systemGestureInsetBottom, - double systemGestureInsetLeft, - double physicalTouchSlop, - List displayFeaturesBounds, - List displayFeaturesType, - List displayFeaturesState, - int displayId, - ) { + void _updateWindowMetrics(int id, _ViewConfiguration viewConfiguration) { assert(_views.containsKey(id), 'View $id does not exist.'); - final _ViewConfiguration viewConfiguration = _ViewConfiguration( - devicePixelRatio: devicePixelRatio, - geometry: Rect.fromLTWH(0.0, 0.0, width, height), - viewPadding: ViewPadding._( - top: viewPaddingTop, - right: viewPaddingRight, - bottom: viewPaddingBottom, - left: viewPaddingLeft, - ), - viewInsets: ViewPadding._( - top: viewInsetTop, - right: viewInsetRight, - bottom: viewInsetBottom, - left: viewInsetLeft, - ), - padding: ViewPadding._( - top: math.max(0.0, viewPaddingTop - viewInsetTop), - right: math.max(0.0, viewPaddingRight - viewInsetRight), - bottom: math.max(0.0, viewPaddingBottom - viewInsetBottom), - left: math.max(0.0, viewPaddingLeft - viewInsetLeft), - ), - systemGestureInsets: ViewPadding._( - top: math.max(0.0, systemGestureInsetTop), - right: math.max(0.0, systemGestureInsetRight), - bottom: math.max(0.0, systemGestureInsetBottom), - left: math.max(0.0, systemGestureInsetLeft), - ), - gestureSettings: GestureSettings( - physicalTouchSlop: physicalTouchSlop == _kUnsetGestureSetting ? null : physicalTouchSlop, - ), - displayFeatures: _decodeDisplayFeatures( - bounds: displayFeaturesBounds, - type: displayFeaturesType, - state: displayFeaturesState, - devicePixelRatio: devicePixelRatio, - ), - displayId: displayId, - ); - _views[id]!._viewConfiguration = viewConfiguration; _invoke(onMetricsChanged, _onMetricsChangedZone); } - List _decodeDisplayFeatures({ - required List bounds, - required List type, - required List state, - required double devicePixelRatio, - }) { - assert(bounds.length / 4 == type.length, 'Bounds are rectangles, requiring 4 measurements each'); - assert(type.length == state.length); - final List result = []; - for(int i = 0; i < type.length; i++) { - final int rectOffset = i * 4; - result.add(DisplayFeature( - bounds: Rect.fromLTRB( - bounds[rectOffset] / devicePixelRatio, - bounds[rectOffset + 1] / devicePixelRatio, - bounds[rectOffset + 2] / devicePixelRatio, - bounds[rectOffset + 3] / devicePixelRatio, - ), - type: DisplayFeatureType.values[type[i]], - state: state[i] < DisplayFeatureState.values.length - ? DisplayFeatureState.values[state[i]] - : DisplayFeatureState.unknown, - )); - } - return result; - } /// A callback invoked when any view begins a frame. /// diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index bea3d118089aa..a1cd36a72f0b7 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -41,8 +41,6 @@ void PlatformConfiguration::DidCreateIsolate() { on_error_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_onError"))); - add_view_.Set(tonic::DartState::Current(), - Dart_GetField(library, tonic::ToDart("_addView"))); remove_view_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_removeView"))); update_displays_.Set( @@ -81,19 +79,13 @@ void PlatformConfiguration::DidCreateIsolate() { library_.Set(tonic::DartState::Current(), library); } -void PlatformConfiguration::AddView(int64_t view_id) { - windows_.emplace( - view_id, std::make_unique(library_, view_id, - ViewportMetrics{1.0, 0.0, 0.0, -1, 0})); - std::shared_ptr dart_state = add_view_.dart_state().lock(); - if (!dart_state) { - return; - } - tonic::DartState::Scope scope(dart_state); - tonic::CheckAndHandleError( - tonic::DartInvoke(add_view_.Get(), { - tonic::ToDart(view_id), - })); +void PlatformConfiguration::AddView(int64_t view_id, + const ViewportMetrics& view_metrics) { + auto [window_iterator, insertion_happened] = windows_.emplace( + view_id, std::make_unique(library_, view_id, view_metrics)); + FML_DCHECK(insertion_happened); + // Make the new window send an AddView message to Dart. + window_iterator->second->AddView(); } void PlatformConfiguration::RemoveView(int64_t view_id) { diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 781be7878f706..44a91b16083ce 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -271,12 +271,12 @@ class PlatformConfiguration final { //---------------------------------------------------------------------------- /// @brief Notify the framework that a new view is available. /// - /// The implicit view might be called with this method, which - /// will be a no-op. + /// The implicit view should also be added with this method. /// - /// @param[in] view_id The ID of the new view. + /// @param[in] view_id The ID of the new view. + /// @param[in] viewport_metrics The initial viewport metrics for the view. /// - void AddView(int64_t view_id); + void AddView(int64_t view_id, const ViewportMetrics& view_metrics); //---------------------------------------------------------------------------- /// @brief Notify the framework that a view is no longer available. @@ -463,7 +463,6 @@ class PlatformConfiguration final { private: PlatformConfigurationClient* client_; tonic::DartPersistentValue on_error_; - tonic::DartPersistentValue add_view_; tonic::DartPersistentValue remove_view_; tonic::DartPersistentValue update_displays_; tonic::DartPersistentValue update_locales_; diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc index 45c8c2693190d..0800f10d31206 100644 --- a/lib/ui/window/window.cc +++ b/lib/ui/window/window.cc @@ -22,6 +22,39 @@ Window::Window(tonic::DartPersistentValue& library, Window::~Window() {} +void Window::AddView() { + std::shared_ptr dart_state = library_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError(tonic::DartInvokeField( + library_.value(), "_addView", + { + tonic::ToDart(window_id_), + tonic::ToDart(viewport_metrics_.device_pixel_ratio), + tonic::ToDart(viewport_metrics_.physical_width), + tonic::ToDart(viewport_metrics_.physical_height), + tonic::ToDart(viewport_metrics_.physical_padding_top), + tonic::ToDart(viewport_metrics_.physical_padding_right), + tonic::ToDart(viewport_metrics_.physical_padding_bottom), + tonic::ToDart(viewport_metrics_.physical_padding_left), + tonic::ToDart(viewport_metrics_.physical_view_inset_top), + tonic::ToDart(viewport_metrics_.physical_view_inset_right), + tonic::ToDart(viewport_metrics_.physical_view_inset_bottom), + tonic::ToDart(viewport_metrics_.physical_view_inset_left), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_top), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_right), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_bottom), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_left), + tonic::ToDart(viewport_metrics_.physical_touch_slop), + tonic::ToDart(viewport_metrics_.physical_display_features_bounds), + tonic::ToDart(viewport_metrics_.physical_display_features_type), + tonic::ToDart(viewport_metrics_.physical_display_features_state), + tonic::ToDart(viewport_metrics_.display_id), + })); +} + void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) { viewport_metrics_ = metrics; @@ -34,26 +67,26 @@ void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) { library_.value(), "_updateWindowMetrics", { tonic::ToDart(window_id_), - tonic::ToDart(metrics.device_pixel_ratio), - tonic::ToDart(metrics.physical_width), - tonic::ToDart(metrics.physical_height), - tonic::ToDart(metrics.physical_padding_top), - tonic::ToDart(metrics.physical_padding_right), - tonic::ToDart(metrics.physical_padding_bottom), - tonic::ToDart(metrics.physical_padding_left), - tonic::ToDart(metrics.physical_view_inset_top), - tonic::ToDart(metrics.physical_view_inset_right), - tonic::ToDart(metrics.physical_view_inset_bottom), - tonic::ToDart(metrics.physical_view_inset_left), - tonic::ToDart(metrics.physical_system_gesture_inset_top), - tonic::ToDart(metrics.physical_system_gesture_inset_right), - tonic::ToDart(metrics.physical_system_gesture_inset_bottom), - tonic::ToDart(metrics.physical_system_gesture_inset_left), - tonic::ToDart(metrics.physical_touch_slop), - tonic::ToDart(metrics.physical_display_features_bounds), - tonic::ToDart(metrics.physical_display_features_type), - tonic::ToDart(metrics.physical_display_features_state), - tonic::ToDart(metrics.display_id), + tonic::ToDart(viewport_metrics_.device_pixel_ratio), + tonic::ToDart(viewport_metrics_.physical_width), + tonic::ToDart(viewport_metrics_.physical_height), + tonic::ToDart(viewport_metrics_.physical_padding_top), + tonic::ToDart(viewport_metrics_.physical_padding_right), + tonic::ToDart(viewport_metrics_.physical_padding_bottom), + tonic::ToDart(viewport_metrics_.physical_padding_left), + tonic::ToDart(viewport_metrics_.physical_view_inset_top), + tonic::ToDart(viewport_metrics_.physical_view_inset_right), + tonic::ToDart(viewport_metrics_.physical_view_inset_bottom), + tonic::ToDart(viewport_metrics_.physical_view_inset_left), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_top), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_right), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_bottom), + tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_left), + tonic::ToDart(viewport_metrics_.physical_touch_slop), + tonic::ToDart(viewport_metrics_.physical_display_features_bounds), + tonic::ToDart(viewport_metrics_.physical_display_features_type), + tonic::ToDart(viewport_metrics_.physical_display_features_state), + tonic::ToDart(viewport_metrics_.display_id), })); } diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h index 67ef8198fe800..c02a2628eca45 100644 --- a/lib/ui/window/window.h +++ b/lib/ui/window/window.h @@ -30,6 +30,10 @@ class Window final { const ViewportMetrics& viewport_metrics() const { return viewport_metrics_; } + // Send an AddView message to Dart with the current view metrics. + void AddView(); + + // Update view metrics, and send an UpdateWindowMetrics message to Dart. void UpdateWindowMetrics(const ViewportMetrics& metrics); private: diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 289279c5b76e8..fb96303d6d71d 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -115,10 +115,7 @@ std::unique_ptr RuntimeController::Clone() const { bool RuntimeController::FlushRuntimeStateToIsolate() { for (auto const& [view_id, viewport_metrics] : platform_data_.viewport_metrics_for_views) { - if (!AddView(view_id)) { - return false; - } - if (!SetViewportMetrics(view_id, viewport_metrics)) { + if (!AddView(view_id, viewport_metrics)) { return false; } } @@ -131,10 +128,11 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { SetDisplays(platform_data_.displays); } -bool RuntimeController::AddView(int64_t view_id) { - platform_data_.viewport_metrics_for_views[view_id] = ViewportMetrics(); +bool RuntimeController::AddView(int64_t view_id, ViewportMetrics view_metrics) { + platform_data_.viewport_metrics_for_views[view_id] = view_metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { - platform_configuration->AddView(view_id); + platform_configuration->AddView(view_id, view_metrics); + return true; } diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 450fac24412d2..5d6f171066fea 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -164,22 +164,17 @@ class RuntimeController : public PlatformConfigurationClient { std::unique_ptr Clone() const; //---------------------------------------------------------------------------- - /// @brief Notify the running isolate that a new view is available. + /// @brief Notify the isolate that a new view is available. /// - /// If the isolate has not been started, this call is a noop. + /// The implicit view should also be added with this method. /// - /// The implicit view should not be added with this method. The - /// running isolate has its own way to create the implicit view on - /// initialization. + /// @param[in] view_id The ID of the new view. + /// @param[in] viewport_metrics The initial viewport metrics for the view. /// - /// @param[in] view_id The ID of the new view. - /// - bool AddView(int64_t view_id); + bool AddView(int64_t view_id, ViewportMetrics view_metrics); //---------------------------------------------------------------------------- - /// @brief Notify the running isolate that a view is no longer available. - /// - /// If the isolate has not been started, this call is a noop. + /// @brief Notify the isolate that a view is no longer available. /// /// The implicit view should not be removed with this method, /// since it should never be removed. diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 9f50236002241..51f1744f234b4 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -292,8 +292,9 @@ tonic::DartErrorHandleType Engine::GetUIIsolateLastError() { return runtime_controller_->GetLastError(); } -void Engine::AddView(int64_t view_id) { - runtime_controller_->AddView(view_id); +void Engine::AddView(int64_t view_id, const ViewportMetrics& view_metrics) { + runtime_controller_->AddView(view_id, view_metrics); + ScheduleFrame(); } void Engine::RemoveView(int64_t view_id) { diff --git a/shell/common/engine.h b/shell/common/engine.h index 0580770b80fa3..ca3e88f973ace 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -676,25 +676,19 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::optional GetUIIsolateReturnCode(); //---------------------------------------------------------------------------- - /// @brief Notify the running Flutter application that a new view is - /// available. + /// @brief Notify the Flutter application that a new view is available. /// - /// If the application is not running, this call is a noop. + /// The implicit view should also be added with this method. /// - /// The implicit view should not be added with this method. The - /// framework has its own way to create the implicit view on - /// initialization. + /// @param[in] view_id The ID of the new view. + /// @param[in] viewport_metrics The initial viewport metrics for the view. /// - /// @param[in] view_id The ID of the new view. - /// - void AddView(int64_t view_id); + void AddView(int64_t view_id, const ViewportMetrics& view_metrics); //---------------------------------------------------------------------------- - /// @brief Notify the running Flutter application that a view is no + /// @brief Notify the Flutter application that a view is no /// longer available. /// - /// If the application is not running, this call is a noop. - /// /// The implicit view should not be removed with this method, /// since it should never be removed. /// diff --git a/shell/common/shell.cc b/shell/common/shell.cc index ea25765cd8335..0fb6a9293d0e7 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -831,7 +831,7 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { if (engine) { engine->ScheduleFrame(); if (enable_implicit_view) { - engine->AddView(kFlutterImplicitViewId); + engine->AddView(kFlutterImplicitViewId, ViewportMetrics{}); } } }; @@ -2039,7 +2039,7 @@ bool Shell::OnServiceProtocolReloadAssetFonts( return true; } -void Shell::AddView(int64_t view_id) { +void Shell::AddView(int64_t view_id, const ViewportMetrics& viewport_metrics) { TRACE_EVENT0("flutter", "Shell::AddView"); FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); @@ -2051,10 +2051,11 @@ void Shell::AddView(int64_t view_id) { } task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // + viewport_metrics, // view_id // ] { if (engine) { - engine->AddView(view_id); + engine->AddView(view_id, viewport_metrics); } }); diff --git a/shell/common/shell.h b/shell/common/shell.h index 047950065142c..f25717a928540 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -310,9 +310,10 @@ class Shell final : public PlatformView::Delegate, /// on `Settings.enable_implicit_view`. Trying to add /// `kFlutterImplicitViewId` is a no-op with warning. /// - /// @param[in] view_id The view ID of the new view. + /// @param[in] view_id The view ID of the new view. + /// @param[in] viewport_metrics The initial viewport metrics for the view. /// - void AddView(int64_t view_id); + void AddView(int64_t view_id, const ViewportMetrics& viewport_metrics); /// @brief Removes a non-implicit view. /// diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index accf1925eed7f..ce02772ce3bb4 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4474,7 +4474,8 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { ASSERT_EQ(viewIds.size(), 1u); ASSERT_EQ(viewIds[0], 0ll); - RunOnPlatformTaskRunner(*shell, [&shell] { shell->AddView(2); }); + RunOnPlatformTaskRunner(*shell, + [&shell] { shell->AddView(2, ViewportMetrics{}); }); reportLatch.Wait(); ASSERT_TRUE(hasImplicitView); ASSERT_EQ(viewIds.size(), 2u); @@ -4486,7 +4487,8 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { ASSERT_EQ(viewIds.size(), 1u); ASSERT_EQ(viewIds[0], 0ll); - RunOnPlatformTaskRunner(*shell, [&shell] { shell->AddView(4); }); + RunOnPlatformTaskRunner(*shell, + [&shell] { shell->AddView(4, ViewportMetrics{}); }); reportLatch.Wait(); ASSERT_TRUE(hasImplicitView); ASSERT_EQ(viewIds.size(), 2u); From a898834d6291aff51747354fdb47bacdb13cd5cd Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Jul 2023 15:23:00 -0700 Subject: [PATCH 23/46] Remove ImplicitViewEnabled from more and lint --- lib/ui/window/platform_configuration.h | 12 ------------ runtime/runtime_controller.cc | 7 +------ runtime/runtime_controller.h | 5 +---- runtime/runtime_delegate.h | 2 -- shell/common/engine.cc | 8 -------- shell/common/engine.h | 3 --- 6 files changed, 2 insertions(+), 35 deletions(-) diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 44a91b16083ce..3d95c1ebe8f18 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -50,16 +50,6 @@ enum class AccessibilityFeatureFlag : int32_t { /// class PlatformConfigurationClient { public: - //-------------------------------------------------------------------------- - /// @brief Whether the platform provides an implicit view. If true, - /// the Framework may assume that it can always render into - /// the view with ID 0. - /// - /// This value must not change for the lifetime of the - /// application. - /// - virtual bool ImplicitViewEnabled() = 0; - //-------------------------------------------------------------------------- /// @brief The route or path that the embedder requested when the /// application was launched. @@ -486,8 +476,6 @@ class PlatformConfiguration final { int next_response_id_ = 1; std::unordered_map> pending_responses_; - - void InsertNewView(int64_t view_id); }; //---------------------------------------------------------------------------- diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index fb96303d6d71d..88515f93e06aa 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -128,7 +128,7 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { SetDisplays(platform_data_.displays); } -bool RuntimeController::AddView(int64_t view_id, ViewportMetrics view_metrics) { +bool RuntimeController::AddView(int64_t view_id, const ViewportMetrics& view_metrics) { platform_data_.viewport_metrics_for_views[view_id] = view_metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->AddView(view_id, view_metrics); @@ -332,11 +332,6 @@ RuntimeController::GetPlatformConfigurationIfAvailable() { return root_isolate ? root_isolate->platform_configuration() : nullptr; } -// |PlatformConfigurationClient| -bool RuntimeController::ImplicitViewEnabled() { - return client_.ImplicitViewEnabled(); -} - // |PlatformConfigurationClient| std::string RuntimeController::DefaultRouteName() { return client_.DefaultRouteName(); diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 5d6f171066fea..cafc74ed138f1 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -171,7 +171,7 @@ class RuntimeController : public PlatformConfigurationClient { /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. /// - bool AddView(int64_t view_id, ViewportMetrics view_metrics); + bool AddView(int64_t view_id, const ViewportMetrics& view_metrics); //---------------------------------------------------------------------------- /// @brief Notify the isolate that a view is no longer available. @@ -641,9 +641,6 @@ class RuntimeController : public PlatformConfigurationClient { bool FlushRuntimeStateToIsolate(); - // |PlatformConfigurationClient| - bool ImplicitViewEnabled() override; - // |PlatformConfigurationClient| std::string DefaultRouteName() override; diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 18e4dbfdfd31c..330fc46e1d6a5 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -21,8 +21,6 @@ namespace flutter { class RuntimeDelegate { public: - virtual bool ImplicitViewEnabled() = 0; - virtual std::string DefaultRouteName() = 0; virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 51f1744f234b4..baa496eee36b9 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -447,14 +447,6 @@ void Engine::SetAccessibilityFeatures(int32_t flags) { runtime_controller_->SetAccessibilityFeatures(flags); } -bool Engine::ImplicitViewEnabled() { - // TODO(loicsharma): This value should be provided by the embedder - // when it launches the engine. For now, assume the embedder always creates a - // view. - // See: https://github.com/flutter/flutter/issues/120306 - return true; -} - std::string Engine::DefaultRouteName() { if (!initial_route_.empty()) { return initial_route_; diff --git a/shell/common/engine.h b/shell/common/engine.h index ca3e88f973ace..c000062230df0 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -919,9 +919,6 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { const std::weak_ptr GetVsyncWaiter() const; private: - // |RuntimeDelegate| - bool ImplicitViewEnabled() override; - // |RuntimeDelegate| std::string DefaultRouteName() override; From 2ff8609fd00cc12cd91743ea0e3639e4f194bdfb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Jul 2023 17:08:50 -0700 Subject: [PATCH 24/46] Fix test and lint --- lib/ui/window/platform_configuration_unittests.cc | 2 ++ runtime/runtime_controller.cc | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ui/window/platform_configuration_unittests.cc b/lib/ui/window/platform_configuration_unittests.cc index 017055a41d91e..011806a191cd5 100644 --- a/lib/ui/window/platform_configuration_unittests.cc +++ b/lib/ui/window/platform_configuration_unittests.cc @@ -28,6 +28,7 @@ TEST_F(PlatformConfigurationTest, Initialization) { Dart_NativeArguments args) { PlatformConfiguration* configuration = UIDartState::Current()->platform_configuration(); + configuration->AddView(0, ViewportMetrics{}); ASSERT_NE(configuration->get_window(0), nullptr); ASSERT_EQ( configuration->get_window(0)->viewport_metrics().device_pixel_ratio, @@ -72,6 +73,7 @@ TEST_F(PlatformConfigurationTest, WindowMetricsUpdate) { Dart_NativeArguments args) { PlatformConfiguration* configuration = UIDartState::Current()->platform_configuration(); + configuration->AddView(0, ViewportMetrics{}); ASSERT_NE(configuration->get_window(0), nullptr); configuration->get_window(0)->UpdateWindowMetrics( diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 88515f93e06aa..51812f6551303 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -128,7 +128,8 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { SetDisplays(platform_data_.displays); } -bool RuntimeController::AddView(int64_t view_id, const ViewportMetrics& view_metrics) { +bool RuntimeController::AddView(int64_t view_id, + const ViewportMetrics& view_metrics) { platform_data_.viewport_metrics_for_views[view_id] = view_metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->AddView(view_id, view_metrics); From c61cf67e913a6c0600b8391f0c332339a61c68cd Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 14:02:52 -0700 Subject: [PATCH 25/46] Fix tests? --- .../platform_configuration_unittests.cc | 2 -- shell/common/engine.cc | 1 - shell/common/rasterizer.cc | 7 +---- shell/common/rasterizer.h | 16 +++------- shell/common/rasterizer_unittests.cc | 17 ---------- shell/common/shell.cc | 31 +++++-------------- 6 files changed, 14 insertions(+), 60 deletions(-) diff --git a/lib/ui/window/platform_configuration_unittests.cc b/lib/ui/window/platform_configuration_unittests.cc index 011806a191cd5..017055a41d91e 100644 --- a/lib/ui/window/platform_configuration_unittests.cc +++ b/lib/ui/window/platform_configuration_unittests.cc @@ -28,7 +28,6 @@ TEST_F(PlatformConfigurationTest, Initialization) { Dart_NativeArguments args) { PlatformConfiguration* configuration = UIDartState::Current()->platform_configuration(); - configuration->AddView(0, ViewportMetrics{}); ASSERT_NE(configuration->get_window(0), nullptr); ASSERT_EQ( configuration->get_window(0)->viewport_metrics().device_pixel_ratio, @@ -73,7 +72,6 @@ TEST_F(PlatformConfigurationTest, WindowMetricsUpdate) { Dart_NativeArguments args) { PlatformConfiguration* configuration = UIDartState::Current()->platform_configuration(); - configuration->AddView(0, ViewportMetrics{}); ASSERT_NE(configuration->get_window(0), nullptr); configuration->get_window(0)->UpdateWindowMetrics( diff --git a/shell/common/engine.cc b/shell/common/engine.cc index baa496eee36b9..88976295297c4 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -294,7 +294,6 @@ tonic::DartErrorHandleType Engine::GetUIIsolateLastError() { void Engine::AddView(int64_t view_id, const ViewportMetrics& view_metrics) { runtime_controller_->AddView(view_id, view_metrics); - ScheduleFrame(); } void Engine::RemoveView(int64_t view_id) { diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index ec12231445b70..9ee70a58ebd74 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -156,12 +156,7 @@ void Rasterizer::NotifyLowMemoryWarning() const { context->performDeferredCleanup(std::chrono::milliseconds(0)); } -void Rasterizer::AddView(int64_t view_id) { - // TODO(dkwingsmt): Support proper view management after Rasterizer supports - // multi-view. -} - -void Rasterizer::RemoveView(int64_t view_id) { +void Rasterizer::CollectView(int64_t view_id) { // TODO(dkwingsmt): Support proper view management after Rasterizer supports // multi-view. } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 7d42d49d73cc3..35575ac7c2ca5 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -205,22 +205,16 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; //---------------------------------------------------------------------------- - /// @brief Create the resources for displaying a view. - /// - /// This method should be called a view is added, implicit or not. - /// - /// @param[in] view_id The ID of the new view. - /// - void AddView(int64_t view_id); - - //---------------------------------------------------------------------------- - /// @brief Destroy the resources for displaying a view. + /// @brief Deallocate the resources for displaying a view. /// /// This method should be called a view is removed. /// + /// Resources for a view is allocated the first time the + /// rasterizer encouters this view ID. + /// /// @param[in] view_id The ID of the view. /// - void RemoveView(int64_t view_id); + void CollectView(int64_t view_id); //---------------------------------------------------------------------------- /// @brief Sometimes, it may be necessary to render the same frame again diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 4ec1699326209..976b0bee38acc 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -30,7 +30,6 @@ using testing::ReturnRef; namespace flutter { namespace { -constexpr int64_t kImplicitViewId = 0; constexpr float kDevicePixelRatio = 2.0f; class MockDelegate : public Rasterizer::Delegate { @@ -127,7 +126,6 @@ TEST(RasterizerTest, drawEmptyPipeline) { EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -189,7 +187,6 @@ TEST(RasterizerTest, .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -257,7 +254,6 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -331,7 +327,6 @@ TEST( .Times(1); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -406,7 +401,6 @@ TEST(RasterizerTest, .Times(2); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -498,7 +492,6 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -557,7 +550,6 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); EXPECT_CALL( *external_view_embedder, @@ -616,7 +608,6 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -675,7 +666,6 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -734,7 +724,6 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -792,7 +781,6 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -849,7 +837,6 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -930,7 +917,6 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -985,7 +971,6 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1102,7 +1087,6 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -1184,7 +1168,6 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); - rasterizer->AddView(kImplicitViewId); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 0fb6a9293d0e7..515eb99a0587f 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -713,6 +713,9 @@ bool Shell::Setup(std::unique_ptr platform_view, weak_rasterizer_ = rasterizer_->GetWeakPtr(); weak_platform_view_ = platform_view_->GetWeakPtr(); + if (settings_.enable_implicit_view) { + engine_->AddView(kFlutterImplicitViewId, ViewportMetrics{}); + } // Setup the time-consuming default font manager right after engine created. if (!settings_.prefetched_default_font_manager) { fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(), @@ -807,32 +810,23 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { fml::AutoResetWaitableEvent latch; auto raster_task = fml::MakeCopyable( - [&waiting_for_first_frame = waiting_for_first_frame_, // - rasterizer = rasterizer_->GetWeakPtr(), // - surface = std::move(surface), // - enable_implicit_view = settings_.enable_implicit_view // + [&waiting_for_first_frame = waiting_for_first_frame_, // + rasterizer = rasterizer_->GetWeakPtr(), // + surface = std::move(surface) // ]() mutable { if (rasterizer) { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); rasterizer->Setup(std::move(surface)); - if (enable_implicit_view) { - rasterizer->AddView(kFlutterImplicitViewId); - } } waiting_for_first_frame.store(true); }); - auto ui_task = [engine = engine_->GetWeakPtr(), // - enable_implicit_view = settings_.enable_implicit_view // - ] { + auto ui_task = [engine = engine_->GetWeakPtr()] { if (engine) { engine->ScheduleFrame(); - if (enable_implicit_view) { - engine->AddView(kFlutterImplicitViewId, ViewportMetrics{}); - } } }; @@ -2058,15 +2052,6 @@ void Shell::AddView(int64_t view_id, const ViewportMetrics& viewport_metrics) { engine->AddView(view_id, viewport_metrics); } }); - - task_runners_.GetRasterTaskRunner()->PostTask( - [rasterizer = rasterizer_->GetWeakPtr(), // - view_id // - ]() { - if (rasterizer) { - rasterizer->AddView(view_id); - } - }); } void Shell::RemoveView(int64_t view_id) { @@ -2097,7 +2082,7 @@ void Shell::RemoveView(int64_t view_id) { view_id // ]() { if (rasterizer) { - rasterizer->RemoveView(view_id); + rasterizer->CollectView(view_id); } latch.Signal(); }); From d9fc2a5ec90607d38838f04303b7b71dd3a5c675 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 17:12:19 -0700 Subject: [PATCH 26/46] Shell Add/RemoveView blocking --- shell/common/shell.cc | 28 ++++++++++++++++------------ shell/common/shell.h | 6 +++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 515eb99a0587f..dbeea866bf758 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2068,24 +2068,28 @@ void Shell::RemoveView(int64_t view_id) { expected_frame_sizes_.erase(view_id); fml::AutoResetWaitableEvent latch; - task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // - view_id // - ] { - if (engine) { - engine->RemoveView(view_id); - } - }); - - task_runners_.GetRasterTaskRunner()->PostTask( + task_runners_.GetUITaskRunner()->PostTask( [&latch, // + & task_runners = task_runners_, // + engine = engine_->GetWeakPtr(), // rasterizer = rasterizer_->GetWeakPtr(), // view_id // - ]() { - if (rasterizer) { - rasterizer->CollectView(view_id); + ] { + if (engine) { + engine->RemoveView(view_id); } + // Don't wait for the raster task here, which only cleans up memory and + // does not affect functionality. Make sure it is done after Dart + // removes the view to avoid receiving another rasterization request + // that adds back the view record. + task_runners.GetRasterTaskRunner()->PostTask([rasterizer, view_id]() { + if (rasterizer) { + rasterizer->CollectView(view_id); + } + }); latch.Signal(); }); + latch.Wait(); } diff --git a/shell/common/shell.h b/shell/common/shell.h index f25717a928540..231bcb1f8814f 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -301,9 +301,9 @@ class Shell final : public PlatformView::Delegate, /// @brief Adds a non-implicit view. /// /// This method returns immediately and does not wait for the tasks - /// on the rasterizer thread and the UI thread to finish. This is - /// because the rasterizer thread can be blocked by the platform - /// thread to render platform views. + /// on the UI thread to finish. This is because operations are either + /// initiated from the UI thread (such as rendering), or are sent as a + /// posted task that is queued. /// /// The implicit view should never be added with this function. /// Instead, it is added internally on Shell initialization depending From 89755d28d196584af8ae78a7d509bf9f10ee4bda Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 17:16:51 -0700 Subject: [PATCH 27/46] Implement Rasterizer::CollectView --- shell/common/rasterizer.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 9ee70a58ebd74..3408d1d7e17c0 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -157,8 +157,9 @@ void Rasterizer::NotifyLowMemoryWarning() const { } void Rasterizer::CollectView(int64_t view_id) { - // TODO(dkwingsmt): Support proper view management after Rasterizer supports - // multi-view. + if (view_id == kFlutterImplicitViewId) { + last_layer_tree_.reset(); + } } std::shared_ptr Rasterizer::GetTextureRegistry() { From 42db5c39fea0a8b4b1a04d5d925e6d357d38f0ee Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 23:23:50 -0700 Subject: [PATCH 28/46] Flushing test --- shell/common/fixtures/shell_test.dart | 25 +++++++++ shell/common/shell_unittests.cc | 78 +++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index d69a5db501332..05fc9394bcbf9 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -523,3 +523,28 @@ void testReportViewIds() { } }; } + +// Returns a list of [view_id 1, view_width 1, view_id 2, view_width 2, ...] +// for all views. +List getCurrentViewWidths() { + final List result = []; + for (final FlutterView view in PlatformDispatcher.instance.views) { + result.add(view.viewId); + result.add(view.physicalGeometry.width.round()); + } + return result; +} + +@pragma('vm:external-name', 'NativeReportViewWidthsCallback') +external void nativeReportViewWidthsCallback(List viewWidthPacket); + +// This entrypoint reports whether there's an implicit view and the list of view +// IDs using nativeReportViewIdsCallback on initialization and every +// onMetricsChanged. +@pragma('vm:entry-point') +void testReportViewWidths() { + nativeReportViewWidthsCallback(getCurrentViewWidths()); + PlatformDispatcher.instance.onMetricsChanged = () { + nativeReportViewWidthsCallback(getCurrentViewWidths()); + }; +} diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index ce02772ce3bb4..b55788365c6f6 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4368,6 +4368,8 @@ static void RunOnPlatformTaskRunner(Shell& shell, const fml::closure& task) { latch.Wait(); } +// Tests that Settings.enable_implicit_view being true causes the shell +// to begin with an implicit view. TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { Settings settings = CreateSettingsForFixture(); settings.enable_implicit_view = true; @@ -4403,6 +4405,8 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { DestroyShell(std::move(shell), task_runners); } +// Tests that Settings.enable_implicit_view being false causes the shell +// to begin without an implicit view. TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { Settings settings = CreateSettingsForFixture(); settings.enable_implicit_view = false; @@ -4437,6 +4441,7 @@ TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { DestroyShell(std::move(shell), task_runners); } +// Tests that Shell::AddView and Shell::RemoveView works. TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); @@ -4498,6 +4503,79 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { DestroyShell(std::move(shell), task_runners); } +// Parse the arguments of NativeReportViewWidthsCallback and +// store them in viewWidths. +static void ParseViewWidthsCallback(const Dart_NativeArguments& args, + std::map* viewWidths) { + Dart_Handle exception = nullptr; + viewWidths->clear(); + std::vector viewWidthPacket = + tonic::DartConverter>::FromArguments(args, 0, + exception); + ASSERT_EQ(exception, nullptr); + ASSERT_EQ(viewWidthPacket.size() % 2, 0ul); + for (size_t packetIndex = 0; packetIndex < viewWidthPacket.size(); + packetIndex += 2) { + (*viewWidths)[viewWidthPacket[packetIndex]] = + viewWidthPacket[packetIndex + 1]; + } +} + +// Tests that PlatformView::SetViewportMetrics and Shell::AddView that are +// dispatched before the engine is run are flushed to the Dart VM when the app +// starts. +TEST_F(ShellTest, ShellFlushesAccumulatedPlatformStates) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + Settings settings = CreateSettingsForFixture(); + settings.enable_implicit_view = true; + + ThreadHost thread_host(ThreadHost::ThreadHostConfig( + "io.flutter.test." + GetCurrentTestName() + ".", + ThreadHost::Type::Platform | ThreadHost::Type::RASTER | + ThreadHost::Type::IO | ThreadHost::Type::UI)); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + std::unique_ptr shell = CreateShell(settings, task_runners); + ASSERT_TRUE(shell); + + RunOnPlatformTaskRunner(*shell, [&shell] { + auto platform_view = shell->GetPlatformView(); + // The construtor for ViewportMetrics{_, width, _, _, _} (only the 2nd + // argument matters in this test). + platform_view->SetViewportMetrics(0, ViewportMetrics{1, 10, 1, 0, 0}); + shell->AddView(1, ViewportMetrics{1, 30, 1, 0, 0}); + platform_view->SetViewportMetrics(0, ViewportMetrics{1, 20, 1, 0, 0}); + }); + + bool first_report = true; + std::map viewWidths; + fml::AutoResetWaitableEvent reportLatch; + auto nativeViewWidthsCallback = [&reportLatch, &viewWidths, + &first_report](Dart_NativeArguments args) { + EXPECT_TRUE(first_report); + first_report = false; + ParseViewWidthsCallback(args, &viewWidths); + reportLatch.Signal(); + }; + AddNativeCallback("NativeReportViewWidthsCallback", + CREATE_NATIVE_ENTRY(nativeViewWidthsCallback)); + + PlatformViewNotifyCreated(shell.get()); + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("testReportViewWidths"); + RunEngine(shell.get(), std::move(configuration)); + + reportLatch.Wait(); + EXPECT_EQ(viewWidths.size(), 2u); + EXPECT_EQ(viewWidths[0], 20ll); + EXPECT_EQ(viewWidths[1], 30ll); + + PlatformViewNotifyDestroyed(shell.get()); + DestroyShell(std::move(shell), task_runners); +} + } // namespace testing } // namespace flutter From 164ca902a36198dc001b81319a5b673949a307cf Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 23:40:19 -0700 Subject: [PATCH 29/46] Add TODO doc --- lib/ui/window.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 77738233bfa84..6feeaf533dbd6 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -406,6 +406,9 @@ class SingletonFlutterWindow extends FlutterView { 'This feature was deprecated after v3.7.0-32.0.pre.' ) SingletonFlutterWindow._() : super._( + // TODO(dkwingsmt): This crashes if the implicit view is disabled. We need + // to resolve this by the end of phase 2 of the multi-window project. + // https://github.com/flutter/flutter/issues/131651 _implicitViewId!, PlatformDispatcher.instance, const _ViewConfiguration(), From 3e2902b0adffd6883823b82d686449fdd84f144b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 23:42:30 -0700 Subject: [PATCH 30/46] doc for implicit view ID. --- common/settings.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/settings.h b/common/settings.h index fe2e5d6d87820..ad6091f087bbf 100644 --- a/common/settings.h +++ b/common/settings.h @@ -22,6 +22,9 @@ namespace flutter { +// The ID for the implicit view if the implicit view is enabled. +// +// See Settings::enable_implicit_view for introduction. constexpr int64_t kFlutterImplicitViewId = 0; class FrameTiming { From 26d3cbe90097a4a0fb56ef854ca0cb7546065f39 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 23:44:00 -0700 Subject: [PATCH 31/46] Better doc --- lib/ui/window.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 6feeaf533dbd6..d86781ef2567f 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -407,7 +407,8 @@ class SingletonFlutterWindow extends FlutterView { ) SingletonFlutterWindow._() : super._( // TODO(dkwingsmt): This crashes if the implicit view is disabled. We need - // to resolve this by the end of phase 2 of the multi-window project. + // to resolve this by the time embedders are allowed to disable the implicit + // view. // https://github.com/flutter/flutter/issues/131651 _implicitViewId!, PlatformDispatcher.instance, From 8db91df2e89471d809772df5698249dcb44a148f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 31 Jul 2023 23:56:28 -0700 Subject: [PATCH 32/46] Bring back docs --- lib/ui/window/platform_configuration.h | 7 ++++--- runtime/runtime_controller.h | 7 ++++--- shell/common/engine.h | 8 +++++--- shell/common/rasterizer.h | 5 +++-- shell/common/shell.h | 17 +++++++++-------- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 3d95c1ebe8f18..c426056097624 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -261,7 +261,9 @@ class PlatformConfiguration final { //---------------------------------------------------------------------------- /// @brief Notify the framework that a new view is available. /// - /// The implicit view should also be added with this method. + /// A view must be added before other methods can refer to it, + /// including the implicit view. Adding a view that has been + /// added triggers assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -271,8 +273,7 @@ class PlatformConfiguration final { //---------------------------------------------------------------------------- /// @brief Notify the framework that a view is no longer available. /// - /// The implicit view should not be removed with this method, - /// since it should never be removed. + /// Removing a view that has not been added triggers assertion. /// /// @param[in] view_id The ID of the view. /// diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index cafc74ed138f1..8fb44a7d7d9b8 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -166,7 +166,9 @@ class RuntimeController : public PlatformConfigurationClient { //---------------------------------------------------------------------------- /// @brief Notify the isolate that a new view is available. /// - /// The implicit view should also be added with this method. + /// A view must be added before other methods can refer to it, + /// including the implicit view. Adding a view that has been + /// added triggers assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -176,8 +178,7 @@ class RuntimeController : public PlatformConfigurationClient { //---------------------------------------------------------------------------- /// @brief Notify the isolate that a view is no longer available. /// - /// The implicit view should not be removed with this method, - /// since it should never be removed. + /// Removing a view that has not been added triggers assertion. /// /// @param[in] view_id The ID of the view. /// diff --git a/shell/common/engine.h b/shell/common/engine.h index c000062230df0..85574ae778ad8 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -678,7 +678,9 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { //---------------------------------------------------------------------------- /// @brief Notify the Flutter application that a new view is available. /// - /// The implicit view should also be added with this method. + /// A view must be added before other methods can refer to it, + /// including the implicit view. Adding a view that has been + /// added triggers assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -689,8 +691,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// @brief Notify the Flutter application that a view is no /// longer available. /// - /// The implicit view should not be removed with this method, - /// since it should never be removed. + /// Removing a view that has not been not added triggers + /// assertion. /// /// @param[in] view_id The ID of the view. /// diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 35575ac7c2ca5..257a1e9d0a113 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -209,8 +209,9 @@ class Rasterizer final : public SnapshotDelegate, /// /// This method should be called a view is removed. /// - /// Resources for a view is allocated the first time the - /// rasterizer encouters this view ID. + /// The rasterizer don't need views to be registered. Last-frame + /// states for views are recorded when layer trees are rasterized + /// to the view and used during `Rasterizer::DrawLastLayerTree`. /// /// @param[in] view_id The ID of the view. /// diff --git a/shell/common/shell.h b/shell/common/shell.h index 231bcb1f8814f..380dd49eed2d2 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,12 +298,13 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; - /// @brief Adds a non-implicit view. + /// @brief Allocates resources for a new non-implicit view. /// - /// This method returns immediately and does not wait for the tasks - /// on the UI thread to finish. This is because operations are either - /// initiated from the UI thread (such as rendering), or are sent as a - /// posted task that is queued. + /// This method returns immediately and does not wait for the tasks on + /// the UI thread to finish. This is safe because operations are + /// either initiated from the UI thread (such as rendering), or are + /// sent as posted tasks that are queued. In either case, it's ok for + /// the engine to have views that the Dart VM doesn't. /// /// The implicit view should never be added with this function. /// Instead, it is added internally on Shell initialization depending @@ -315,10 +316,10 @@ class Shell final : public PlatformView::Delegate, /// void AddView(int64_t view_id, const ViewportMetrics& viewport_metrics); - /// @brief Removes a non-implicit view. + /// @brief Deallocates resources for a non-implicit view. /// - /// This method waits for the tasks on the rasterizer thread and the - /// UI thread to finish before returning. + /// This method waits for the tasks on the UI thread to finish before + /// returning. /// /// The implicit view should never be removed. Trying to remove /// `kFlutterImplicitViewId` is a no-op with warning. From 5cb56f8a4c45005bb07ec53d453592a9093b8ea2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 2 Aug 2023 17:40:07 -0700 Subject: [PATCH 33/46] Trivial comments --- common/settings.h | 2 +- lib/ui/window/platform_configuration.cc | 6 ++++-- lib/ui/window/platform_configuration.h | 3 +++ runtime/runtime_controller.h | 3 +++ shell/common/engine.h | 3 +++ shell/common/rasterizer.cc | 2 ++ shell/common/rasterizer.h | 2 +- shell/common/shell.cc | 24 ++++++++---------------- shell/common/shell.h | 4 ++-- 9 files changed, 27 insertions(+), 22 deletions(-) diff --git a/common/settings.h b/common/settings.h index ad6091f087bbf..1bf1183a0b19c 100644 --- a/common/settings.h +++ b/common/settings.h @@ -254,7 +254,7 @@ struct Settings { // The single-view APIs, which are APIs that do not specify view IDs, operate // the implicit view. The multi-view APIs can operate all views, including the // implicit view with the correct ID (kFlutterImplicitViewId), unless - // specified otherwise, + // specified otherwise. // // The enable_implicit_view defaults to true. bool enable_implicit_view = true; diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index a1cd36a72f0b7..f7262603aa4e6 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -89,8 +89,10 @@ void PlatformConfiguration::AddView(int64_t view_id, } void PlatformConfiguration::RemoveView(int64_t view_id) { - FML_DCHECK(view_id != kFlutterImplicitViewId); - windows_.erase(view_id); + FML_DCHECK(view_id != kFlutterImplicitViewId) + << "The implicit view #" << view_id << " should never be removed."; + size_t erased_elements = windows_.erase(view_id); + FML_DCHECK(erased_elements != 0) << "View #" << view_id << " doesn't exist."; std::shared_ptr dart_state = remove_view_.dart_state().lock(); if (!dart_state) { diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index c426056097624..4528ce3779929 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -275,6 +275,9 @@ class PlatformConfiguration final { /// /// Removing a view that has not been added triggers assertion. /// + /// The implicit view (kFlutterImplicitViewId) should never be + /// removed. Doing so triggers assertion. + /// /// @param[in] view_id The ID of the view. /// void RemoveView(int64_t view_id); diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 8fb44a7d7d9b8..bffabcb44276b 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -180,6 +180,9 @@ class RuntimeController : public PlatformConfigurationClient { /// /// Removing a view that has not been added triggers assertion. /// + /// The implicit view (kFlutterImplicitViewId) should never be + /// removed. Doing so triggers assertion. + /// /// @param[in] view_id The ID of the view. /// bool RemoveView(int64_t view_id); diff --git a/shell/common/engine.h b/shell/common/engine.h index 85574ae778ad8..d20b2c13cda60 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -694,6 +694,9 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// Removing a view that has not been not added triggers /// assertion. /// + /// The implicit view (kFlutterImplicitViewId) should never be + /// removed. Doing so triggers assertion. + /// /// @param[in] view_id The ID of the view. /// void RemoveView(int64_t view_id); diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 3408d1d7e17c0..efd044717a9c7 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -157,6 +157,8 @@ void Rasterizer::NotifyLowMemoryWarning() const { } void Rasterizer::CollectView(int64_t view_id) { + // TODO(dkwingsmt): When Rasterizer supports multi-view, this method should + // correctly clear the view corresponding to the ID. if (view_id == kFlutterImplicitViewId) { last_layer_tree_.reset(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 257a1e9d0a113..bb05e4475f998 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -207,7 +207,7 @@ class Rasterizer final : public SnapshotDelegate, //---------------------------------------------------------------------------- /// @brief Deallocate the resources for displaying a view. /// - /// This method should be called a view is removed. + /// This method should be called when a view is removed. /// /// The rasterizer don't need views to be registered. Last-frame /// states for views are recorded when layer trees are rasterized diff --git a/shell/common/shell.cc b/shell/common/shell.cc index dbeea866bf758..390ad2ae63d15 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -990,9 +990,6 @@ void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id, }); { - // TODO(dkwingsmt): Use the correct view ID when this method supports - // multi-view. - int64_t view_id = kFlutterImplicitViewId; std::scoped_lock lock(resize_mutex_); expected_frame_sizes_[view_id] = SkISize::Make(metrics.physical_width, metrics.physical_height); @@ -2037,12 +2034,10 @@ void Shell::AddView(int64_t view_id, const ViewportMetrics& viewport_metrics) { TRACE_EVENT0("flutter", "Shell::AddView"); FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - if (view_id == kFlutterImplicitViewId) { - FML_DLOG(ERROR) << "Unexpected request to add the implicit view #" - << kFlutterImplicitViewId - << ". This view should never be added. This call is no-op."; - return; - } + FML_DCHECK(view_id != kFlutterImplicitViewId) + << "Unexpected request to add the implicit view #" + << kFlutterImplicitViewId + << ". This view should never be added. This call is no-op."; task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // viewport_metrics, // @@ -2058,13 +2053,10 @@ void Shell::RemoveView(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::RemoveView"); FML_DCHECK(is_set_up_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - if (view_id == kFlutterImplicitViewId) { - FML_DLOG(ERROR) - << "Unexpected request to remove the implicit view #" - << kFlutterImplicitViewId - << ". This view should never be removed. This call is no-op."; - return; - } + FML_DCHECK(view_id != kFlutterImplicitViewId) + << "Unexpected request to remove the implicit view #" + << kFlutterImplicitViewId + << ". This view should never be removed. This call is no-op."; expected_frame_sizes_.erase(view_id); fml::AutoResetWaitableEvent latch; diff --git a/shell/common/shell.h b/shell/common/shell.h index 380dd49eed2d2..0df400c44d944 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -309,7 +309,7 @@ class Shell final : public PlatformView::Delegate, /// The implicit view should never be added with this function. /// Instead, it is added internally on Shell initialization depending /// on `Settings.enable_implicit_view`. Trying to add - /// `kFlutterImplicitViewId` is a no-op with warning. + /// `kFlutterImplicitViewId` triggers an assertion. /// /// @param[in] view_id The view ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -322,7 +322,7 @@ class Shell final : public PlatformView::Delegate, /// returning. /// /// The implicit view should never be removed. Trying to remove - /// `kFlutterImplicitViewId` is a no-op with warning. + /// `kFlutterImplicitViewId` triggers an assertion. /// /// @param[in] view_id The view ID of the view to be removed. /// From 6264164497d82dbe3ce029d97ceee80cd1d723d0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 3 Aug 2023 14:49:34 -0700 Subject: [PATCH 34/46] Use TODO issue; solve lint --- lib/ui/window/platform_configuration.cc | 1 + shell/common/shell.cc | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index f7262603aa4e6..c2e018c9403a1 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -93,6 +93,7 @@ void PlatformConfiguration::RemoveView(int64_t view_id) { << "The implicit view #" << view_id << " should never be removed."; size_t erased_elements = windows_.erase(view_id); FML_DCHECK(erased_elements != 0) << "View #" << view_id << " doesn't exist."; + (void)erased_elements; std::shared_ptr dart_state = remove_view_.dart_state().lock(); if (!dart_state) { diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 390ad2ae63d15..f4916572bc285 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1941,6 +1941,9 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( rapidjson::Document* response) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + // TODO(dkwingsmt): This method only handles view #0, including the snapshot + // and the frame size. We need to adapt this method to multi-view. + // https://github.com/flutter/flutter/issues/131892 if (auto last_layer_tree = rasterizer_->GetLastLayerTree()) { auto& allocator = response->GetAllocator(); response->SetObject(); @@ -1972,8 +1975,6 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( response->AddMember("snapshots", snapshots, allocator); - // TODO(dkwingsmt): Not sure what these fields are supposed to be after - // multi-view. For now it sends the implicit view's dimension as before. const auto& frame_size = ExpectedFrameSize(kFlutterImplicitViewId); response->AddMember("frame_width", frame_size.width(), allocator); response->AddMember("frame_height", frame_size.height(), allocator); From a1b074032a910d2565be928e30182973d36b5d52 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 4 Aug 2023 10:31:37 -0700 Subject: [PATCH 35/46] Simplify implicit view init, add assertion --- lib/ui/platform_dispatcher.dart | 32 +++++++++++++++++++++----------- shell/common/shell_unittests.cc | 8 ++++---- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 87f6c3a341380..331ead5cf1777 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -116,9 +116,6 @@ class PlatformDispatcher { /// these. Use [instance] to access the singleton. PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; - if (_implicitViewId != null) { - _views[_implicitViewId!] = FlutterView._(_implicitViewId!, this, const _ViewConfiguration()); - } } /// The [PlatformDispatcher] singleton. @@ -215,12 +212,27 @@ class PlatformDispatcher { /// by the platform. FlutterView? get implicitView { final FlutterView? result = _views[_implicitViewId]; + // Make sure [implicitView] agrees with `_implicitViewId`. assert((result != null) == (_implicitViewId != null), (_implicitViewId != null) ? 'The implicit view ID is $_implicitViewId, but the implicit view does not exist.' : 'The implicit view ID is null, but the implicit view exists.'); + // Make sure [implicitView] never chages. + assert(() { + if (debugHasRecordedLastImplicitView) { + assert(identical(debugLastImplicitView, result), + 'The implicitView has changed:\n' + 'Last: $debugLastImplicitView\nCurrent: $result'); + } else { + debugLastImplicitView = result; + debugHasRecordedLastImplicitView = true; + } + return true; + }()); return result; } + FlutterView? debugLastImplicitView; + bool debugHasRecordedLastImplicitView = false; /// A callback that is invoked whenever the [ViewConfiguration] of any of the /// [views] changes. @@ -254,14 +266,9 @@ class PlatformDispatcher { // the implicit view, then it's equivalent to _updateWindowMetrics. // Otherwise, the target view must not exist. void _addView(int id, _ViewConfiguration viewConfiguration) { - // The implicit view is added at construction. - if (id != _implicitViewId) { - assert(!_views.containsKey(id), 'View ID $id already exists.'); - _views[id] = FlutterView._(id, this, viewConfiguration); - _invoke(onMetricsChanged, _onMetricsChangedZone); - } else { - _updateWindowMetrics(id, viewConfiguration); - } + assert(!_views.containsKey(id), 'View ID $id already exists.'); + _views[id] = FlutterView._(id, this, viewConfiguration); + _invoke(onMetricsChanged, _onMetricsChangedZone); } // Called from the engine, via hooks.dart @@ -271,6 +278,9 @@ class PlatformDispatcher { // The target view must not be the implicit view, and must exist. void _removeView(int id) { assert(id != _implicitViewId, 'The implicit view #$id can not be removed.'); + if (id == _implicitViewId) { + return; + } assert(_views.containsKey(id), 'View ID $id does not exist.'); _views.remove(id); _invoke(onMetricsChanged, _onMetricsChangedZone); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index b55788365c6f6..a0d8f726733aa 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4521,10 +4521,10 @@ static void ParseViewWidthsCallback(const Dart_NativeArguments& args, } } -// Tests that PlatformView::SetViewportMetrics and Shell::AddView that are -// dispatched before the engine is run are flushed to the Dart VM when the app -// starts. -TEST_F(ShellTest, ShellFlushesAccumulatedPlatformStates) { +// Ensure that PlatformView::SetViewportMetrics and Shell::AddView that were +// dispatched before the isolate is run have been flushed to the Dart VM when +// the main function starts. +TEST_F(ShellTest, ShellFlushesPlatformStatesByMain) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); settings.enable_implicit_view = true; From b3284aaa32bc7e9cb3461b011c716a111807038b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 4 Aug 2023 10:34:51 -0700 Subject: [PATCH 36/46] Doc --- lib/ui/platform_dispatcher.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index 331ead5cf1777..c33d421e7127f 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -262,9 +262,10 @@ class PlatformDispatcher { // Called from the engine, via hooks.dart // - // Adds a new view with the specific view configuration. If the target view is - // the implicit view, then it's equivalent to _updateWindowMetrics. - // Otherwise, the target view must not exist. + // Adds a new view with the specific view configuration. + // + // The implicit view must be added before [implicitView] is first called, + // which is typically the main function. void _addView(int id, _ViewConfiguration viewConfiguration) { assert(!_views.containsKey(id), 'View ID $id already exists.'); _views[id] = FlutterView._(id, this, viewConfiguration); @@ -275,7 +276,8 @@ class PlatformDispatcher { // // Removes the specific view. // - // The target view must not be the implicit view, and must exist. + // The target view must must exist. The implicit view must not be removed, + // or an assertion will be triggered. void _removeView(int id) { assert(id != _implicitViewId, 'The implicit view #$id can not be removed.'); if (id == _implicitViewId) { From 2fb045bdc839c155357b49e49c6d8a7f3daf8b10 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 4 Aug 2023 16:47:48 -0700 Subject: [PATCH 37/46] Comments --- lib/ui/platform_dispatcher.dart | 14 +++++++------- lib/ui/window/platform_configuration.h | 8 ++++---- lib/ui/window/window.h | 5 ++++- runtime/runtime_controller.cc | 3 +++ runtime/runtime_controller.h | 14 ++++++++++---- shell/common/engine.h | 9 ++++----- shell/common/fixtures/shell_test.dart | 5 ++--- shell/common/shell.cc | 6 ++---- 8 files changed, 36 insertions(+), 28 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index c33d421e7127f..ecef92a05407b 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -219,20 +219,20 @@ class PlatformDispatcher { 'The implicit view ID is null, but the implicit view exists.'); // Make sure [implicitView] never chages. assert(() { - if (debugHasRecordedLastImplicitView) { - assert(identical(debugLastImplicitView, result), + if (_debugRecordedLastImplicitView) { + assert(identical(_debugLastImplicitView, result), 'The implicitView has changed:\n' - 'Last: $debugLastImplicitView\nCurrent: $result'); + 'Last: $_debugLastImplicitView\nCurrent: $result'); } else { - debugLastImplicitView = result; - debugHasRecordedLastImplicitView = true; + _debugLastImplicitView = result; + _debugRecordedLastImplicitView = true; } return true; }()); return result; } - FlutterView? debugLastImplicitView; - bool debugHasRecordedLastImplicitView = false; + FlutterView? _debugLastImplicitView; + bool _debugRecordedLastImplicitView = false; /// A callback that is invoked whenever the [ViewConfiguration] of any of the /// [views] changes. diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 4528ce3779929..3c3101308e4b9 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -262,8 +262,8 @@ class PlatformConfiguration final { /// @brief Notify the framework that a new view is available. /// /// A view must be added before other methods can refer to it, - /// including the implicit view. Adding a view that has been - /// added triggers assertion. + /// including the implicit view. Adding a view that already exists + /// triggers an assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -273,10 +273,10 @@ class PlatformConfiguration final { //---------------------------------------------------------------------------- /// @brief Notify the framework that a view is no longer available. /// - /// Removing a view that has not been added triggers assertion. + /// Removing a view that does not exist triggers an assertion. /// /// The implicit view (kFlutterImplicitViewId) should never be - /// removed. Doing so triggers assertion. + /// removed. Doing so triggers an assertion. /// /// @param[in] view_id The ID of the view. /// diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h index c02a2628eca45..7945f594e1b6e 100644 --- a/lib/ui/window/window.h +++ b/lib/ui/window/window.h @@ -30,7 +30,10 @@ class Window final { const ViewportMetrics& viewport_metrics() const { return viewport_metrics_; } - // Send an AddView message to Dart with the current view metrics. + // Called by PlatformConfiguration to send an AddView message to Dart with the + // current view metrics. + // + // This must not be called more than once per `window_id`. void AddView(); // Update view metrics, and send an UpdateWindowMetrics message to Dart. diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 51812f6551303..1884eeb338981 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -113,6 +113,9 @@ std::unique_ptr RuntimeController::Clone() const { } bool RuntimeController::FlushRuntimeStateToIsolate() { + FML_DCHECK(!has_flushed_runtime_state_) + << "FlushRuntimeStateToIsolate is called more than once somehow."; + has_flushed_runtime_state_ = true; for (auto const& [view_id, viewport_metrics] : platform_data_.viewport_metrics_for_views) { if (!AddView(view_id, viewport_metrics)) { diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index bffabcb44276b..1d1b0d7407e62 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -42,6 +42,11 @@ class Window; /// used by the engine to copy the currently accumulated window state so it can /// be referenced by the new runtime controller. /// +/// When `RuntimeController` is created, it takes some time before the root +/// isolate becomes ready. Operation during this gap is stored by +/// `RuntimeController` and flushed to the Dart VM when the isolate becomes +/// ready before the entrypoint function. See `PlatformData`. +/// class RuntimeController : public PlatformConfigurationClient { public: //---------------------------------------------------------------------------- @@ -167,8 +172,8 @@ class RuntimeController : public PlatformConfigurationClient { /// @brief Notify the isolate that a new view is available. /// /// A view must be added before other methods can refer to it, - /// including the implicit view. Adding a view that has been - /// added triggers assertion. + /// including the implicit view. Adding a view that already exists + /// triggers an assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -178,10 +183,10 @@ class RuntimeController : public PlatformConfigurationClient { //---------------------------------------------------------------------------- /// @brief Notify the isolate that a view is no longer available. /// - /// Removing a view that has not been added triggers assertion. + /// Removing a view that does not exist triggers an assertion. /// /// The implicit view (kFlutterImplicitViewId) should never be - /// removed. Doing so triggers assertion. + /// removed. Doing so triggers an assertion. /// /// @param[in] view_id The ID of the view. /// @@ -640,6 +645,7 @@ class RuntimeController : public PlatformConfigurationClient { const fml::closure isolate_shutdown_callback_; std::shared_ptr persistent_isolate_data_; UIDartState::Context context_; + bool has_flushed_runtime_state_ = false; PlatformConfiguration* GetPlatformConfigurationIfAvailable(); diff --git a/shell/common/engine.h b/shell/common/engine.h index d20b2c13cda60..e53efc9eb3882 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -679,8 +679,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// @brief Notify the Flutter application that a new view is available. /// /// A view must be added before other methods can refer to it, - /// including the implicit view. Adding a view that has been - /// added triggers assertion. + /// including the implicit view. Adding a view that already exists + /// triggers an assertion. /// /// @param[in] view_id The ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. @@ -691,11 +691,10 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// @brief Notify the Flutter application that a view is no /// longer available. /// - /// Removing a view that has not been not added triggers - /// assertion. + /// Removing a view that does not exist triggers an assertion. /// /// The implicit view (kFlutterImplicitViewId) should never be - /// removed. Doing so triggers assertion. + /// removed. Doing so triggers an assertion. /// /// @param[in] view_id The ID of the view. /// diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index 05fc9394bcbf9..e4b0d98833f44 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -538,9 +538,8 @@ List getCurrentViewWidths() { @pragma('vm:external-name', 'NativeReportViewWidthsCallback') external void nativeReportViewWidthsCallback(List viewWidthPacket); -// This entrypoint reports whether there's an implicit view and the list of view -// IDs using nativeReportViewIdsCallback on initialization and every -// onMetricsChanged. +// This entrypoint reports the list of views and their widths using +// nativeReportViewWidthsCallback on initialization and every onMetricsChanged. @pragma('vm:entry-point') void testReportViewWidths() { nativeReportViewWidthsCallback(getCurrentViewWidths()); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f4916572bc285..07b83c5d6df97 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2037,8 +2037,7 @@ void Shell::AddView(int64_t view_id, const ViewportMetrics& viewport_metrics) { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); FML_DCHECK(view_id != kFlutterImplicitViewId) << "Unexpected request to add the implicit view #" - << kFlutterImplicitViewId - << ". This view should never be added. This call is no-op."; + << kFlutterImplicitViewId << ". This view should never be added."; task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // viewport_metrics, // @@ -2056,8 +2055,7 @@ void Shell::RemoveView(int64_t view_id) { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); FML_DCHECK(view_id != kFlutterImplicitViewId) << "Unexpected request to remove the implicit view #" - << kFlutterImplicitViewId - << ". This view should never be removed. This call is no-op."; + << kFlutterImplicitViewId << ". This view should never be removed."; expected_frame_sizes_.erase(view_id); fml::AutoResetWaitableEvent latch; From 9bb1d7540af285a9dbd730c5724429fc931ac43c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 4 Aug 2023 16:59:28 -0700 Subject: [PATCH 38/46] RemoveView no longer blocks --- shell/common/shell.cc | 3 --- shell/common/shell.h | 8 +++++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 23d5cc1da9906..7c4788fc9daf6 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2082,10 +2082,7 @@ void Shell::RemoveView(int64_t view_id) { rasterizer->CollectView(view_id); } }); - latch.Signal(); }); - - latch.Wait(); } Rasterizer::Screenshot Shell::Screenshot( diff --git a/shell/common/shell.h b/shell/common/shell.h index 0df400c44d944..8c16e1ed33e37 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -300,7 +300,7 @@ class Shell final : public PlatformView::Delegate, /// @brief Allocates resources for a new non-implicit view. /// - /// This method returns immediately and does not wait for the tasks on + /// This method returns immediately and does not wait for the task on /// the UI thread to finish. This is safe because operations are /// either initiated from the UI thread (such as rendering), or are /// sent as posted tasks that are queued. In either case, it's ok for @@ -318,8 +318,10 @@ class Shell final : public PlatformView::Delegate, /// @brief Deallocates resources for a non-implicit view. /// - /// This method waits for the tasks on the UI thread to finish before - /// returning. + /// This method returns immediately and does not wait for the task on + /// the UI thread to finish. This means that the Dart VM might still + /// send messages regarding this view ID for a short while, even + /// though this view ID is already invalid. /// /// The implicit view should never be removed. Trying to remove /// `kFlutterImplicitViewId` triggers an assertion. From 90020f485db07fe9ebb724d3ab2f4d3a3afa5f0a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 4 Aug 2023 17:35:25 -0700 Subject: [PATCH 39/46] Fix compile --- shell/common/shell.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 7c4788fc9daf6..eadc0d409efee 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2062,10 +2062,8 @@ void Shell::RemoveView(int64_t view_id) { << kFlutterImplicitViewId << ". This view should never be removed."; expected_frame_sizes_.erase(view_id); - fml::AutoResetWaitableEvent latch; task_runners_.GetUITaskRunner()->PostTask( - [&latch, // - & task_runners = task_runners_, // + [&task_runners = task_runners_, // engine = engine_->GetWeakPtr(), // rasterizer = rasterizer_->GetWeakPtr(), // view_id // From 58f18a8dd61ae6fad6582892b6d6beb8e1200938 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 16 Aug 2023 15:29:26 -0700 Subject: [PATCH 40/46] Remove flag --- common/settings.h | 53 ++++++++++++----------------- lib/ui/dart_ui.cc | 10 +++--- shell/common/shell.cc | 4 +-- shell/common/shell.h | 5 ++- shell/common/shell_unittests.cc | 49 ++------------------------ shell/platform/embedder/embedder.cc | 3 -- 6 files changed, 32 insertions(+), 92 deletions(-) diff --git a/common/settings.h b/common/settings.h index 1bf1183a0b19c..7ca439af0f5e9 100644 --- a/common/settings.h +++ b/common/settings.h @@ -24,7 +24,28 @@ namespace flutter { // The ID for the implicit view if the implicit view is enabled. // -// See Settings::enable_implicit_view for introduction. +// The implicit view is a compatibility mechanism to help the transition from +// the older single-view APIs to the newer multi-view APIs. The two sets of APIs +// use different models for view management. The implicit view mechanism allows +// single-view APIs to operate a special view as if other views don't exist. +// +// In the regular multi-view model, all views should be created by +// `Shell::AddView` before being used, and removed by `Shell::RemoveView` to +// signify that they are gone. If a view is added or removed, the framework +// (`PlatformDispatcher`) will be notified. New view IDs are always unique, +// never reused. Operating a non-existing view is an error. +// +// The implicit view is another special view in addition to the "regular views" +// as above. The shell starts up having the implicit view, which has a fixed +// view ID of `kFlutterImplicitViewId` and is available throughout the lifetime +// of the shell. `Shell::AddView` or `RemoveView` must not be called for this +// view. Even when the window that shows the view is closed, the framework is +// unaware and might continue rendering into or operating this view. +// +// The single-view APIs, which are APIs that do not specify view IDs, operate +// the implicit view. The multi-view APIs can operate all views, including the +// implicit view if the target ID is `kFlutterImplicitViewId`, unless specified +// otherwise. constexpr int64_t kFlutterImplicitViewId = 0; class FrameTiming { @@ -229,36 +250,6 @@ struct Settings { // must be available to the application. bool enable_vulkan_validation = false; - // Enable the implicit view. - // - // The implicit view mode is a compatibility mode to help the transition from - // the older single-view APIs to the newer multi-view APIs. The two sets of - // APIs use different models for view management. By enabling the implicit - // view, single-view APIs can operate a special view as if other views don't - // exist. - // - // In the regular multi-view model where the implicit view is disabled, all - // views should be created by Shell::AddView before being used, and removed by - // Shell::RemoveView to signify that they are gone. If a view is added or - // removed, the framework (PlatformDispatcher) will be notified. New view IDs - // are always unique, never reused. Operating a non-existing view is an error. - // - // If the implicit view is enabled, in addition to the "regular views" as - // above, the shell will start up with a special view with a fixed view ID of - // kFlutterImplicitViewId. This view, called the implicit view, is available - // throughout the lifetime of the shell. Shell::AddView or RemoveView must not - // be called for this view. Even when the window that shows the view is - // closed, the framework is unaware and might continue render into or operate - // this view. - // - // The single-view APIs, which are APIs that do not specify view IDs, operate - // the implicit view. The multi-view APIs can operate all views, including the - // implicit view with the correct ID (kFlutterImplicitViewId), unless - // specified otherwise. - // - // The enable_implicit_view defaults to true. - bool enable_implicit_view = true; - // Data set by platform-specific embedders for use in font initialization. uint32_t font_initialization_data = 0; diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index a8bf580cdb1ee..323b69745d776 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -373,12 +373,10 @@ void DartUI::InitForIsolate(const Settings& settings) { } } - if (settings.enable_implicit_view) { - result = Dart_SetField(dart_ui, ToDart("_implicitViewId"), - Dart_NewInteger(kFlutterImplicitViewId)); - if (Dart_IsError(result)) { - Dart_PropagateError(result); - } + result = Dart_SetField(dart_ui, ToDart("_implicitViewId"), + Dart_NewInteger(kFlutterImplicitViewId)); + if (Dart_IsError(result)) { + Dart_PropagateError(result); } } diff --git a/shell/common/shell.cc b/shell/common/shell.cc index eadc0d409efee..57b2c055d1427 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -715,9 +715,7 @@ bool Shell::Setup(std::unique_ptr platform_view, weak_rasterizer_ = rasterizer_->GetWeakPtr(); weak_platform_view_ = platform_view_->GetWeakPtr(); - if (settings_.enable_implicit_view) { - engine_->AddView(kFlutterImplicitViewId, ViewportMetrics{}); - } + engine_->AddView(kFlutterImplicitViewId, ViewportMetrics{}); // Setup the time-consuming default font manager right after engine created. if (!settings_.prefetched_default_font_manager) { fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(), diff --git a/shell/common/shell.h b/shell/common/shell.h index 8c16e1ed33e37..c4b585550b082 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -307,9 +307,8 @@ class Shell final : public PlatformView::Delegate, /// the engine to have views that the Dart VM doesn't. /// /// The implicit view should never be added with this function. - /// Instead, it is added internally on Shell initialization depending - /// on `Settings.enable_implicit_view`. Trying to add - /// `kFlutterImplicitViewId` triggers an assertion. + /// Instead, it is added internally on Shell initialization. Trying to + /// add `kFlutterImplicitViewId` triggers an assertion. /// /// @param[in] view_id The view ID of the new view. /// @param[in] viewport_metrics The initial viewport metrics for the view. diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 579494d1b166d..43a14bb13b75f 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -4402,12 +4402,9 @@ static void RunOnPlatformTaskRunner(Shell& shell, const fml::closure& task) { latch.Wait(); } -// Tests that Settings.enable_implicit_view being true causes the shell -// to begin with an implicit view. -TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { +TEST_F(ShellTest, ShellStartsWithImplicitView) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); - settings.enable_implicit_view = true; - auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); @@ -4439,48 +4436,10 @@ TEST_F(ShellTest, ShellWithImplicitViewEnabledStartsWithImplicitView) { DestroyShell(std::move(shell), task_runners); } -// Tests that Settings.enable_implicit_view being false causes the shell -// to begin without an implicit view. -TEST_F(ShellTest, ShellWithImplicitViewDisabledStartsWithoutImplicitView) { - Settings settings = CreateSettingsForFixture(); - settings.enable_implicit_view = false; - - auto task_runner = CreateNewThread(); - TaskRunners task_runners("test", task_runner, task_runner, task_runner, - task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); - ASSERT_TRUE(shell); - - bool hasImplicitView; - std::vector viewIds; - fml::AutoResetWaitableEvent reportLatch; - auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView, - &viewIds](Dart_NativeArguments args) { - ParseViewIdsCallback(args, &hasImplicitView, &viewIds); - reportLatch.Signal(); - }; - AddNativeCallback("NativeReportViewIdsCallback", - CREATE_NATIVE_ENTRY(nativeViewIdsCallback)); - - PlatformViewNotifyCreated(shell.get()); - auto configuration = RunConfiguration::InferFromSettings(settings); - configuration.SetEntrypoint("testReportViewIds"); - RunEngine(shell.get(), std::move(configuration)); - reportLatch.Wait(); - - ASSERT_FALSE(hasImplicitView); - ASSERT_EQ(viewIds.size(), 0u); - - PlatformViewNotifyDestroyed(shell.get()); - DestroyShell(std::move(shell), task_runners); -} - // Tests that Shell::AddView and Shell::RemoveView works. -TEST_F(ShellTest, ShellWithImplicitViewEnabledAddViewRemoveView) { +TEST_F(ShellTest, ShellCanAddViewOrRemoveView) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); - settings.enable_implicit_view = true; - ThreadHost thread_host(ThreadHost::ThreadHostConfig( "io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::RASTER | @@ -4561,8 +4520,6 @@ static void ParseViewWidthsCallback(const Dart_NativeArguments& args, TEST_F(ShellTest, ShellFlushesPlatformStatesByMain) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); - settings.enable_implicit_view = true; - ThreadHost thread_host(ThreadHost::ThreadHostConfig( "io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::RASTER | diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index a7a933a240244..e571001a26588 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -1733,9 +1733,6 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, settings.assets_path = args->assets_path; settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false); settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1); - // TODO(dkwingsmt): Add a switch for this to FlutterProjectArgs so that - // platforms can configure whether to use the implicit view. - settings.enable_implicit_view = true; if (!flutter::DartVM::IsRunningPrecompiledCode()) { // Verify the assets path contains Dart 2 kernel assets. From dd832b170ab573f9ef44b6a43ba301f5b20dd3a6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 16 Aug 2023 15:42:01 -0700 Subject: [PATCH 41/46] Impl --- lib/ui/hooks.dart | 95 +++++++++++++++++++++++++++++- lib/ui/platform_dispatcher.dart | 101 +------------------------------- 2 files changed, 95 insertions(+), 101 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index c391d273e1e59..7d31bd4f0c2f1 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -30,9 +30,98 @@ void _updateDisplays( PlatformDispatcher.instance._updateDisplays(displays); } +List _decodeDisplayFeatures({ + required List bounds, + required List type, + required List state, + required double devicePixelRatio, +}) { + assert(bounds.length / 4 == type.length, 'Bounds are rectangles, requiring 4 measurements each'); + assert(type.length == state.length); + final List result = []; + for(int i = 0; i < type.length; i++) { + final int rectOffset = i * 4; + result.add(DisplayFeature( + bounds: Rect.fromLTRB( + bounds[rectOffset] / devicePixelRatio, + bounds[rectOffset + 1] / devicePixelRatio, + bounds[rectOffset + 2] / devicePixelRatio, + bounds[rectOffset + 3] / devicePixelRatio, + ), + type: DisplayFeatureType.values[type[i]], + state: state[i] < DisplayFeatureState.values.length + ? DisplayFeatureState.values[state[i]] + : DisplayFeatureState.unknown, + )); + } + return result; +} + +_ViewConfiguration _buildViewConfiguration( + double devicePixelRatio, + double width, + double height, + double viewPaddingTop, + double viewPaddingRight, + double viewPaddingBottom, + double viewPaddingLeft, + double viewInsetTop, + double viewInsetRight, + double viewInsetBottom, + double viewInsetLeft, + double systemGestureInsetTop, + double systemGestureInsetRight, + double systemGestureInsetBottom, + double systemGestureInsetLeft, + double physicalTouchSlop, + List displayFeaturesBounds, + List displayFeaturesType, + List displayFeaturesState, + int displayId, +) { + return _ViewConfiguration( + devicePixelRatio: devicePixelRatio, + geometry: Rect.fromLTWH(0.0, 0.0, width, height), + viewPadding: ViewPadding._( + top: viewPaddingTop, + right: viewPaddingRight, + bottom: viewPaddingBottom, + left: viewPaddingLeft, + ), + viewInsets: ViewPadding._( + top: viewInsetTop, + right: viewInsetRight, + bottom: viewInsetBottom, + left: viewInsetLeft, + ), + padding: ViewPadding._( + top: math.max(0.0, viewPaddingTop - viewInsetTop), + right: math.max(0.0, viewPaddingRight - viewInsetRight), + bottom: math.max(0.0, viewPaddingBottom - viewInsetBottom), + left: math.max(0.0, viewPaddingLeft - viewInsetLeft), + ), + systemGestureInsets: ViewPadding._( + top: math.max(0.0, systemGestureInsetTop), + right: math.max(0.0, systemGestureInsetRight), + bottom: math.max(0.0, systemGestureInsetBottom), + left: math.max(0.0, systemGestureInsetLeft), + ), + gestureSettings: GestureSettings( + physicalTouchSlop: physicalTouchSlop == _kUnsetGestureSetting ? null : physicalTouchSlop, + ), + displayFeatures: _decodeDisplayFeatures( + bounds: displayFeaturesBounds, + type: displayFeaturesType, + state: displayFeaturesState, + devicePixelRatio: devicePixelRatio, + ), + displayId: displayId, + ); +} + @pragma('vm:entry-point') void _updateWindowMetrics( - int id, + int viewId, double devicePixelRatio, double width, double height, @@ -54,8 +143,7 @@ void _updateWindowMetrics( List displayFeaturesState, int displayId, ) { - PlatformDispatcher.instance._updateWindowMetrics( - id, + final _ViewConfiguration viewConfiguration = _buildViewConfiguration( devicePixelRatio, width, height, @@ -77,6 +165,7 @@ void _updateWindowMetrics( displayFeaturesState, displayId, ); + PlatformDispatcher.instance._updateWindowMetrics(viewId, viewConfiguration); } typedef _LocaleClosure = String Function(); diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index ebcc86456d00c..78f9a52a1b9c8 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -263,107 +263,12 @@ class PlatformDispatcher { // Called from the engine, via hooks.dart // // Updates the metrics of the window with the given id. - void _updateWindowMetrics( - int id, - double devicePixelRatio, - double width, - double height, - double viewPaddingTop, - double viewPaddingRight, - double viewPaddingBottom, - double viewPaddingLeft, - double viewInsetTop, - double viewInsetRight, - double viewInsetBottom, - double viewInsetLeft, - double systemGestureInsetTop, - double systemGestureInsetRight, - double systemGestureInsetBottom, - double systemGestureInsetLeft, - double physicalTouchSlop, - List displayFeaturesBounds, - List displayFeaturesType, - List displayFeaturesState, - int displayId, - ) { - final _ViewConfiguration viewConfiguration = _ViewConfiguration( - devicePixelRatio: devicePixelRatio, - geometry: Rect.fromLTWH(0.0, 0.0, width, height), - viewPadding: ViewPadding._( - top: viewPaddingTop, - right: viewPaddingRight, - bottom: viewPaddingBottom, - left: viewPaddingLeft, - ), - viewInsets: ViewPadding._( - top: viewInsetTop, - right: viewInsetRight, - bottom: viewInsetBottom, - left: viewInsetLeft, - ), - padding: ViewPadding._( - top: math.max(0.0, viewPaddingTop - viewInsetTop), - right: math.max(0.0, viewPaddingRight - viewInsetRight), - bottom: math.max(0.0, viewPaddingBottom - viewInsetBottom), - left: math.max(0.0, viewPaddingLeft - viewInsetLeft), - ), - systemGestureInsets: ViewPadding._( - top: math.max(0.0, systemGestureInsetTop), - right: math.max(0.0, systemGestureInsetRight), - bottom: math.max(0.0, systemGestureInsetBottom), - left: math.max(0.0, systemGestureInsetLeft), - ), - gestureSettings: GestureSettings( - physicalTouchSlop: physicalTouchSlop == _kUnsetGestureSetting ? null : physicalTouchSlop, - ), - displayFeatures: _decodeDisplayFeatures( - bounds: displayFeaturesBounds, - type: displayFeaturesType, - state: displayFeaturesState, - devicePixelRatio: devicePixelRatio, - ), - displayId: displayId, - ); - - final FlutterView? view = _views[id]; - if (id == _kImplicitViewId && view == null) { - // TODO(goderbauer): Remove the implicit creation of the implicit view - // when we have an addView API and the implicit view is added via that. - _views[id] = FlutterView._(id, this, viewConfiguration); - } else { - assert(view != null); - view!._viewConfiguration = viewConfiguration; - } - + void _updateWindowMetrics(int id, _ViewConfiguration viewConfiguration) { + assert(_views.containsKey(id), 'View $id does not exist.'); + _views[id]!._viewConfiguration = viewConfiguration; _invoke(onMetricsChanged, _onMetricsChangedZone); } - List _decodeDisplayFeatures({ - required List bounds, - required List type, - required List state, - required double devicePixelRatio, - }) { - assert(bounds.length / 4 == type.length, 'Bounds are rectangles, requiring 4 measurements each'); - assert(type.length == state.length); - final List result = []; - for(int i = 0; i < type.length; i++) { - final int rectOffset = i * 4; - result.add(DisplayFeature( - bounds: Rect.fromLTRB( - bounds[rectOffset] / devicePixelRatio, - bounds[rectOffset + 1] / devicePixelRatio, - bounds[rectOffset + 2] / devicePixelRatio, - bounds[rectOffset + 3] / devicePixelRatio, - ), - type: DisplayFeatureType.values[type[i]], - state: state[i] < DisplayFeatureState.values.length - ? DisplayFeatureState.values[state[i]] - : DisplayFeatureState.unknown, - )); - } - return result; - } /// A callback invoked when any view begins a frame. /// From c044725f255831f1d7801a008a3b7bc358af7e77 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 16 Aug 2023 18:14:35 -0700 Subject: [PATCH 42/46] Remove window --- ci/licenses_golden/licenses_flutter | 4 - lib/ui/BUILD.gn | 2 - lib/ui/compositing/scene.cc | 1 - lib/ui/painting/canvas.cc | 16 ++- lib/ui/ui_dart_state.cc | 1 + lib/ui/window/platform_configuration.cc | 103 +++++++++++++++--- lib/ui/window/platform_configuration.h | 24 +++- .../platform_configuration_unittests.cc | 63 +++++------ lib/ui/window/window.cc | 93 ---------------- lib/ui/window/window.h | 50 --------- runtime/runtime_controller.cc | 22 ++-- .../platform/fuchsia/flutter/platform_view.cc | 1 - 12 files changed, 153 insertions(+), 227 deletions(-) delete mode 100644 lib/ui/window/window.cc delete mode 100644 lib/ui/window/window.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 0a19c690fc6a5..0bbba217b2fd0 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1904,8 +1904,6 @@ ORIGIN: ../../../flutter/lib/ui/window/pointer_data_packet_converter.cc + ../../ ORIGIN: ../../../flutter/lib/ui/window/pointer_data_packet_converter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/lib/ui/window/viewport_metrics.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/lib/ui/window/viewport_metrics.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/lib/ui/window/window.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/lib/ui/window/window.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/lib/web_ui/lib/annotations.dart + ../../../flutter/LICENSE ORIGIN: ../../../flutter/lib/web_ui/lib/canvas.dart + ../../../flutter/LICENSE ORIGIN: ../../../flutter/lib/web_ui/lib/channel_buffers.dart + ../../../flutter/LICENSE @@ -4634,8 +4632,6 @@ FILE: ../../../flutter/lib/ui/window/pointer_data_packet_converter.cc FILE: ../../../flutter/lib/ui/window/pointer_data_packet_converter.h FILE: ../../../flutter/lib/ui/window/viewport_metrics.cc FILE: ../../../flutter/lib/ui/window/viewport_metrics.h -FILE: ../../../flutter/lib/ui/window/window.cc -FILE: ../../../flutter/lib/ui/window/window.h FILE: ../../../flutter/lib/web_ui/lib/annotations.dart FILE: ../../../flutter/lib/web_ui/lib/canvas.dart FILE: ../../../flutter/lib/web_ui/lib/channel_buffers.dart diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 596dac782b3d4..8ad0197bb1d8d 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -155,8 +155,6 @@ source_set("ui") { "window/pointer_data_packet_converter.h", "window/viewport_metrics.cc", "window/viewport_metrics.h", - "window/window.cc", - "window/window.h", ] public_configs = [ "//flutter:config" ] diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 17d00ea794c2a..5e44f3fcc27bf 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -10,7 +10,6 @@ #include "flutter/lib/ui/painting/picture.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" -#include "flutter/lib/ui/window/window.h" #if IMPELLER_SUPPORTS_RENDERING #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h" #endif // IMPELLER_SUPPORTS_RENDERING diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc index 403a4c3f440a1..0b090b68c9a7b 100644 --- a/lib/ui/painting/canvas.cc +++ b/lib/ui/painting/canvas.cc @@ -13,7 +13,6 @@ #include "flutter/lib/ui/painting/paint.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" -#include "flutter/lib/ui/window/window.h" using tonic::ToDart; @@ -621,11 +620,16 @@ void Canvas::drawShadow(const CanvasPath* path, } // Not using SafeNarrow because DPR will always be a relatively small number. - SkScalar dpr = static_cast(UIDartState::Current() - ->platform_configuration() - ->get_window(0) - ->viewport_metrics() - .device_pixel_ratio); + const ViewportMetrics* metrics = + UIDartState::Current()->platform_configuration()->GetMetrics(0); + SkScalar dpr; + // TODO(dkwingsmt): We should support rendering shadows on non-implicit views. + // However, currently this method has no way to get the target view ID. + if (metrics == nullptr) { + dpr = 1.0f; + } else { + dpr = static_cast(metrics->device_pixel_ratio); + } if (display_list_builder_) { // The DrawShadow mechanism results in non-public operations to be // performed on the canvas involving an SkDrawShadowRec. Since we diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index e66059fc515b3..4af7f0837d81e 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -9,6 +9,7 @@ #include "flutter/fml/message_loop.h" #include "flutter/lib/ui/window/platform_configuration.h" +#include "flutter/lib/ui/window/platform_message.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_message_handler.h" diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index c2e018c9403a1..f4d82e20473fe 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -8,10 +8,10 @@ #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/ui_dart_state.h" +#include "flutter/lib/ui/window/platform_message.h" #include "flutter/lib/ui/window/platform_message_response_dart.h" #include "flutter/lib/ui/window/platform_message_response_dart_port.h" #include "flutter/lib/ui/window/viewport_metrics.h" -#include "flutter/lib/ui/window/window.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_library_natives.h" @@ -41,8 +41,13 @@ void PlatformConfiguration::DidCreateIsolate() { on_error_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_onError"))); + add_view_.Set(tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_addView"))); remove_view_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_removeView"))); + update_window_metrics_.Set( + tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_updateWindowMetrics"))); update_displays_.Set( tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_updateDisplays"))); @@ -75,25 +80,53 @@ void PlatformConfiguration::DidCreateIsolate() { Dart_GetField(library, tonic::ToDart("_drawFrame"))); report_timings_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_reportTimings"))); - - library_.Set(tonic::DartState::Current(), library); } void PlatformConfiguration::AddView(int64_t view_id, const ViewportMetrics& view_metrics) { - auto [window_iterator, insertion_happened] = windows_.emplace( - view_id, std::make_unique(library_, view_id, view_metrics)); + auto [view_iterator, insertion_happened] = + metrics_.emplace(view_id, view_metrics); FML_DCHECK(insertion_happened); - // Make the new window send an AddView message to Dart. - window_iterator->second->AddView(); + + std::shared_ptr dart_state = add_view_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError(tonic::DartInvoke( + add_view_.Get(), + { + tonic::ToDart(view_id), + tonic::ToDart(view_metrics.device_pixel_ratio), + tonic::ToDart(view_metrics.physical_width), + tonic::ToDart(view_metrics.physical_height), + tonic::ToDart(view_metrics.physical_padding_top), + tonic::ToDart(view_metrics.physical_padding_right), + tonic::ToDart(view_metrics.physical_padding_bottom), + tonic::ToDart(view_metrics.physical_padding_left), + tonic::ToDart(view_metrics.physical_view_inset_top), + tonic::ToDart(view_metrics.physical_view_inset_right), + tonic::ToDart(view_metrics.physical_view_inset_bottom), + tonic::ToDart(view_metrics.physical_view_inset_left), + tonic::ToDart(view_metrics.physical_system_gesture_inset_top), + tonic::ToDart(view_metrics.physical_system_gesture_inset_right), + tonic::ToDart(view_metrics.physical_system_gesture_inset_bottom), + tonic::ToDart(view_metrics.physical_system_gesture_inset_left), + tonic::ToDart(view_metrics.physical_touch_slop), + tonic::ToDart(view_metrics.physical_display_features_bounds), + tonic::ToDart(view_metrics.physical_display_features_type), + tonic::ToDart(view_metrics.physical_display_features_state), + tonic::ToDart(view_metrics.display_id), + })); } void PlatformConfiguration::RemoveView(int64_t view_id) { FML_DCHECK(view_id != kFlutterImplicitViewId) << "The implicit view #" << view_id << " should never be removed."; - size_t erased_elements = windows_.erase(view_id); + size_t erased_elements = metrics_.erase(view_id); FML_DCHECK(erased_elements != 0) << "View #" << view_id << " doesn't exist."; - (void)erased_elements; + (void)erased_elements; // Suppress unused variable warning + std::shared_ptr dart_state = remove_view_.dart_state().lock(); if (!dart_state) { @@ -106,6 +139,50 @@ void PlatformConfiguration::RemoveView(int64_t view_id) { })); } +bool PlatformConfiguration::UpdateViewMetrics( + int64_t view_id, + const ViewportMetrics& view_metrics) { + auto found_iter = metrics_.find(view_id); + if (found_iter == metrics_.end()) { + return false; + } + + found_iter->second = view_metrics; + + std::shared_ptr dart_state = + update_window_metrics_.dart_state().lock(); + if (!dart_state) { + return false; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError(tonic::DartInvoke( + update_window_metrics_.Get(), + { + tonic::ToDart(view_id), + tonic::ToDart(view_metrics.device_pixel_ratio), + tonic::ToDart(view_metrics.physical_width), + tonic::ToDart(view_metrics.physical_height), + tonic::ToDart(view_metrics.physical_padding_top), + tonic::ToDart(view_metrics.physical_padding_right), + tonic::ToDart(view_metrics.physical_padding_bottom), + tonic::ToDart(view_metrics.physical_padding_left), + tonic::ToDart(view_metrics.physical_view_inset_top), + tonic::ToDart(view_metrics.physical_view_inset_right), + tonic::ToDart(view_metrics.physical_view_inset_bottom), + tonic::ToDart(view_metrics.physical_view_inset_left), + tonic::ToDart(view_metrics.physical_system_gesture_inset_top), + tonic::ToDart(view_metrics.physical_system_gesture_inset_right), + tonic::ToDart(view_metrics.physical_system_gesture_inset_bottom), + tonic::ToDart(view_metrics.physical_system_gesture_inset_left), + tonic::ToDart(view_metrics.physical_touch_slop), + tonic::ToDart(view_metrics.physical_display_features_bounds), + tonic::ToDart(view_metrics.physical_display_features_type), + tonic::ToDart(view_metrics.physical_display_features_state), + tonic::ToDart(view_metrics.display_id), + })); + return true; +} + void PlatformConfiguration::UpdateDisplays( const std::vector& displays) { std::vector ids; @@ -330,10 +407,10 @@ void PlatformConfiguration::ReportTimings(std::vector timings) { })); } -Window* PlatformConfiguration::get_window(int window_id) { - auto found = windows_.find(window_id); - if (found != windows_.end()) { - return found->second.get(); +const ViewportMetrics* PlatformConfiguration::GetMetrics(int view_id) { + auto found = metrics_.find(view_id); + if (found != metrics_.end()) { + return &found->second; } else { return nullptr; } diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 3c3101308e4b9..90000890dde9f 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -14,9 +14,9 @@ #include "flutter/assets/asset_manager.h" #include "flutter/fml/time/time_point.h" #include "flutter/lib/ui/semantics/semantics_update.h" +#include "flutter/lib/ui/window/platform_message_response.h" #include "flutter/lib/ui/window/pointer_data_packet.h" #include "flutter/lib/ui/window/viewport_metrics.h" -#include "flutter/lib/ui/window/window.h" #include "flutter/shell/common/display.h" #include "third_party/tonic/dart_persistent_value.h" #include "third_party/tonic/typed_data/dart_byte_data.h" @@ -282,6 +282,18 @@ class PlatformConfiguration final { /// void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- + /// @brief Update the view metrics for the specified view. + /// + /// If the view is not found, silently return false. + /// + /// @param[in] view_id The ID of the view. + /// @param[in] metrics The new metrics of the view. + /// + /// @return Whether the view is found. + /// + bool UpdateViewMetrics(int64_t view_id, const ViewportMetrics& metrics); + //---------------------------------------------------------------------------- /// @brief Update the specified display data in the framework. /// @@ -430,7 +442,7 @@ class PlatformConfiguration final { /// @return a pointer to the Window. Returns nullptr if the ID is not /// found. /// - Window* get_window(int window_id); + const ViewportMetrics* GetMetrics(int view_id); //---------------------------------------------------------------------------- /// @brief Responds to a previous platform message to the engine from the @@ -457,7 +469,9 @@ class PlatformConfiguration final { private: PlatformConfigurationClient* client_; tonic::DartPersistentValue on_error_; + tonic::DartPersistentValue add_view_; tonic::DartPersistentValue remove_view_; + tonic::DartPersistentValue update_window_metrics_; tonic::DartPersistentValue update_displays_; tonic::DartPersistentValue update_locales_; tonic::DartPersistentValue update_user_settings_data_; @@ -471,10 +485,8 @@ class PlatformConfiguration final { tonic::DartPersistentValue draw_frame_; tonic::DartPersistentValue report_timings_; - tonic::DartPersistentValue library_; - - // All current views mapped from view IDs. - std::unordered_map> windows_; + // All current views' view metrics mapped from view IDs. + std::unordered_map metrics_; // ID starts at 1 because an ID of 0 indicates that no response is expected. int next_response_id_ = 1; diff --git a/lib/ui/window/platform_configuration_unittests.cc b/lib/ui/window/platform_configuration_unittests.cc index 017055a41d91e..7410caeb66d6c 100644 --- a/lib/ui/window/platform_configuration_unittests.cc +++ b/lib/ui/window/platform_configuration_unittests.cc @@ -24,21 +24,17 @@ class PlatformConfigurationTest : public ShellTest {}; TEST_F(PlatformConfigurationTest, Initialization) { auto message_latch = std::make_shared(); - auto nativeValidateConfiguration = [message_latch]( - Dart_NativeArguments args) { - PlatformConfiguration* configuration = - UIDartState::Current()->platform_configuration(); - ASSERT_NE(configuration->get_window(0), nullptr); - ASSERT_EQ( - configuration->get_window(0)->viewport_metrics().device_pixel_ratio, - 1.0); - ASSERT_EQ(configuration->get_window(0)->viewport_metrics().physical_width, - 0.0); - ASSERT_EQ(configuration->get_window(0)->viewport_metrics().physical_height, - 0.0); + auto nativeValidateConfiguration = + [message_latch](Dart_NativeArguments args) { + PlatformConfiguration* configuration = + UIDartState::Current()->platform_configuration(); + ASSERT_NE(configuration->GetMetrics(0), nullptr); + ASSERT_EQ(configuration->GetMetrics(0)->device_pixel_ratio, 1.0); + ASSERT_EQ(configuration->GetMetrics(0)->physical_width, 0.0); + ASSERT_EQ(configuration->GetMetrics(0)->physical_height, 0.0); - message_latch->Signal(); - }; + message_latch->Signal(); + }; Settings settings = CreateSettingsForFixture(); TaskRunners task_runners("test", // label @@ -68,27 +64,22 @@ TEST_F(PlatformConfigurationTest, Initialization) { TEST_F(PlatformConfigurationTest, WindowMetricsUpdate) { auto message_latch = std::make_shared(); - auto nativeValidateConfiguration = [message_latch]( - Dart_NativeArguments args) { - PlatformConfiguration* configuration = - UIDartState::Current()->platform_configuration(); - - ASSERT_NE(configuration->get_window(0), nullptr); - configuration->get_window(0)->UpdateWindowMetrics( - ViewportMetrics{2.0, 10.0, 20.0, 22, 0}); - ASSERT_EQ( - configuration->get_window(0)->viewport_metrics().device_pixel_ratio, - 2.0); - ASSERT_EQ(configuration->get_window(0)->viewport_metrics().physical_width, - 10.0); - ASSERT_EQ(configuration->get_window(0)->viewport_metrics().physical_height, - 20.0); - ASSERT_EQ( - configuration->get_window(0)->viewport_metrics().physical_touch_slop, - 22); + auto nativeValidateConfiguration = + [message_latch](Dart_NativeArguments args) { + PlatformConfiguration* configuration = + UIDartState::Current()->platform_configuration(); - message_latch->Signal(); - }; + ASSERT_NE(configuration->GetMetrics(0), nullptr); + bool has_view = configuration->UpdateViewMetrics( + 0, ViewportMetrics{2.0, 10.0, 20.0, 22, 0}); + ASSERT_TRUE(has_view); + ASSERT_EQ(configuration->GetMetrics(0)->device_pixel_ratio, 2.0); + ASSERT_EQ(configuration->GetMetrics(0)->physical_width, 10.0); + ASSERT_EQ(configuration->GetMetrics(0)->physical_height, 20.0); + ASSERT_EQ(configuration->GetMetrics(0)->physical_touch_slop, 22); + + message_latch->Signal(); + }; Settings settings = CreateSettingsForFixture(); TaskRunners task_runners("test", // label @@ -123,8 +114,8 @@ TEST_F(PlatformConfigurationTest, GetWindowReturnsNullForNonexistentId) { PlatformConfiguration* configuration = UIDartState::Current()->platform_configuration(); - ASSERT_EQ(configuration->get_window(1), nullptr); - ASSERT_EQ(configuration->get_window(2), nullptr); + ASSERT_EQ(configuration->GetMetrics(1), nullptr); + ASSERT_EQ(configuration->GetMetrics(2), nullptr); message_latch->Signal(); }; diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc deleted file mode 100644 index 0800f10d31206..0000000000000 --- a/lib/ui/window/window.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/lib/ui/window/window.h" - -#include - -#include "third_party/tonic/converter/dart_converter.h" -#include "third_party/tonic/dart_args.h" -#include "third_party/tonic/logging/dart_invoke.h" -#include "third_party/tonic/typed_data/dart_byte_data.h" - -namespace flutter { - -Window::Window(tonic::DartPersistentValue& library, - int64_t window_id, - ViewportMetrics metrics) - : library_(library), - window_id_(window_id), - viewport_metrics_(std::move(metrics)) {} - -Window::~Window() {} - -void Window::AddView() { - std::shared_ptr dart_state = library_.dart_state().lock(); - if (!dart_state) { - return; - } - tonic::DartState::Scope scope(dart_state); - tonic::CheckAndHandleError(tonic::DartInvokeField( - library_.value(), "_addView", - { - tonic::ToDart(window_id_), - tonic::ToDart(viewport_metrics_.device_pixel_ratio), - tonic::ToDart(viewport_metrics_.physical_width), - tonic::ToDart(viewport_metrics_.physical_height), - tonic::ToDart(viewport_metrics_.physical_padding_top), - tonic::ToDart(viewport_metrics_.physical_padding_right), - tonic::ToDart(viewport_metrics_.physical_padding_bottom), - tonic::ToDart(viewport_metrics_.physical_padding_left), - tonic::ToDart(viewport_metrics_.physical_view_inset_top), - tonic::ToDart(viewport_metrics_.physical_view_inset_right), - tonic::ToDart(viewport_metrics_.physical_view_inset_bottom), - tonic::ToDart(viewport_metrics_.physical_view_inset_left), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_top), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_right), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_bottom), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_left), - tonic::ToDart(viewport_metrics_.physical_touch_slop), - tonic::ToDart(viewport_metrics_.physical_display_features_bounds), - tonic::ToDart(viewport_metrics_.physical_display_features_type), - tonic::ToDart(viewport_metrics_.physical_display_features_state), - tonic::ToDart(viewport_metrics_.display_id), - })); -} - -void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) { - viewport_metrics_ = metrics; - - std::shared_ptr dart_state = library_.dart_state().lock(); - if (!dart_state) { - return; - } - tonic::DartState::Scope scope(dart_state); - tonic::CheckAndHandleError(tonic::DartInvokeField( - library_.value(), "_updateWindowMetrics", - { - tonic::ToDart(window_id_), - tonic::ToDart(viewport_metrics_.device_pixel_ratio), - tonic::ToDart(viewport_metrics_.physical_width), - tonic::ToDart(viewport_metrics_.physical_height), - tonic::ToDart(viewport_metrics_.physical_padding_top), - tonic::ToDart(viewport_metrics_.physical_padding_right), - tonic::ToDart(viewport_metrics_.physical_padding_bottom), - tonic::ToDart(viewport_metrics_.physical_padding_left), - tonic::ToDart(viewport_metrics_.physical_view_inset_top), - tonic::ToDart(viewport_metrics_.physical_view_inset_right), - tonic::ToDart(viewport_metrics_.physical_view_inset_bottom), - tonic::ToDart(viewport_metrics_.physical_view_inset_left), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_top), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_right), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_bottom), - tonic::ToDart(viewport_metrics_.physical_system_gesture_inset_left), - tonic::ToDart(viewport_metrics_.physical_touch_slop), - tonic::ToDart(viewport_metrics_.physical_display_features_bounds), - tonic::ToDart(viewport_metrics_.physical_display_features_type), - tonic::ToDart(viewport_metrics_.physical_display_features_state), - tonic::ToDart(viewport_metrics_.display_id), - })); -} - -} // namespace flutter diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h deleted file mode 100644 index 7945f594e1b6e..0000000000000 --- a/lib/ui/window/window.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_LIB_UI_WINDOW_WINDOW_H_ -#define FLUTTER_LIB_UI_WINDOW_WINDOW_H_ - -#include -#include -#include -#include - -#include "flutter/lib/ui/window/key_data_packet.h" -#include "flutter/lib/ui/window/platform_message.h" -#include "flutter/lib/ui/window/pointer_data_packet.h" -#include "flutter/lib/ui/window/viewport_metrics.h" -#include "third_party/skia/include/gpu/GrDirectContext.h" -#include "third_party/tonic/dart_persistent_value.h" - -namespace flutter { -class Window final { - public: - Window(tonic::DartPersistentValue& library, - int64_t window_id, - ViewportMetrics metrics); - - ~Window(); - - int window_id() const { return window_id_; } - - const ViewportMetrics& viewport_metrics() const { return viewport_metrics_; } - - // Called by PlatformConfiguration to send an AddView message to Dart with the - // current view metrics. - // - // This must not be called more than once per `window_id`. - void AddView(); - - // Update view metrics, and send an UpdateWindowMetrics message to Dart. - void UpdateWindowMetrics(const ViewportMetrics& metrics); - - private: - tonic::DartPersistentValue& library_; - int64_t window_id_; - ViewportMetrics viewport_metrics_; -}; - -} // namespace flutter - -#endif // FLUTTER_LIB_UI_WINDOW_WINDOW_H_ diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 1884eeb338981..36d1f129bf86a 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -13,7 +13,6 @@ #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/lib/ui/window/viewport_metrics.h" -#include "flutter/lib/ui/window/window.h" #include "flutter/runtime/dart_isolate_group_data.h" #include "flutter/runtime/isolate_configuration.h" #include "flutter/runtime/runtime_delegate.h" @@ -159,13 +158,7 @@ bool RuntimeController::SetViewportMetrics(int64_t view_id, platform_data_.viewport_metrics_for_views[view_id] = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { - Window* window = platform_configuration->get_window(view_id); - if (window) { - window->UpdateWindowMetrics(metrics); - return true; - } else { - FML_LOG(WARNING) << "View ID " << view_id << " does not exist."; - } + return platform_configuration->UpdateViewMetrics(view_id, metrics); } return false; @@ -350,15 +343,14 @@ void RuntimeController::ScheduleFrame() { void RuntimeController::Render(Scene* scene) { // TODO(dkwingsmt): Currently only supports a single window. int64_t view_id = kFlutterImplicitViewId; - auto window = - UIDartState::Current()->platform_configuration()->get_window(view_id); - if (window == nullptr) { + const ViewportMetrics* view_metrics = + UIDartState::Current()->platform_configuration()->GetMetrics(view_id); + if (view_metrics == nullptr) { return; } - const auto& viewport_metrics = window->viewport_metrics(); - client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, - viewport_metrics.physical_height), - viewport_metrics.device_pixel_ratio); + client_.Render(scene->takeLayerTree(view_metrics->physical_width, + view_metrics->physical_height), + view_metrics->device_pixel_ratio); } // |PlatformConfigurationClient| diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index 22fd9dbfa854c..0074361fafda8 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -17,7 +17,6 @@ #include "flutter/fml/logging.h" #include "flutter/fml/make_copyable.h" #include "flutter/lib/ui/window/pointer_data.h" -#include "flutter/lib/ui/window/window.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h" #include "third_party/rapidjson/include/rapidjson/document.h" From 6a49f79d68617b6675808642b692ddf1b5762aa7 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 16 Aug 2023 18:34:24 -0700 Subject: [PATCH 43/46] return when assert --- lib/ui/window/platform_configuration.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index f4d82e20473fe..be32266543a36 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -121,8 +121,11 @@ void PlatformConfiguration::AddView(int64_t view_id, } void PlatformConfiguration::RemoveView(int64_t view_id) { - FML_DCHECK(view_id != kFlutterImplicitViewId) - << "The implicit view #" << view_id << " should never be removed."; + if (view_id == kFlutterImplicitViewId) { + FML_LOG(ERROR) << "The implicit view #" << view_id << " cannot be removed."; + FML_DCHECK(false); + return; + } size_t erased_elements = metrics_.erase(view_id); FML_DCHECK(erased_elements != 0) << "View #" << view_id << " doesn't exist."; (void)erased_elements; // Suppress unused variable warning From f634fe1b160cfc3e7058ba7205affd764ba15b4b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 17 Aug 2023 12:03:06 -0700 Subject: [PATCH 44/46] Move to constants --- common/constants.h | 26 ++++++++++++++++++ common/settings.h | 27 ------------------- lib/ui/dart_ui.cc | 1 + lib/ui/window/platform_configuration.cc | 1 + runtime/platform_data.h | 1 - runtime/runtime_controller.cc | 1 + shell/common/rasterizer.cc | 1 + shell/common/shell.cc | 1 + .../ios/framework/Source/FlutterEngine.mm | 2 +- 9 files changed, 32 insertions(+), 29 deletions(-) diff --git a/common/constants.h b/common/constants.h index 378f7c84e7c0f..668aa4f64ebd2 100644 --- a/common/constants.h +++ b/common/constants.h @@ -7,6 +7,32 @@ namespace flutter { constexpr double kMegaByteSizeInBytes = (1 << 20); + +// The ID for the implicit view if the implicit view is enabled. +// +// The implicit view is a compatibility mechanism to help the transition from +// the older single-view APIs to the newer multi-view APIs. The two sets of APIs +// use different models for view management. The implicit view mechanism allows +// single-view APIs to operate a special view as if other views don't exist. +// +// In the regular multi-view model, all views should be created by +// `Shell::AddView` before being used, and removed by `Shell::RemoveView` to +// signify that they are gone. If a view is added or removed, the framework +// (`PlatformDispatcher`) will be notified. New view IDs are always unique, +// never reused. Operating a non-existing view is an error. +// +// The implicit view is another special view in addition to the "regular views" +// as above. The shell starts up having the implicit view, which has a fixed +// view ID of `kFlutterImplicitViewId` and is available throughout the lifetime +// of the shell. `Shell::AddView` or `RemoveView` must not be called for this +// view. Even when the window that shows the view is closed, the framework is +// unaware and might continue rendering into or operating this view. +// +// The single-view APIs, which are APIs that do not specify view IDs, operate +// the implicit view. The multi-view APIs can operate all views, including the +// implicit view if the target ID is `kFlutterImplicitViewId`, unless specified +// otherwise. +constexpr int64_t kFlutterImplicitViewId = 0; } // namespace flutter #endif // FLUTTER_COMMON_CONSTANTS_H_ diff --git a/common/settings.h b/common/settings.h index 7ca439af0f5e9..09955cddffbb1 100644 --- a/common/settings.h +++ b/common/settings.h @@ -21,33 +21,6 @@ #include "flutter/fml/unique_fd.h" namespace flutter { - -// The ID for the implicit view if the implicit view is enabled. -// -// The implicit view is a compatibility mechanism to help the transition from -// the older single-view APIs to the newer multi-view APIs. The two sets of APIs -// use different models for view management. The implicit view mechanism allows -// single-view APIs to operate a special view as if other views don't exist. -// -// In the regular multi-view model, all views should be created by -// `Shell::AddView` before being used, and removed by `Shell::RemoveView` to -// signify that they are gone. If a view is added or removed, the framework -// (`PlatformDispatcher`) will be notified. New view IDs are always unique, -// never reused. Operating a non-existing view is an error. -// -// The implicit view is another special view in addition to the "regular views" -// as above. The shell starts up having the implicit view, which has a fixed -// view ID of `kFlutterImplicitViewId` and is available throughout the lifetime -// of the shell. `Shell::AddView` or `RemoveView` must not be called for this -// view. Even when the window that shows the view is closed, the framework is -// unaware and might continue rendering into or operating this view. -// -// The single-view APIs, which are APIs that do not specify view IDs, operate -// the implicit view. The multi-view APIs can operate all views, including the -// implicit view if the target ID is `kFlutterImplicitViewId`, unless specified -// otherwise. -constexpr int64_t kFlutterImplicitViewId = 0; - class FrameTiming { public: enum Phase { diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 323b69745d776..02a6b79978241 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -7,6 +7,7 @@ #include #include +#include "flutter/common/constants.h" #include "flutter/common/settings.h" #include "flutter/fml/build_config.h" #include "flutter/lib/ui/compositing/scene.h" diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index be32266543a36..c796bdfac5ef4 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -6,6 +6,7 @@ #include +#include "flutter/common/constants.h" #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_message.h" diff --git a/runtime/platform_data.h b/runtime/platform_data.h index a101323f83c7d..f7f00e1380b76 100644 --- a/runtime/platform_data.h +++ b/runtime/platform_data.h @@ -9,7 +9,6 @@ #include #include -#include "flutter/common/settings.h" #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/shell/common/display.h" diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 36d1f129bf86a..a11b9c2ff24f3 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -6,6 +6,7 @@ #include +#include "flutter/common/constants.h" #include "flutter/common/settings.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/trace_event.h" diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 32e68e910c545..7cc45fa1f5b5a 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -9,6 +9,7 @@ #include #include "flow/frame_timings.h" +#include "flutter/common/constants.h" #include "flutter/common/graphics/persistent_cache.h" #include "flutter/flow/layers/offscreen_surface.h" #include "flutter/fml/time/time_delta.h" diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 57b2c055d1427..7964a530031db 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -11,6 +11,7 @@ #include #include "flutter/assets/directory_asset_bundle.h" +#include "flutter/common/constants.h" #include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/base32.h" #include "flutter/fml/file.h" diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index ebe4f056c03e1..b300714f166ad 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -8,7 +8,7 @@ #include -#include "flutter/common/settings.h" +#include "flutter/common/constants.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/platform/darwin/platform_version.h" #include "flutter/fml/trace_event.h" From 42f4309d1e243df81a91c8fb35b9ee06a256b11d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 17 Aug 2023 12:04:45 -0700 Subject: [PATCH 45/46] Revert empty line --- common/settings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/common/settings.h b/common/settings.h index 09955cddffbb1..d9df7e707b172 100644 --- a/common/settings.h +++ b/common/settings.h @@ -21,6 +21,7 @@ #include "flutter/fml/unique_fd.h" namespace flutter { + class FrameTiming { public: enum Phase { From 64ecc08e0e4b90251d14b050d7e905de26983ae2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 17 Aug 2023 12:30:49 -0700 Subject: [PATCH 46/46] Fix compile --- shell/platform/android/platform_view_android_jni_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 802b12bd2b4e4..b755e4f4d2ed0 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -17,7 +17,7 @@ #include "unicode/uchar.h" #include "flutter/assets/directory_asset_bundle.h" -#include "flutter/common/settings.h" +#include "flutter/common/constants.h" #include "flutter/fml/file.h" #include "flutter/fml/mapping.h" #include "flutter/fml/native_library.h"