Setup default font manager after engine created, to improve startup performance (flutter/engine#18225)

This commit is contained in:
chenjianguang 2020-05-29 08:53:04 +08:00 committed by GitHub
parent 384105d5d8
commit db630fbd93
8 changed files with 53 additions and 2 deletions

View File

@ -47,8 +47,6 @@ void _LoadFontFromList(Dart_NativeArguments args) {
FontCollection::FontCollection()
: collection_(std::make_shared<txt::FontCollection>()) {
collection_->SetupDefaultFontManager();
dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
collection_->SetDynamicFontManager(dynamic_font_manager_);
}
@ -68,6 +66,10 @@ std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}
void FontCollection::SetupDefaultFontManager() {
collection_->SetupDefaultFontManager();
}
void FontCollection::RegisterFonts(
std::shared_ptr<AssetManager> asset_manager) {
std::unique_ptr<fml::Mapping> manifest_mapping =

View File

@ -29,6 +29,8 @@ class FontCollection {
std::shared_ptr<txt::FontCollection> GetFontCollection() const;
void SetupDefaultFontManager();
void RegisterFonts(std::shared_ptr<AssetManager> asset_manager);
void RegisterTestFonts();

View File

@ -90,6 +90,11 @@ fml::WeakPtr<Engine> Engine::GetWeakPtr() const {
return weak_factory_.GetWeakPtr();
}
void Engine::SetupDefaultFontManager() {
TRACE_EVENT0("flutter", "Engine::SetupDefaultFontManager");
font_collection_.SetupDefaultFontManager();
}
bool Engine::UpdateAssetManager(
std::shared_ptr<AssetManager> new_asset_manager) {
if (asset_manager_ == new_asset_manager) {

View File

@ -363,6 +363,11 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
///
[[nodiscard]] bool Restart(RunConfiguration configuration);
//----------------------------------------------------------------------------
/// @brief Setup default font manager according to specific platform.
///
void SetupDefaultFontManager();
//----------------------------------------------------------------------------
/// @brief Updates the asset manager referenced by the root isolate of a
/// Flutter application. This happens implicitly in the call to

View File

@ -542,6 +542,14 @@ bool Shell::Setup(std::unique_ptr<PlatformView> 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());

View File

@ -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,11 @@ void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) {
});
}
static void PrefetchDefaultFontManager(JNIEnv* env, jclass jcaller) {
// Initialize a singleton owned by Skia.
SkFontMgr::RefDefault();
}
bool FlutterMain::Register(JNIEnv* env) {
static const JNINativeMethod methods[] = {
{
@ -163,6 +169,11 @@ bool FlutterMain::Register(JNIEnv* env) {
"lang/String;Ljava/lang/String;Ljava/lang/String;J)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
.name = "nativePrefetchDefaultFontManager",
.signature = "()V",
.fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager),
},
};
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");

View File

@ -106,6 +106,13 @@ public class FlutterJNI {
@NonNull String engineCachesPath,
long initTimeMillis);
/**
* 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 nativePrefetchDefaultFontManager();
// TODO(mattcarroll): add javadocs
@UiThread
public native boolean nativeGetIsSoftwareRenderingEnabled();

View File

@ -144,6 +144,17 @@ public class FlutterLoader {
System.loadLibrary("flutter");
// 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.
Executors.newSingleThreadExecutor()
.execute(
new Runnable() {
@Override
public void run() {
FlutterJNI.nativePrefetchDefaultFontManager();
}
});
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
}