Skip to content

Commit

Permalink
Replace AssetResolver GetAsBuffer with GetAsMapping. (flutter#5546)
Browse files Browse the repository at this point in the history
Toward no-copy loading of kernel.
  • Loading branch information
rmacnak-google authored Jun 19, 2018
1 parent a7fda2b commit fe9dd64
Show file tree
Hide file tree
Showing 26 changed files with 165 additions and 134 deletions.
15 changes: 8 additions & 7 deletions assets/asset_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,20 @@ void AssetManager::PushBack(std::unique_ptr<AssetResolver> resolver) {
}

// |blink::AssetResolver|
bool AssetManager::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const {
std::unique_ptr<fml::Mapping> AssetManager::GetAsMapping(
const std::string& asset_name) const {
if (asset_name.size() == 0) {
return false;
return nullptr;
}
TRACE_EVENT0("flutter", "AssetManager::GetAsBuffer");
TRACE_EVENT0("flutter", "AssetManager::GetAsMapping");
for (const auto& resolver : resolvers_) {
if (resolver->GetAsBuffer(asset_name, data)) {
return true;
auto mapping = resolver->GetAsMapping(asset_name);
if (mapping != nullptr) {
return mapping;
}
}
FML_DLOG(WARNING) << "Could not find asset: " << asset_name;
return false;
return nullptr;
}

// |blink::AssetResolver|
Expand Down
4 changes: 2 additions & 2 deletions assets/asset_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class AssetManager final : public AssetResolver,
bool IsValid() const override;

// |blink::AssetResolver|
bool GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const override;
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

private:
std::deque<std::unique_ptr<AssetResolver>> resolvers_;
Expand Down
6 changes: 4 additions & 2 deletions assets/asset_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <vector>

#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"

namespace blink {

Expand All @@ -20,8 +21,9 @@ class AssetResolver {

virtual bool IsValid() const = 0;

virtual bool GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const = 0;
FML_WARN_UNUSED_RESULT
virtual std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const = 0;

private:
FML_DISALLOW_COPY_AND_ASSIGN(AssetResolver);
Expand Down
20 changes: 7 additions & 13 deletions assets/directory_asset_bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,23 @@ bool DirectoryAssetBundle::IsValid() const {
}

// |blink::AssetResolver|
bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const {
if (data == nullptr) {
return false;
}

std::unique_ptr<fml::Mapping> DirectoryAssetBundle::GetAsMapping(
const std::string& asset_name) const {
if (!is_valid_) {
FML_DLOG(WARNING) << "Asset bundle was not valid.";
return false;
return nullptr;
}

fml::FileMapping mapping(
auto mapping = std::make_unique<fml::FileMapping>(
fml::OpenFile(descriptor_, asset_name.c_str(), fml::OpenPermission::kRead,
false /* directory */),
false /* executable */);

if (mapping.GetMapping() == nullptr) {
return false;
if (mapping->GetMapping() == nullptr) {
return nullptr;
}

data->resize(mapping.GetSize());
memmove(data->data(), mapping.GetMapping(), mapping.GetSize());
return true;
return mapping;
}

} // namespace blink
4 changes: 2 additions & 2 deletions assets/directory_asset_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class DirectoryAssetBundle : public AssetResolver {
bool IsValid() const override;

// |blink::AssetResolver|
bool GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const override;
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

FML_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle);
};
Expand Down
24 changes: 12 additions & 12 deletions assets/zip_asset_store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,47 +35,47 @@ bool ZipAssetStore::IsValid() const {
}

// |blink::AssetResolver|
bool ZipAssetStore::GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const {
TRACE_EVENT0("flutter", "ZipAssetStore::GetAsBuffer");
std::unique_ptr<fml::Mapping> ZipAssetStore::GetAsMapping(
const std::string& asset_name) const {
TRACE_EVENT0("flutter", "ZipAssetStore::GetAsMapping");
auto found = stat_cache_.find(asset_name);

if (found == stat_cache_.end()) {
return false;
return nullptr;
}

auto unzipper = CreateUnzipper();

if (!unzipper.is_valid()) {
return false;
return nullptr;
}

int result = UNZ_OK;

result = unzGoToFilePos(unzipper.get(), &(found->second.file_pos));
if (result != UNZ_OK) {
FXL_LOG(WARNING) << "unzGetCurrentFileInfo failed, error=" << result;
return false;
return nullptr;
}

result = unzOpenCurrentFile(unzipper.get());
if (result != UNZ_OK) {
FXL_LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
return false;
return nullptr;
}

data->resize(found->second.uncompressed_size);
std::vector<uint8_t> data(found->second.uncompressed_size);
int total_read = 0;
while (total_read < static_cast<int>(data->size())) {
while (total_read < static_cast<int>(data.size())) {
int bytes_read = unzReadCurrentFile(
unzipper.get(), data->data() + total_read, data->size() - total_read);
unzipper.get(), data.data() + total_read, data.size() - total_read);
if (bytes_read <= 0) {
return false;
return nullptr;
}
total_read += bytes_read;
}

return true;
return std::make_unique<fml::DataMapping>(std::move(data));
}

void ZipAssetStore::BuildStatCache() {
Expand Down
4 changes: 2 additions & 2 deletions assets/zip_asset_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class ZipAssetStore final : public AssetResolver {
bool IsValid() const override;

// |blink::AssetResolver|
bool GetAsBuffer(const std::string& asset_name,
std::vector<uint8_t>* data) const override;
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

void BuildStatCache();

Expand Down
19 changes: 10 additions & 9 deletions lib/ui/text/asset_manager_font_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ namespace blink {

namespace {

void VectorReleaseProc(const void* ptr, void* context) {
delete reinterpret_cast<std::vector<uint8_t>*>(context);
void MappingReleaseProc(const void* ptr, void* context) {
delete reinterpret_cast<fml::Mapping*>(context);
}

} // anonymous namespace
Expand Down Expand Up @@ -90,15 +90,16 @@ SkTypeface* AssetManagerFontStyleSet::createTypeface(int i) {

TypefaceAsset& asset = assets_[index];
if (!asset.typeface) {
std::unique_ptr<std::vector<uint8_t>> asset_buf =
std::make_unique<std::vector<uint8_t>>();
if (!asset_manager_->GetAsBuffer(asset.asset, asset_buf.get()))
std::unique_ptr<fml::Mapping> asset_mapping =
asset_manager_->GetAsMapping(asset.asset);
if (asset_mapping == nullptr) {
return nullptr;
}

std::vector<uint8_t>* asset_buf_ptr = asset_buf.release();
sk_sp<SkData> asset_data =
SkData::MakeWithProc(asset_buf_ptr->data(), asset_buf_ptr->size(),
VectorReleaseProc, asset_buf_ptr);
fml::Mapping* asset_mapping_ptr = asset_mapping.release();
sk_sp<SkData> asset_data = SkData::MakeWithProc(
asset_mapping_ptr->GetMapping(), asset_mapping_ptr->GetSize(),
MappingReleaseProc, asset_mapping_ptr);
std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(asset_data);

// Ownership of the stream is transferred.
Expand Down
19 changes: 9 additions & 10 deletions lib/ui/text/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,18 @@ std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
}

void FontCollection::RegisterFonts(fml::RefPtr<AssetManager> asset_manager) {
std::vector<uint8_t> manifest_data;
if (!asset_manager->GetAsBuffer("FontManifest.json", &manifest_data)) {
std::unique_ptr<fml::Mapping> manifest_mapping =
asset_manager->GetAsMapping("FontManifest.json");
if (manifest_mapping == nullptr) {
FXL_DLOG(WARNING) << "Could not find the font manifest in the asset store.";
return;
}

rapidjson::Document document;
static_assert(sizeof(decltype(manifest_data)::value_type) ==
sizeof(decltype(document)::Ch),
"");
document.Parse(
reinterpret_cast<decltype(document)::Ch*>(manifest_data.data()),
manifest_data.size());
static_assert(sizeof(decltype(document)::Ch) == sizeof(uint8_t), "");
document.Parse(reinterpret_cast<const decltype(document)::Ch*>(
manifest_mapping->GetMapping()),
manifest_mapping->GetSize());

if (document.HasParseError()) {
FXL_DLOG(WARNING) << "Error parsing the font manifest in the asset store.";
Expand Down Expand Up @@ -82,8 +81,8 @@ void FontCollection::RegisterFonts(fml::RefPtr<AssetManager> asset_manager) {
}

// TODO: Handle weights and styles.
font_provider->RegisterAsset(
family_name->value.GetString(), font_asset->value.GetString());
font_provider->RegisterAsset(family_name->value.GetString(),
font_asset->value.GetString());
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/ui/window/platform_message_response.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <vector>

#include "flutter/fml/mapping.h"
#include "lib/fxl/memory/ref_counted.h"
#include "lib/fxl/memory/ref_ptr.h"

Expand All @@ -18,7 +19,7 @@ class PlatformMessageResponse

public:
// Callable on any thread.
virtual void Complete(std::vector<uint8_t> data) = 0;
virtual void Complete(std::unique_ptr<fml::Mapping> data) = 0;
virtual void CompleteEmpty() = 0;

bool is_complete() const { return is_complete_; }
Expand Down
8 changes: 7 additions & 1 deletion lib/ui/window/platform_message_response_dart.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ Dart_Handle WrapByteData(std::vector<uint8_t> data) {
}
}

Dart_Handle WrapByteData(std::unique_ptr<fml::Mapping> mapping) {
std::vector<uint8_t> data(mapping->GetSize());
memcpy(data.data(), mapping->GetMapping(), mapping->GetSize());
return WrapByteData(std::move(data));
}

} // anonymous namespace

PlatformMessageResponseDart::PlatformMessageResponseDart(
Expand All @@ -56,7 +62,7 @@ PlatformMessageResponseDart::~PlatformMessageResponseDart() {
}
}

void PlatformMessageResponseDart::Complete(std::vector<uint8_t> data) {
void PlatformMessageResponseDart::Complete(std::unique_ptr<fml::Mapping> data) {
if (callback_.is_empty())
return;
FXL_DCHECK(!is_complete_);
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/window/platform_message_response_dart.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PlatformMessageResponseDart : public PlatformMessageResponse {

public:
// Callable on any thread.
void Complete(std::vector<uint8_t> data) override;
void Complete(std::unique_ptr<fml::Mapping> data) override;
void CompleteEmpty() override;

protected:
Expand Down
3 changes: 2 additions & 1 deletion lib/ui/window/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void RespondToPlatformMessage(Dart_Handle window,
UIDartState::Current()->window()->CompletePlatformMessageEmptyResponse(
response_id);
} else {
// TODO(engine): Avoid this copy.
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());
UIDartState::Current()->window()->CompletePlatformMessageResponse(
response_id,
Expand Down Expand Up @@ -288,7 +289,7 @@ void Window::CompletePlatformMessageResponse(int response_id,
return;
auto response = std::move(it->second);
pending_responses_.erase(it);
response->Complete(std::move(data));
response->Complete(std::make_unique<fml::DataMapping>(std::move(data)));
}

void Window::RegisterNatives(tonic::DartLibraryNatives* natives) {
Expand Down
14 changes: 9 additions & 5 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,16 @@ void Engine::HandleAssetPlatformMessage(
std::string asset_name(reinterpret_cast<const char*>(data.data()),
data.size());

std::vector<uint8_t> asset_data;
if (asset_manager_ && asset_manager_->GetAsBuffer(asset_name, &asset_data)) {
response->Complete(std::move(asset_data));
} else {
response->CompleteEmpty();
if (asset_manager_) {
std::unique_ptr<fml::Mapping> asset_mapping =
asset_manager_->GetAsMapping(asset_name);
if (asset_mapping) {
response->Complete(std::move(asset_mapping));
return;
}
}

response->CompleteEmpty();
}

} // namespace shell
Loading

0 comments on commit fe9dd64

Please sign in to comment.