diff --git a/assets/asset_manager.h b/assets/asset_manager.h index 4ab58ed0f2bf7..41c05ec7f9640 100644 --- a/assets/asset_manager.h +++ b/assets/asset_manager.h @@ -15,9 +15,12 @@ namespace blink { -class AssetManager final : public AssetResolver, - public fml::RefCountedThreadSafe { +class AssetManager final : public AssetResolver { public: + AssetManager(); + + ~AssetManager(); + void PushFront(std::unique_ptr resolver); void PushBack(std::unique_ptr resolver); @@ -32,13 +35,7 @@ class AssetManager final : public AssetResolver, private: std::deque> resolvers_; - AssetManager(); - - ~AssetManager(); - FML_DISALLOW_COPY_AND_ASSIGN(AssetManager); - FML_FRIEND_MAKE_REF_COUNTED(AssetManager); - FML_FRIEND_REF_COUNTED_THREAD_SAFE(AssetManager); }; } // namespace blink diff --git a/lib/ui/text/asset_manager_font_provider.cc b/lib/ui/text/asset_manager_font_provider.cc index b0be57f13e4a9..e247592365526 100644 --- a/lib/ui/text/asset_manager_font_provider.cc +++ b/lib/ui/text/asset_manager_font_provider.cc @@ -21,7 +21,7 @@ void MappingReleaseProc(const void* ptr, void* context) { } // anonymous namespace AssetManagerFontProvider::AssetManagerFontProvider( - fml::RefPtr asset_manager) + std::shared_ptr asset_manager) : asset_manager_(asset_manager) {} AssetManagerFontProvider::~AssetManagerFontProvider() = default; @@ -65,7 +65,7 @@ void AssetManagerFontProvider::RegisterAsset(std::string family_name, } AssetManagerFontStyleSet::AssetManagerFontStyleSet( - fml::RefPtr asset_manager) + std::shared_ptr asset_manager) : asset_manager_(asset_manager) {} AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default; diff --git a/lib/ui/text/asset_manager_font_provider.h b/lib/ui/text/asset_manager_font_provider.h index a6f9544ab2611..89554b14f527e 100644 --- a/lib/ui/text/asset_manager_font_provider.h +++ b/lib/ui/text/asset_manager_font_provider.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_LIB_UI_TEXT_ASSET_MANAGER_FONT_PROVIDER_H_ #define FLUTTER_LIB_UI_TEXT_ASSET_MANAGER_FONT_PROVIDER_H_ +#include #include #include #include @@ -18,7 +19,7 @@ namespace blink { class AssetManagerFontStyleSet : public SkFontStyleSet { public: - AssetManagerFontStyleSet(fml::RefPtr asset_manager); + AssetManagerFontStyleSet(std::shared_ptr asset_manager); ~AssetManagerFontStyleSet() override; @@ -37,7 +38,7 @@ class AssetManagerFontStyleSet : public SkFontStyleSet { SkTypeface* matchStyle(const SkFontStyle& pattern) override; private: - fml::RefPtr asset_manager_; + std::shared_ptr asset_manager_; struct TypefaceAsset { TypefaceAsset(std::string a) : asset(std::move(a)) {} @@ -51,7 +52,8 @@ class AssetManagerFontStyleSet : public SkFontStyleSet { class AssetManagerFontProvider : public txt::FontAssetProvider { public: - AssetManagerFontProvider(fml::RefPtr asset_manager); + AssetManagerFontProvider(std::shared_ptr asset_manager); + ~AssetManagerFontProvider() override; void RegisterAsset(std::string family_name, std::string asset); @@ -66,7 +68,7 @@ class AssetManagerFontProvider : public txt::FontAssetProvider { SkFontStyleSet* MatchFamily(const std::string& family_name) override; private: - fml::RefPtr asset_manager_; + std::shared_ptr asset_manager_; std::unordered_map registered_families_; std::vector family_names_; diff --git a/lib/ui/text/font_collection.cc b/lib/ui/text/font_collection.cc index 83166f96bbf9d..aee3711a100df 100644 --- a/lib/ui/text/font_collection.cc +++ b/lib/ui/text/font_collection.cc @@ -67,7 +67,8 @@ std::shared_ptr FontCollection::GetFontCollection() const { return collection_; } -void FontCollection::RegisterFonts(fml::RefPtr asset_manager) { +void FontCollection::RegisterFonts( + std::shared_ptr asset_manager) { std::unique_ptr manifest_mapping = asset_manager->GetAsMapping("FontManifest.json"); if (manifest_mapping == nullptr) { diff --git a/lib/ui/text/font_collection.h b/lib/ui/text/font_collection.h index a9bf31d73a2bc..9b0804dcd7d8a 100644 --- a/lib/ui/text/font_collection.h +++ b/lib/ui/text/font_collection.h @@ -29,7 +29,7 @@ class FontCollection { std::shared_ptr GetFontCollection() const; - void RegisterFonts(fml::RefPtr asset_manager); + void RegisterFonts(std::shared_ptr asset_manager); void RegisterTestFonts(); diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 59cff299b7ab0..f6f1553652b61 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -78,7 +78,7 @@ fml::WeakPtr Engine::GetWeakPtr() const { } bool Engine::UpdateAssetManager( - fml::RefPtr new_asset_manager) { + std::shared_ptr new_asset_manager) { if (asset_manager_ == new_asset_manager) { return false; } diff --git a/shell/common/engine.h b/shell/common/engine.h index 0f79eeeb31c00..2f34dcf3db31d 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -75,7 +75,7 @@ class Engine final : public blink::RuntimeDelegate { FML_WARN_UNUSED_RESULT bool Restart(RunConfiguration configuration); - bool UpdateAssetManager(fml::RefPtr asset_manager); + bool UpdateAssetManager(std::shared_ptr asset_manager); void BeginFrame(fml::TimePoint frame_time); @@ -121,7 +121,7 @@ class Engine final : public blink::RuntimeDelegate { std::unique_ptr runtime_controller_; std::string initial_route_; blink::ViewportMetrics viewport_metrics_; - fml::RefPtr asset_manager_; + std::shared_ptr asset_manager_; bool activity_running_; bool have_surface_; blink::FontCollection font_collection_; diff --git a/shell/common/isolate_configuration.cc b/shell/common/isolate_configuration.cc index 57c38bef9f8d8..c3bbc04c653a2 100644 --- a/shell/common/isolate_configuration.cc +++ b/shell/common/isolate_configuration.cc @@ -4,6 +4,7 @@ #include "flutter/shell/common/isolate_configuration.h" +#include "flutter/fml/make_copyable.h" #include "flutter/runtime/dart_vm.h" #ifdef ERROR @@ -61,7 +62,7 @@ class KernelIsolateConfiguration : public IsolateConfiguration { class KernelListIsolateConfiguration final : public IsolateConfiguration { public: KernelListIsolateConfiguration( - std::vector> kernel_pieces) + std::vector>> kernel_pieces) : kernel_pieces_(std::move(kernel_pieces)) {} // |shell::IsolateConfiguration| @@ -72,7 +73,8 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration { for (size_t i = 0; i < kernel_pieces_.size(); i++) { bool last_piece = i + 1 == kernel_pieces_.size(); - if (!isolate.PrepareForRunningFromKernel(std::move(kernel_pieces_[i]), + + if (!isolate.PrepareForRunningFromKernel(kernel_pieces_[i].get(), last_piece)) { return false; } @@ -82,21 +84,81 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration { } private: - std::vector> kernel_pieces_; + std::vector>> kernel_pieces_; FML_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration); }; +static std::vector ParseKernelListPaths( + std::unique_ptr kernel_list) { + FML_DCHECK(kernel_list); + + std::vector kernel_pieces_paths; + + const char* kernel_list_str = + reinterpret_cast(kernel_list->GetMapping()); + size_t kernel_list_size = kernel_list->GetSize(); + + size_t piece_path_start = 0; + while (piece_path_start < kernel_list_size) { + size_t piece_path_end = piece_path_start; + while ((piece_path_end < kernel_list_size) && + (kernel_list_str[piece_path_end] != '\n')) { + piece_path_end++; + } + std::string piece_path(&kernel_list_str[piece_path_start], + piece_path_end - piece_path_start); + kernel_pieces_paths.emplace_back(std::move(piece_path)); + + piece_path_start = piece_path_end + 1; + } + + return kernel_pieces_paths; +} + +static std::vector>> +PrepareKernelMappings(std::vector kernel_pieces_paths, + std::shared_ptr asset_manager, + fml::RefPtr io_worker) { + FML_DCHECK(asset_manager); + std::vector>> fetch_futures; + + for (const auto& kernel_pieces_path : kernel_pieces_paths) { + std::promise> fetch_promise; + fetch_futures.push_back(fetch_promise.get_future()); + auto fetch_task = + fml::MakeCopyable([asset_manager, kernel_pieces_path, + fetch_promise = std::move(fetch_promise)]() mutable { + fetch_promise.set_value( + asset_manager->GetAsMapping(kernel_pieces_path)); + }); + // Fulfill the promise on the worker if one is available or the current + // thread if one is not. + if (io_worker) { + io_worker->PostTask(fetch_task); + } else { + fetch_task(); + } + } + + return fetch_futures; +} + std::unique_ptr IsolateConfiguration::InferFromSettings( const blink::Settings& settings, - fml::RefPtr asset_manager) { + std::shared_ptr asset_manager, + fml::RefPtr io_worker) { // Running in AOT mode. if (blink::DartVM::IsRunningPrecompiledCode()) { return CreateForAppSnapshot(); } + if (!asset_manager) { + return nullptr; + } + // Running from kernel snapshot. - if (asset_manager) { + { std::unique_ptr kernel = asset_manager->GetAsMapping(settings.application_kernel_asset); if (kernel) { @@ -105,39 +167,14 @@ std::unique_ptr IsolateConfiguration::InferFromSettings( } // Running from kernel divided into several pieces (for sharing). - // TODO(fuchsia): Use async blobfs API once it becomes available. - if (asset_manager) { + { std::unique_ptr kernel_list = asset_manager->GetAsMapping(settings.application_kernel_list_asset); if (kernel_list) { - const char* kernel_list_str = - reinterpret_cast(kernel_list->GetMapping()); - size_t kernel_list_size = kernel_list->GetSize(); - - std::vector> kernel_pieces; - - size_t piece_path_start = 0; - while (piece_path_start < kernel_list_size) { - size_t piece_path_end = piece_path_start; - while ((piece_path_end < kernel_list_size) && - (kernel_list_str[piece_path_end] != '\n')) { - piece_path_end++; - } - - std::string piece_path(&kernel_list_str[piece_path_start], - piece_path_end - piece_path_start); - std::unique_ptr piece = - asset_manager->GetAsMapping(piece_path); - if (piece == nullptr) { - FML_LOG(ERROR) << "Failed to load: " << piece_path; - return nullptr; - } - - kernel_pieces.emplace_back(std::move(piece)); - - piece_path_start = piece_path_end + 1; - } - return CreateForKernelList(std::move(kernel_pieces)); + auto kernel_pieces_paths = ParseKernelListPaths(std::move(kernel_list)); + auto kernel_mappings = PrepareKernelMappings( + std::move(kernel_pieces_paths), asset_manager, io_worker); + return CreateForKernelList(std::move(kernel_mappings)); } } @@ -156,6 +193,17 @@ std::unique_ptr IsolateConfiguration::CreateForKernel( std::unique_ptr IsolateConfiguration::CreateForKernelList( std::vector> kernel_pieces) { + std::vector>> pieces; + for (auto& piece : kernel_pieces) { + std::promise> promise; + pieces.push_back(promise.get_future()); + promise.set_value(std::move(piece)); + } + return CreateForKernelList(std::move(pieces)); +} + +std::unique_ptr IsolateConfiguration::CreateForKernelList( + std::vector>> kernel_pieces) { return std::make_unique( std::move(kernel_pieces)); } diff --git a/shell/common/isolate_configuration.h b/shell/common/isolate_configuration.h index 7dd54ccf3b3b7..3983d07d61e0c 100644 --- a/shell/common/isolate_configuration.h +++ b/shell/common/isolate_configuration.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_ #define FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_ +#include #include #include @@ -22,13 +23,20 @@ class IsolateConfiguration { public: static std::unique_ptr InferFromSettings( const blink::Settings& settings, - fml::RefPtr asset_manager); + std::shared_ptr asset_manager, + fml::RefPtr io_worker); static std::unique_ptr CreateForAppSnapshot(); static std::unique_ptr CreateForKernel( std::unique_ptr kernel); + static std::unique_ptr CreateForKernelList( + std::vector>> kernel_pieces); + + // TODO(chinmaygarde): Remove this variant in favor of the one using futures + // for parallelizing asset loads. This one is in place for API compatibility + // till Android is updated. static std::unique_ptr CreateForKernelList( std::vector> kernel_pieces); diff --git a/shell/common/run_configuration.cc b/shell/common/run_configuration.cc index 57784a0e08d67..4439d8f57413d 100644 --- a/shell/common/run_configuration.cc +++ b/shell/common/run_configuration.cc @@ -13,8 +13,9 @@ namespace shell { RunConfiguration RunConfiguration::InferFromSettings( - const blink::Settings& settings) { - auto asset_manager = fml::MakeRefCounted(); + const blink::Settings& settings, + fml::RefPtr io_worker) { + auto asset_manager = std::make_shared(); asset_manager->PushBack(std::make_unique( fml::Duplicate(settings.assets_dir))); @@ -23,18 +24,19 @@ RunConfiguration RunConfiguration::InferFromSettings( std::make_unique(fml::OpenDirectory( settings.assets_path.c_str(), false, fml::FilePermission::kRead))); - return {IsolateConfiguration::InferFromSettings(settings, asset_manager), + return {IsolateConfiguration::InferFromSettings(settings, asset_manager, + io_worker), asset_manager}; } RunConfiguration::RunConfiguration( std::unique_ptr configuration) : RunConfiguration(std::move(configuration), - fml::MakeRefCounted()) {} + std::make_shared()) {} RunConfiguration::RunConfiguration( std::unique_ptr configuration, - fml::RefPtr asset_manager) + std::shared_ptr asset_manager) : isolate_configuration_(std::move(configuration)), asset_manager_(std::move(asset_manager)) {} @@ -66,7 +68,7 @@ void RunConfiguration::SetEntrypointAndLibrary(std::string entrypoint, entrypoint_library_ = std::move(library); } -fml::RefPtr RunConfiguration::GetAssetManager() const { +std::shared_ptr RunConfiguration::GetAssetManager() const { return asset_manager_; } diff --git a/shell/common/run_configuration.h b/shell/common/run_configuration.h index bc3b78f52e157..7baeb30b9a55f 100644 --- a/shell/common/run_configuration.h +++ b/shell/common/run_configuration.h @@ -20,12 +20,14 @@ namespace shell { class RunConfiguration { public: - static RunConfiguration InferFromSettings(const blink::Settings& settings); + static RunConfiguration InferFromSettings( + const blink::Settings& settings, + fml::RefPtr io_worker = nullptr); RunConfiguration(std::unique_ptr configuration); RunConfiguration(std::unique_ptr configuration, - fml::RefPtr asset_manager); + std::shared_ptr asset_manager); RunConfiguration(RunConfiguration&&); @@ -39,7 +41,7 @@ class RunConfiguration { void SetEntrypointAndLibrary(std::string entrypoint, std::string library); - fml::RefPtr GetAssetManager() const; + std::shared_ptr GetAssetManager() const; const std::string& GetEntrypoint() const; @@ -49,7 +51,7 @@ class RunConfiguration { private: std::unique_ptr isolate_configuration_; - fml::RefPtr asset_manager_; + std::shared_ptr asset_manager_; std::string entrypoint_ = "main"; std::string entrypoint_library_ = ""; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1139be8531c94..178f81488a184 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -949,7 +949,7 @@ bool Shell::OnServiceProtocolSetAssetBundlePath( auto& allocator = response.GetAllocator(); response.SetObject(); - auto asset_manager = fml::MakeRefCounted(); + auto asset_manager = std::make_shared(); asset_manager->PushFront(std::make_unique( fml::OpenDirectory(params.at("assetDirectory").ToString().c_str(), false, diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index e84e68737b281..eee6900cb2b11 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -241,7 +241,7 @@ static void RunBundleAndSnapshotFromLibrary(JNIEnv* env, jstring jEntrypoint, jstring jLibraryUrl, jobject jAssetManager) { - auto asset_manager = fml::MakeRefCounted(); + auto asset_manager = std::make_shared(); const auto bundlepath = fml::jni::JavaStringToString(env, jbundlepath); if (bundlepath.size() > 0) { diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 207e35301ff5d..f8c72fad41845 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -145,7 +145,7 @@ int RunTester(const blink::Settings& settings, bool run_forever) { return EXIT_FAILURE; } - auto asset_manager = fml::MakeRefCounted(); + auto asset_manager = std::make_shared(); asset_manager->PushBack(std::make_unique( fml::Duplicate(settings.assets_dir))); asset_manager->PushBack(