Skip to content

Commit

Permalink
Realize kernel asset mappings on a worker thread if one is available. (
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored Oct 24, 2018
1 parent d3874a9 commit e1e6093
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 68 deletions.
13 changes: 5 additions & 8 deletions assets/asset_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@

namespace blink {

class AssetManager final : public AssetResolver,
public fml::RefCountedThreadSafe<AssetManager> {
class AssetManager final : public AssetResolver {
public:
AssetManager();

~AssetManager();

void PushFront(std::unique_ptr<AssetResolver> resolver);

void PushBack(std::unique_ptr<AssetResolver> resolver);
Expand All @@ -32,13 +35,7 @@ class AssetManager final : public AssetResolver,
private:
std::deque<std::unique_ptr<AssetResolver>> resolvers_;

AssetManager();

~AssetManager();

FML_DISALLOW_COPY_AND_ASSIGN(AssetManager);
FML_FRIEND_MAKE_REF_COUNTED(AssetManager);
FML_FRIEND_REF_COUNTED_THREAD_SAFE(AssetManager);
};

} // namespace blink
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/text/asset_manager_font_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void MappingReleaseProc(const void* ptr, void* context) {
} // anonymous namespace

AssetManagerFontProvider::AssetManagerFontProvider(
fml::RefPtr<blink::AssetManager> asset_manager)
std::shared_ptr<blink::AssetManager> asset_manager)
: asset_manager_(asset_manager) {}

AssetManagerFontProvider::~AssetManagerFontProvider() = default;
Expand Down Expand Up @@ -65,7 +65,7 @@ void AssetManagerFontProvider::RegisterAsset(std::string family_name,
}

AssetManagerFontStyleSet::AssetManagerFontStyleSet(
fml::RefPtr<blink::AssetManager> asset_manager)
std::shared_ptr<blink::AssetManager> asset_manager)
: asset_manager_(asset_manager) {}

AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;
Expand Down
10 changes: 6 additions & 4 deletions lib/ui/text/asset_manager_font_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <memory>
#include <string>
#include <unordered_map>
#include <vector>
Expand All @@ -18,7 +19,7 @@ namespace blink {

class AssetManagerFontStyleSet : public SkFontStyleSet {
public:
AssetManagerFontStyleSet(fml::RefPtr<blink::AssetManager> asset_manager);
AssetManagerFontStyleSet(std::shared_ptr<blink::AssetManager> asset_manager);

~AssetManagerFontStyleSet() override;

Expand All @@ -37,7 +38,7 @@ class AssetManagerFontStyleSet : public SkFontStyleSet {
SkTypeface* matchStyle(const SkFontStyle& pattern) override;

private:
fml::RefPtr<blink::AssetManager> asset_manager_;
std::shared_ptr<blink::AssetManager> asset_manager_;

struct TypefaceAsset {
TypefaceAsset(std::string a) : asset(std::move(a)) {}
Expand All @@ -51,7 +52,8 @@ class AssetManagerFontStyleSet : public SkFontStyleSet {

class AssetManagerFontProvider : public txt::FontAssetProvider {
public:
AssetManagerFontProvider(fml::RefPtr<blink::AssetManager> asset_manager);
AssetManagerFontProvider(std::shared_ptr<blink::AssetManager> asset_manager);

~AssetManagerFontProvider() override;

void RegisterAsset(std::string family_name, std::string asset);
Expand All @@ -66,7 +68,7 @@ class AssetManagerFontProvider : public txt::FontAssetProvider {
SkFontStyleSet* MatchFamily(const std::string& family_name) override;

private:
fml::RefPtr<AssetManager> asset_manager_;
std::shared_ptr<AssetManager> asset_manager_;
std::unordered_map<std::string, AssetManagerFontStyleSet>
registered_families_;
std::vector<std::string> family_names_;
Expand Down
3 changes: 2 additions & 1 deletion lib/ui/text/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}

void FontCollection::RegisterFonts(fml::RefPtr<AssetManager> asset_manager) {
void FontCollection::RegisterFonts(
std::shared_ptr<AssetManager> asset_manager) {
std::unique_ptr<fml::Mapping> manifest_mapping =
asset_manager->GetAsMapping("FontManifest.json");
if (manifest_mapping == nullptr) {
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/text/font_collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FontCollection {

std::shared_ptr<txt::FontCollection> GetFontCollection() const;

void RegisterFonts(fml::RefPtr<AssetManager> asset_manager);
void RegisterFonts(std::shared_ptr<AssetManager> asset_manager);

void RegisterTestFonts();

Expand Down
2 changes: 1 addition & 1 deletion shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fml::WeakPtr<Engine> Engine::GetWeakPtr() const {
}

bool Engine::UpdateAssetManager(
fml::RefPtr<blink::AssetManager> new_asset_manager) {
std::shared_ptr<blink::AssetManager> new_asset_manager) {
if (asset_manager_ == new_asset_manager) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions shell/common/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Engine final : public blink::RuntimeDelegate {
FML_WARN_UNUSED_RESULT
bool Restart(RunConfiguration configuration);

bool UpdateAssetManager(fml::RefPtr<blink::AssetManager> asset_manager);
bool UpdateAssetManager(std::shared_ptr<blink::AssetManager> asset_manager);

void BeginFrame(fml::TimePoint frame_time);

Expand Down Expand Up @@ -121,7 +121,7 @@ class Engine final : public blink::RuntimeDelegate {
std::unique_ptr<blink::RuntimeController> runtime_controller_;
std::string initial_route_;
blink::ViewportMetrics viewport_metrics_;
fml::RefPtr<blink::AssetManager> asset_manager_;
std::shared_ptr<blink::AssetManager> asset_manager_;
bool activity_running_;
bool have_surface_;
blink::FontCollection font_collection_;
Expand Down
118 changes: 83 additions & 35 deletions shell/common/isolate_configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -61,7 +62,7 @@ class KernelIsolateConfiguration : public IsolateConfiguration {
class KernelListIsolateConfiguration final : public IsolateConfiguration {
public:
KernelListIsolateConfiguration(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces)
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces)
: kernel_pieces_(std::move(kernel_pieces)) {}

// |shell::IsolateConfiguration|
Expand All @@ -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;
}
Expand All @@ -82,21 +84,81 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration {
}

private:
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces_;
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces_;

FML_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration);
};

static std::vector<std::string> ParseKernelListPaths(
std::unique_ptr<fml::Mapping> kernel_list) {
FML_DCHECK(kernel_list);

std::vector<std::string> kernel_pieces_paths;

const char* kernel_list_str =
reinterpret_cast<const char*>(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<std::future<std::unique_ptr<fml::Mapping>>>
PrepareKernelMappings(std::vector<std::string> kernel_pieces_paths,
std::shared_ptr<blink::AssetManager> asset_manager,
fml::RefPtr<fml::TaskRunner> io_worker) {
FML_DCHECK(asset_manager);
std::vector<std::future<std::unique_ptr<fml::Mapping>>> fetch_futures;

for (const auto& kernel_pieces_path : kernel_pieces_paths) {
std::promise<std::unique_ptr<fml::Mapping>> 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> IsolateConfiguration::InferFromSettings(
const blink::Settings& settings,
fml::RefPtr<blink::AssetManager> asset_manager) {
std::shared_ptr<blink::AssetManager> asset_manager,
fml::RefPtr<fml::TaskRunner> 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<fml::Mapping> kernel =
asset_manager->GetAsMapping(settings.application_kernel_asset);
if (kernel) {
Expand All @@ -105,39 +167,14 @@ std::unique_ptr<IsolateConfiguration> 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<fml::Mapping> kernel_list =
asset_manager->GetAsMapping(settings.application_kernel_list_asset);
if (kernel_list) {
const char* kernel_list_str =
reinterpret_cast<const char*>(kernel_list->GetMapping());
size_t kernel_list_size = kernel_list->GetSize();

std::vector<std::unique_ptr<fml::Mapping>> 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<fml::Mapping> 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));
}
}

Expand All @@ -156,6 +193,17 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernel(

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces) {
std::vector<std::future<std::unique_ptr<fml::Mapping>>> pieces;
for (auto& piece : kernel_pieces) {
std::promise<std::unique_ptr<fml::Mapping>> promise;
pieces.push_back(promise.get_future());
promise.set_value(std::move(piece));
}
return CreateForKernelList(std::move(pieces));
}

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces) {
return std::make_unique<KernelListIsolateConfiguration>(
std::move(kernel_pieces));
}
Expand Down
10 changes: 9 additions & 1 deletion shell/common/isolate_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_
#define FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_

#include <future>
#include <memory>
#include <string>

Expand All @@ -22,13 +23,20 @@ class IsolateConfiguration {
public:
static std::unique_ptr<IsolateConfiguration> InferFromSettings(
const blink::Settings& settings,
fml::RefPtr<blink::AssetManager> asset_manager);
std::shared_ptr<blink::AssetManager> asset_manager,
fml::RefPtr<fml::TaskRunner> io_worker);

static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot();

static std::unique_ptr<IsolateConfiguration> CreateForKernel(
std::unique_ptr<fml::Mapping> kernel);

static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
std::vector<std::future<std::unique_ptr<fml::Mapping>>> 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<IsolateConfiguration> CreateForKernelList(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces);

Expand Down
14 changes: 8 additions & 6 deletions shell/common/run_configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
namespace shell {

RunConfiguration RunConfiguration::InferFromSettings(
const blink::Settings& settings) {
auto asset_manager = fml::MakeRefCounted<blink::AssetManager>();
const blink::Settings& settings,
fml::RefPtr<fml::TaskRunner> io_worker) {
auto asset_manager = std::make_shared<blink::AssetManager>();

asset_manager->PushBack(std::make_unique<blink::DirectoryAssetBundle>(
fml::Duplicate(settings.assets_dir)));
Expand All @@ -23,18 +24,19 @@ RunConfiguration RunConfiguration::InferFromSettings(
std::make_unique<blink::DirectoryAssetBundle>(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<IsolateConfiguration> configuration)
: RunConfiguration(std::move(configuration),
fml::MakeRefCounted<blink::AssetManager>()) {}
std::make_shared<blink::AssetManager>()) {}

RunConfiguration::RunConfiguration(
std::unique_ptr<IsolateConfiguration> configuration,
fml::RefPtr<blink::AssetManager> asset_manager)
std::shared_ptr<blink::AssetManager> asset_manager)
: isolate_configuration_(std::move(configuration)),
asset_manager_(std::move(asset_manager)) {}

Expand Down Expand Up @@ -66,7 +68,7 @@ void RunConfiguration::SetEntrypointAndLibrary(std::string entrypoint,
entrypoint_library_ = std::move(library);
}

fml::RefPtr<blink::AssetManager> RunConfiguration::GetAssetManager() const {
std::shared_ptr<blink::AssetManager> RunConfiguration::GetAssetManager() const {
return asset_manager_;
}

Expand Down
Loading

0 comments on commit e1e6093

Please sign in to comment.