From 2999d0c5acf55d893f87b8ee0ddfadaf6e8da4aa Mon Sep 17 00:00:00 2001 From: "jianguang.cjg" Date: Fri, 8 May 2020 16:53:23 +0800 Subject: [PATCH 1/3] Setup default font manager after engine created, to improve startup performance. --- lib/ui/text/font_collection.cc | 6 ++++-- lib/ui/text/font_collection.h | 2 ++ shell/common/engine.cc | 5 +++++ shell/common/engine.h | 7 +++++++ shell/common/shell.cc | 8 ++++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/ui/text/font_collection.cc b/lib/ui/text/font_collection.cc index 8d1070852c391..c59dac720875d 100644 --- a/lib/ui/text/font_collection.cc +++ b/lib/ui/text/font_collection.cc @@ -47,8 +47,6 @@ void _LoadFontFromList(Dart_NativeArguments args) { FontCollection::FontCollection() : collection_(std::make_shared()) { - collection_->SetupDefaultFontManager(); - dynamic_font_manager_ = sk_make_sp(); collection_->SetDynamicFontManager(dynamic_font_manager_); } @@ -68,6 +66,10 @@ std::shared_ptr FontCollection::GetFontCollection() const { return collection_; } +void FontCollection::SetupDefaultFontManager() { + collection_->SetupDefaultFontManager(); +} + void FontCollection::RegisterFonts( std::shared_ptr asset_manager) { std::unique_ptr manifest_mapping = diff --git a/lib/ui/text/font_collection.h b/lib/ui/text/font_collection.h index 4e19e2a999776..48e0e1e49db06 100644 --- a/lib/ui/text/font_collection.h +++ b/lib/ui/text/font_collection.h @@ -29,6 +29,8 @@ class FontCollection { std::shared_ptr GetFontCollection() const; + void SetupDefaultFontManager(); + void RegisterFonts(std::shared_ptr asset_manager); void RegisterTestFonts(); diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 4703411376357..9f03c9200fd32 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -90,6 +90,11 @@ fml::WeakPtr Engine::GetWeakPtr() const { return weak_factory_.GetWeakPtr(); } +void Engine::SetupDefaultFontManager() { + TRACE_EVENT0("flutter", "Engine::SetupDefaultFontManager"); + font_collection_.SetupDefaultFontManager(); +} + bool Engine::UpdateAssetManager( std::shared_ptr new_asset_manager) { if (asset_manager_ == new_asset_manager) { diff --git a/shell/common/engine.h b/shell/common/engine.h index 0f5f0717220b1..71ca9d678c709 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -363,6 +363,13 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// [[nodiscard]] bool Restart(RunConfiguration configuration); + //---------------------------------------------------------------------------- + /// @brief Setup default font manager according to specific platform. + /// + /// @attention This operation calls `SkFontMgr::RefDefault` which is + /// time-consuming except running at linux and windows. + void SetupDefaultFontManager(); + //---------------------------------------------------------------------------- /// @brief Updates the asset manager referenced by the root isolate of a /// Flutter application. This happens implicitly in the call to diff --git a/shell/common/shell.cc b/shell/common/shell.cc index fd5a581647de8..99236e05cb50f 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -542,6 +542,14 @@ bool Shell::Setup(std::unique_ptr platform_view, weak_rasterizer_ = rasterizer_->GetWeakPtr(); weak_platform_view_ = platform_view_->GetWeakPtr(); + // Setup the time-consuming default font manager right after engine created. + fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(), + [engine = weak_engine_] { + if (engine) { + engine->SetupDefaultFontManager(); + } + }); + is_setup_ = true; vm_->GetServiceProtocol()->AddHandler(this, GetServiceProtocolDescription()); From 322cd0bc0216b7c1aa05091f53b4f989243fc6a3 Mon Sep 17 00:00:00 2001 From: "jianguang.cjg" Date: Mon, 18 May 2020 20:56:39 +0800 Subject: [PATCH 2/3] Pre-warm default font manager, to reduce time cost of engine setup --- shell/platform/android/flutter_main.cc | 10 ++++++++++ .../io/flutter/embedding/engine/FlutterJNI.java | 7 +++++++ .../embedding/engine/loader/FlutterLoader.java | 11 +++++++++++ 3 files changed, 28 insertions(+) diff --git a/shell/platform/android/flutter_main.cc b/shell/platform/android/flutter_main.cc index cb2d51649aaeb..617df007f46c4 100644 --- a/shell/platform/android/flutter_main.cc +++ b/shell/platform/android/flutter_main.cc @@ -21,6 +21,7 @@ #include "flutter/shell/common/shell.h" #include "flutter/shell/common/switches.h" #include "third_party/dart/runtime/include/dart_tools_api.h" +#include "third_party/skia/include/core/SkFontMgr.h" namespace flutter { @@ -155,6 +156,10 @@ void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) { }); } +static void CreateDefaultFontManager(JNIEnv* env, jclass jcaller) { + sk_sp font_mgr(SkFontMgr::RefDefault()); +} + bool FlutterMain::Register(JNIEnv* env) { static const JNINativeMethod methods[] = { { @@ -163,6 +168,11 @@ bool FlutterMain::Register(JNIEnv* env) { "lang/String;Ljava/lang/String;Ljava/lang/String;J)V", .fnPtr = reinterpret_cast(&Init), }, + { + .name = "nativeCreateDefaultFontManager", + .signature = "()V", + .fnPtr = reinterpret_cast(&CreateDefaultFontManager), + }, }; jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI"); diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 6f55fce248f72..94f6fcca2beff 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -106,6 +106,13 @@ public static native void nativeInit( @NonNull String engineCachesPath, long initTimeMillis); + /** + * Create the default font manager provided by SkFontMgr::RefDefault() which is a process-wide + * singleton owned by Skia. Note that, the first call to SkFontMgr::RefDefault() will take + * noticeable time, but later calls will return a reference to the preexisting font manager. + */ + public static native void nativeCreateDefaultFontManager(); + // TODO(mattcarroll): add javadocs @UiThread public native boolean nativeGetIsSoftwareRenderingEnabled(); diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index bd506957289fe..ad75a9cd0c187 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -144,6 +144,17 @@ public InitResult call() { System.loadLibrary("flutter"); + // Pre-warm the default font manager as soon as possible on a background thread. + // It helps to reduce time cost of engine setup that blocks the platform thread. + new Thread( + new Runnable() { + @Override + public void run() { + FlutterJNI.nativeCreateDefaultFontManager(); + } + }) + .start(); + if (resourceExtractor != null) { resourceExtractor.waitForCompletion(); } From e5b6447ee5fe5bec4bb9162af95b81f6620f00d3 Mon Sep 17 00:00:00 2001 From: "jianguang.cjg" Date: Wed, 20 May 2020 15:53:09 +0800 Subject: [PATCH 3/3] Update changes as review requested. --- shell/common/engine.h | 2 -- shell/platform/android/flutter_main.cc | 9 +++++---- .../io/flutter/embedding/engine/FlutterJNI.java | 4 ++-- .../flutter/embedding/engine/loader/FlutterLoader.java | 10 +++++----- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/shell/common/engine.h b/shell/common/engine.h index 71ca9d678c709..5f970b3717701 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -366,8 +366,6 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { //---------------------------------------------------------------------------- /// @brief Setup default font manager according to specific platform. /// - /// @attention This operation calls `SkFontMgr::RefDefault` which is - /// time-consuming except running at linux and windows. void SetupDefaultFontManager(); //---------------------------------------------------------------------------- diff --git a/shell/platform/android/flutter_main.cc b/shell/platform/android/flutter_main.cc index 617df007f46c4..1493bf4f0d161 100644 --- a/shell/platform/android/flutter_main.cc +++ b/shell/platform/android/flutter_main.cc @@ -156,8 +156,9 @@ void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) { }); } -static void CreateDefaultFontManager(JNIEnv* env, jclass jcaller) { - sk_sp font_mgr(SkFontMgr::RefDefault()); +static void PrefetchDefaultFontManager(JNIEnv* env, jclass jcaller) { + // Initialize a singleton owned by Skia. + SkFontMgr::RefDefault(); } bool FlutterMain::Register(JNIEnv* env) { @@ -169,9 +170,9 @@ bool FlutterMain::Register(JNIEnv* env) { .fnPtr = reinterpret_cast(&Init), }, { - .name = "nativeCreateDefaultFontManager", + .name = "nativePrefetchDefaultFontManager", .signature = "()V", - .fnPtr = reinterpret_cast(&CreateDefaultFontManager), + .fnPtr = reinterpret_cast(&PrefetchDefaultFontManager), }, }; diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 94f6fcca2beff..b0d5ad9ba19e2 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -107,11 +107,11 @@ public static native void nativeInit( long initTimeMillis); /** - * Create the default font manager provided by SkFontMgr::RefDefault() which is a process-wide + * Prefetch the default font manager provided by SkFontMgr::RefDefault() which is a process-wide * singleton owned by Skia. Note that, the first call to SkFontMgr::RefDefault() will take * noticeable time, but later calls will return a reference to the preexisting font manager. */ - public static native void nativeCreateDefaultFontManager(); + public static native void nativePrefetchDefaultFontManager(); // TODO(mattcarroll): add javadocs @UiThread diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index ad75a9cd0c187..c57d8c86b8374 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -144,16 +144,16 @@ public InitResult call() { System.loadLibrary("flutter"); - // Pre-warm the default font manager as soon as possible on a background thread. + // Prefetch the default font manager as soon as possible on a background thread. // It helps to reduce time cost of engine setup that blocks the platform thread. - new Thread( + Executors.newSingleThreadExecutor() + .execute( new Runnable() { @Override public void run() { - FlutterJNI.nativeCreateDefaultFontManager(); + FlutterJNI.nativePrefetchDefaultFontManager(); } - }) - .start(); + }); if (resourceExtractor != null) { resourceExtractor.waitForCompletion();