From 78941c96db44f719e6ac43acd22204ef986aff69 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 14 Sep 2020 08:20:33 -0700 Subject: [PATCH 1/6] [dart:ui] add an explicit API for loading assets --- lib/ui/BUILD.gn | 2 + lib/ui/assets.cc | 59 ++++++++++++++++++++++++++ lib/ui/assets.dart | 23 ++++++++++ lib/ui/assets.h | 27 ++++++++++++ lib/ui/dart_ui.cc | 2 + lib/ui/ui.dart | 1 + lib/ui/window/platform_configuration.h | 3 ++ lib/web_ui/lib/src/ui/assets.dart | 17 ++++++++ lib/web_ui/lib/ui.dart | 1 + runtime/runtime_controller.cc | 6 +++ runtime/runtime_controller.h | 4 ++ runtime/runtime_delegate.h | 3 ++ shell/common/engine.cc | 4 ++ shell/common/engine.h | 3 ++ shell/common/engine_unittests.cc | 1 + testing/dart/assets_test.dart | 18 ++++++++ 16 files changed, 174 insertions(+) create mode 100644 lib/ui/assets.cc create mode 100644 lib/ui/assets.dart create mode 100644 lib/ui/assets.h create mode 100644 lib/web_ui/lib/src/ui/assets.dart create mode 100644 testing/dart/assets_test.dart diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index decca25d81f90..dd18d861800a6 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -8,6 +8,8 @@ import("//flutter/testing/testing.gni") source_set("ui") { sources = [ + "assets.cc", + "assets.h", "compositing/scene.cc", "compositing/scene.h", "compositing/scene_builder.cc", diff --git a/lib/ui/assets.cc b/lib/ui/assets.cc new file mode 100644 index 0000000000000..88c27fe035c85 --- /dev/null +++ b/lib/ui/assets.cc @@ -0,0 +1,59 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/lib/ui/assets.h" + +#include "flutter/lib/ui/window/platform_configuration.h" +#include "flutter/assets/asset_manager.h" +#include "flutter/lib/ui/ui_dart_state.h" +#include "third_party/tonic/dart_binding_macros.h" +#include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/logging/dart_invoke.h" +#include "third_party/tonic/typed_data/typed_list.h" +#include "third_party/tonic/typed_data/dart_byte_data.h" +#include "third_party/tonic/dart_library_natives.h" + +using tonic::DartInvoke; +using tonic::DartPersistentValue; +using tonic::ToDart; + +namespace flutter { + +void Assets::loadAssetBytes(Dart_NativeArguments args) { + UIDartState::ThrowIfUIOperationsProhibited(); + Dart_Handle callback = Dart_GetNativeArgument(args, 1); + if (!Dart_IsClosure(callback)) { + Dart_SetReturnValue(args, tonic::ToDart("Callback must be a function")); + return; + } + Dart_Handle asset_name_handle = Dart_GetNativeArgument(args, 0); + uint8_t* chars = nullptr; + intptr_t asset_length = 0; + Dart_Handle result = Dart_StringToUTF8(asset_name_handle, &chars, &asset_length); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + return; + } + std::string asset_name = std::string{reinterpret_cast(chars), + static_cast(asset_length)}; + + std::shared_ptr asset_manager = UIDartState::Current() + ->platform_configuration() + ->client() + ->GetAssetManager(); + std::unique_ptr data = + asset_manager->GetAsMapping(asset_name); + + Dart_Handle byte_buffer = + tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); + tonic::DartInvoke(callback, {ToDart(byte_buffer)}); +} + +void Assets::RegisterNatives(tonic::DartLibraryNatives* natives) { + natives->Register({ + {"loadAssetBytes", loadAssetBytes, 2, true}, + }); +} + +} // namespace flutter diff --git a/lib/ui/assets.dart b/lib/ui/assets.dart new file mode 100644 index 0000000000000..eded711bd558b --- /dev/null +++ b/lib/ui/assets.dart @@ -0,0 +1,23 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @dart = 2.10 + +part of dart.ui; + +/// Load the asset bytes specified by [assetKey]. +/// +/// The [assetKey] is generally the filepath of the asset which is bundled +/// into the flutter application. This API is not supported on the Web. +/// +/// If the [assetKey] does not correspond to a real asset, returns `null`. +ByteData? loadAsset(String assetKey) { + ByteData? result; + _loadAsset(assetKey, (ByteData? byteData) { + result = byteData; + }); + return result; +} + +void _loadAsset(String asseyKey, void Function(ByteData?) onData) native 'loadAssetBytes'; diff --git a/lib/ui/assets.h b/lib/ui/assets.h new file mode 100644 index 0000000000000..e576dc000b7c8 --- /dev/null +++ b/lib/ui/assets.h @@ -0,0 +1,27 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_LIB_UI_ASSETS_H_ +#define FLUTTER_LIB_UI_ASSETS_H_ + +#include "flutter/lib/ui/window/platform_configuration.h" +#include "flutter/assets/asset_manager.h" +#include "flutter/lib/ui/ui_dart_state.h" +#include "third_party/tonic/dart_binding_macros.h" +#include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/logging/dart_invoke.h" +#include "third_party/tonic/typed_data/typed_list.h" +#include "third_party/tonic/typed_data/dart_byte_data.h" +#include "third_party/tonic/dart_library_natives.h" + +namespace flutter { + +class Assets { + public: + static void loadAssetBytes(Dart_NativeArguments args); + + static void RegisterNatives(tonic::DartLibraryNatives* natives); +}; +} // flutter +#endif // FLUTTER_LIB_UI_ASSETS_H_ diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index f9f89d6f22d67..dd232d2de1852 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -33,6 +33,7 @@ #include "flutter/lib/ui/window/platform_configuration.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/logging/dart_error.h" +#include "flutter/lib/ui/assets.h" #if defined(LEGACY_FUCHSIA_EMBEDDER) #include "flutter/lib/ui/compositing/scene_host.h" // nogncheck @@ -86,6 +87,7 @@ void DartUI::InitForGlobal() { SemanticsUpdateBuilder::RegisterNatives(g_natives); Vertices::RegisterNatives(g_natives); PlatformConfiguration::RegisterNatives(g_natives); + Assets::RegisterNatives(g_natives); #if defined(LEGACY_FUCHSIA_EMBEDDER) SceneHost::RegisterNatives(g_natives); #endif diff --git a/lib/ui/ui.dart b/lib/ui/ui.dart index fe0e4fa16bcd6..64a7685789a4e 100644 --- a/lib/ui/ui.dart +++ b/lib/ui/ui.dart @@ -24,6 +24,7 @@ import 'dart:nativewrappers'; import 'dart:typed_data'; part 'annotations.dart'; +part 'assets.dart'; part 'channel_buffers.dart'; part 'compositing.dart'; part 'geometry.dart'; diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 4652c7c5dcdbb..72b5c01ece41c 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -11,6 +11,7 @@ #include #include +#include "flutter/assets/asset_manager.h" #include "flutter/fml/time/time_point.h" #include "flutter/lib/ui/semantics/semantics_update.h" #include "flutter/lib/ui/window/platform_message.h" @@ -111,6 +112,8 @@ class PlatformConfigurationClient { /// creation. virtual FontCollection& GetFontCollection() = 0; + virtual std::shared_ptr GetAssetManager() = 0; + //-------------------------------------------------------------------------- /// @brief Notifies this client of the name of the root isolate and its /// port when that isolate is launched, restarted (in the diff --git a/lib/web_ui/lib/src/ui/assets.dart b/lib/web_ui/lib/src/ui/assets.dart new file mode 100644 index 0000000000000..efc138a4639ef --- /dev/null +++ b/lib/web_ui/lib/src/ui/assets.dart @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @dart = 2.10 +part of ui; + +/// Load the asset bytes specified by [assetKey]. +/// +/// The [assetKey] is generally the filepath of the asset which is bundled +/// into the flutter application. This API is not supported on the +/// Web. +/// +/// If the [assetKey] does not correspond to a real asset, returns `null`. +ByteData? loadAsset(String assetKey) { + return null; +} diff --git a/lib/web_ui/lib/ui.dart b/lib/web_ui/lib/ui.dart index 13d5ee2813b20..e1af78fff2d77 100644 --- a/lib/web_ui/lib/ui.dart +++ b/lib/web_ui/lib/ui.dart @@ -35,6 +35,7 @@ part 'src/ui/test_embedding.dart'; part 'src/ui/text.dart'; part 'src/ui/tile_mode.dart'; part 'src/ui/window.dart'; +part 'src/ui/assets.dart'; /// Provides a compile time constant to customize flutter framework and other /// users of ui engine for web runtime. diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index f66cfed778660..a0a7b589236d7 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "flutter/assets/asset_manager.h" #include "flutter/runtime/runtime_controller.h" #include "flutter/fml/message_loop.h" @@ -328,6 +329,11 @@ FontCollection& RuntimeController::GetFontCollection() { return client_.GetFontCollection(); } +// |PlatfromConfigurationClient| +std::shared_ptr RuntimeController::GetAssetManager() { + return client_.GetAssetManager(); +} + // |PlatformConfigurationClient| void RuntimeController::UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port) { diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 18adbc2c1d720..4216eab0bea3c 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -8,6 +8,7 @@ #include #include +#include "flutter/assets/asset_manager.h" #include "flutter/common/task_runners.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/fml/macros.h" @@ -499,6 +500,9 @@ class RuntimeController : public PlatformConfigurationClient { // |PlatformConfigurationClient| FontCollection& GetFontCollection() override; + // |PlatformConfigurationClient| + std::shared_ptr GetAssetManager() override; + // |PlatformConfigurationClient| void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port) override; diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 20059827b8150..38d174fd0a961 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -8,6 +8,7 @@ #include #include +#include "flutter/assets/asset_manager.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/lib/ui/semantics/custom_accessibility_action.h" #include "flutter/lib/ui/semantics/semantics_node.h" @@ -32,6 +33,8 @@ class RuntimeDelegate { virtual FontCollection& GetFontCollection() = 0; + virtual std::shared_ptr GetAssetManager() = 0; + virtual void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port) = 0; diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 315780f23346b..dcc99750c262e 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -513,6 +513,10 @@ FontCollection& Engine::GetFontCollection() { return font_collection_; } +std::shared_ptr Engine::GetAssetManager() { + return asset_manager_; +} + void Engine::DoDispatchPacket(std::unique_ptr packet, uint64_t trace_flow_id) { animator_->EnqueueTraceFlowId(trace_flow_id); diff --git a/shell/common/engine.h b/shell/common/engine.h index d16ae0ffed2c7..37d1c0e7fffef 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -751,6 +751,9 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { // |RuntimeDelegate| FontCollection& GetFontCollection() override; + // |RuntimeDelegate| + std::shared_ptr GetAssetManager() override; + // |PointerDataDispatcher::Delegate| void DoDispatchPacket(std::unique_ptr packet, uint64_t trace_flow_id) override; diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 54f6f00d7a8f6..7895add7f5e4a 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -46,6 +46,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { void(SemanticsNodeUpdates, CustomAccessibilityActionUpdates)); MOCK_METHOD1(HandlePlatformMessage, void(fml::RefPtr)); MOCK_METHOD0(GetFontCollection, FontCollection&()); + MOCK_METHOD0(GetAssetManager, std::shared_ptr()); MOCK_METHOD2(UpdateIsolateDescription, void(const std::string, int64_t)); MOCK_METHOD1(SetNeedsReportTimings, void(bool)); MOCK_METHOD1(ComputePlatformResolvedLocale, diff --git a/testing/dart/assets_test.dart b/testing/dart/assets_test.dart new file mode 100644 index 0000000000000..99d3661038d02 --- /dev/null +++ b/testing/dart/assets_test.dart @@ -0,0 +1,18 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @dart = 2.6 +import 'dart:ui' as ui; + +import 'package:test/test.dart'; + +void main() { + test('Loading an asset that does not exist returns null', () { + expect(ui.loadAsset('ThisDoesNotExist'), null); + }); + + test('returns the bytes of a bundled asset', () { + expect(ui.loadAsset('FontManifest.json'), isNotNull); + }); +} From 31c26c901ad1942e5df7017a9babc00bcb40c975 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 14 Sep 2020 09:10:23 -0700 Subject: [PATCH 2/6] nullcheck mapping --- lib/ui/assets.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/ui/assets.cc b/lib/ui/assets.cc index 88c27fe035c85..778c92d60263a 100644 --- a/lib/ui/assets.cc +++ b/lib/ui/assets.cc @@ -45,6 +45,10 @@ void Assets::loadAssetBytes(Dart_NativeArguments args) { std::unique_ptr data = asset_manager->GetAsMapping(asset_name); + if (data == nullptr) { + return; + } + Dart_Handle byte_buffer = tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); tonic::DartInvoke(callback, {ToDart(byte_buffer)}); From 226be4a52546161476de0d7cfba63888766342b2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 14 Sep 2020 09:40:54 -0700 Subject: [PATCH 3/6] apply formatting --- lib/ui/assets.cc | 21 ++++++++++----------- lib/ui/assets.h | 13 ++++++------- runtime/runtime_controller.cc | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/ui/assets.cc b/lib/ui/assets.cc index 778c92d60263a..31796a6b1d8a6 100644 --- a/lib/ui/assets.cc +++ b/lib/ui/assets.cc @@ -4,15 +4,14 @@ #include "flutter/lib/ui/assets.h" -#include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/assets/asset_manager.h" #include "flutter/lib/ui/ui_dart_state.h" +#include "flutter/lib/ui/window/platform_configuration.h" #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" #include "third_party/tonic/logging/dart_invoke.h" -#include "third_party/tonic/typed_data/typed_list.h" #include "third_party/tonic/typed_data/dart_byte_data.h" -#include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/typed_data/typed_list.h" using tonic::DartInvoke; using tonic::DartPersistentValue; @@ -30,7 +29,8 @@ void Assets::loadAssetBytes(Dart_NativeArguments args) { Dart_Handle asset_name_handle = Dart_GetNativeArgument(args, 0); uint8_t* chars = nullptr; intptr_t asset_length = 0; - Dart_Handle result = Dart_StringToUTF8(asset_name_handle, &chars, &asset_length); + Dart_Handle result = + Dart_StringToUTF8(asset_name_handle, &chars, &asset_length); if (Dart_IsError(result)) { Dart_PropagateError(result); return; @@ -39,18 +39,17 @@ void Assets::loadAssetBytes(Dart_NativeArguments args) { static_cast(asset_length)}; std::shared_ptr asset_manager = UIDartState::Current() - ->platform_configuration() - ->client() - ->GetAssetManager(); - std::unique_ptr data = - asset_manager->GetAsMapping(asset_name); + ->platform_configuration() + ->client() + ->GetAssetManager(); + std::unique_ptr data = asset_manager->GetAsMapping(asset_name); if (data == nullptr) { return; } Dart_Handle byte_buffer = - tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); + tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); tonic::DartInvoke(callback, {ToDart(byte_buffer)}); } @@ -60,4 +59,4 @@ void Assets::RegisterNatives(tonic::DartLibraryNatives* natives) { }); } -} // namespace flutter +} // namespace flutter diff --git a/lib/ui/assets.h b/lib/ui/assets.h index e576dc000b7c8..e183d7db0fd42 100644 --- a/lib/ui/assets.h +++ b/lib/ui/assets.h @@ -5,23 +5,22 @@ #ifndef FLUTTER_LIB_UI_ASSETS_H_ #define FLUTTER_LIB_UI_ASSETS_H_ -#include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/assets/asset_manager.h" #include "flutter/lib/ui/ui_dart_state.h" +#include "flutter/lib/ui/window/platform_configuration.h" #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" #include "third_party/tonic/logging/dart_invoke.h" -#include "third_party/tonic/typed_data/typed_list.h" #include "third_party/tonic/typed_data/dart_byte_data.h" -#include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/typed_data/typed_list.h" namespace flutter { class Assets { - public: - static void loadAssetBytes(Dart_NativeArguments args); + public: + static void loadAssetBytes(Dart_NativeArguments args); - static void RegisterNatives(tonic::DartLibraryNatives* natives); + static void RegisterNatives(tonic::DartLibraryNatives* natives); }; -} // flutter +} // namespace flutter #endif // FLUTTER_LIB_UI_ASSETS_H_ diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index a0a7b589236d7..dd95239bd562f 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/assets/asset_manager.h" #include "flutter/runtime/runtime_controller.h" +#include "flutter/assets/asset_manager.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/trace_event.h" From f284e47ea29ab1c1fe36f34ed639de669296e214 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 14 Sep 2020 10:13:07 -0700 Subject: [PATCH 4/6] more clang format fix --- lib/ui/dart_ui.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index dd232d2de1852..a4f80c52d3ead 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -5,6 +5,7 @@ #include "flutter/lib/ui/dart_ui.h" #include "flutter/fml/build_config.h" +#include "flutter/lib/ui/assets.h" #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/compositing/scene_builder.h" #include "flutter/lib/ui/dart_runtime_hooks.h" @@ -33,7 +34,6 @@ #include "flutter/lib/ui/window/platform_configuration.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/logging/dart_error.h" -#include "flutter/lib/ui/assets.h" #if defined(LEGACY_FUCHSIA_EMBEDDER) #include "flutter/lib/ui/compositing/scene_host.h" // nogncheck From 79833b7d3e75eac3cf29b7b6e6add447a9db705e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 15 Sep 2020 10:18:44 -0700 Subject: [PATCH 5/6] unsafe use of dart API --- lib/ui/assets.cc | 16 ++++++++++++++-- lib/ui/assets.dart | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/ui/assets.cc b/lib/ui/assets.cc index 31796a6b1d8a6..ad44e4a7770a9 100644 --- a/lib/ui/assets.cc +++ b/lib/ui/assets.cc @@ -19,6 +19,12 @@ using tonic::ToDart; namespace flutter { + void FinalizeSkData(void* isolate_callback_data, + Dart_WeakPersistentHandle handle, + void* peer) { + +} + void Assets::loadAssetBytes(Dart_NativeArguments args) { UIDartState::ThrowIfUIOperationsProhibited(); Dart_Handle callback = Dart_GetNativeArgument(args, 1); @@ -47,9 +53,15 @@ void Assets::loadAssetBytes(Dart_NativeArguments args) { if (data == nullptr) { return; } + const void* bytes_ = static_cast(data->GetMapping()); + void* bytes = const_cast(bytes_); + const intptr_t length = data->GetSize(); + void* peer = reinterpret_cast(data.release()); + Dart_Handle byte_buffer = Dart_NewExternalTypedDataWithFinalizer( + Dart_TypedData_kUint8, bytes, length, peer, length, FinalizeSkData); - Dart_Handle byte_buffer = - tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); + // Dart_Handle byte_buffer = + // tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); tonic::DartInvoke(callback, {ToDart(byte_buffer)}); } diff --git a/lib/ui/assets.dart b/lib/ui/assets.dart index eded711bd558b..8a29e20ecb98b 100644 --- a/lib/ui/assets.dart +++ b/lib/ui/assets.dart @@ -14,10 +14,10 @@ part of dart.ui; /// If the [assetKey] does not correspond to a real asset, returns `null`. ByteData? loadAsset(String assetKey) { ByteData? result; - _loadAsset(assetKey, (ByteData? byteData) { - result = byteData; + _loadAsset(assetKey, (Uint8List bytes) { + result = bytes.buffer.asByteData(); }); return result; } -void _loadAsset(String asseyKey, void Function(ByteData?) onData) native 'loadAssetBytes'; +void _loadAsset(String asseyKey, void Function(Uint8List) onData) native 'loadAssetBytes'; From b5892d36f754d5d852d0b6a50cb2ee9e03a3dbef Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sat, 26 Sep 2020 09:37:49 -0700 Subject: [PATCH 6/6] more draft work on immut buffer --- lib/ui/BUILD.gn | 2 - lib/ui/assets.cc | 74 ----------------------------- lib/ui/assets.dart | 23 --------- lib/ui/assets.h | 26 ---------- lib/ui/dart_ui.cc | 2 - lib/ui/painting.dart | 16 +++++++ lib/ui/painting/immutable_buffer.cc | 48 +++++++++++++++++++ lib/ui/painting/immutable_buffer.h | 9 ++++ lib/ui/ui.dart | 1 - 9 files changed, 73 insertions(+), 128 deletions(-) delete mode 100644 lib/ui/assets.cc delete mode 100644 lib/ui/assets.dart delete mode 100644 lib/ui/assets.h diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 5e7a1bacc2be1..6ce9238b2738d 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -8,8 +8,6 @@ import("//flutter/testing/testing.gni") source_set("ui") { sources = [ - "assets.cc", - "assets.h", "compositing/scene.cc", "compositing/scene.h", "compositing/scene_builder.cc", diff --git a/lib/ui/assets.cc b/lib/ui/assets.cc deleted file mode 100644 index ad44e4a7770a9..0000000000000 --- a/lib/ui/assets.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/lib/ui/assets.h" - -#include "flutter/assets/asset_manager.h" -#include "flutter/lib/ui/ui_dart_state.h" -#include "flutter/lib/ui/window/platform_configuration.h" -#include "third_party/tonic/dart_binding_macros.h" -#include "third_party/tonic/dart_library_natives.h" -#include "third_party/tonic/logging/dart_invoke.h" -#include "third_party/tonic/typed_data/dart_byte_data.h" -#include "third_party/tonic/typed_data/typed_list.h" - -using tonic::DartInvoke; -using tonic::DartPersistentValue; -using tonic::ToDart; - -namespace flutter { - - void FinalizeSkData(void* isolate_callback_data, - Dart_WeakPersistentHandle handle, - void* peer) { - -} - -void Assets::loadAssetBytes(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle callback = Dart_GetNativeArgument(args, 1); - if (!Dart_IsClosure(callback)) { - Dart_SetReturnValue(args, tonic::ToDart("Callback must be a function")); - return; - } - Dart_Handle asset_name_handle = Dart_GetNativeArgument(args, 0); - uint8_t* chars = nullptr; - intptr_t asset_length = 0; - Dart_Handle result = - Dart_StringToUTF8(asset_name_handle, &chars, &asset_length); - if (Dart_IsError(result)) { - Dart_PropagateError(result); - return; - } - std::string asset_name = std::string{reinterpret_cast(chars), - static_cast(asset_length)}; - - std::shared_ptr asset_manager = UIDartState::Current() - ->platform_configuration() - ->client() - ->GetAssetManager(); - std::unique_ptr data = asset_manager->GetAsMapping(asset_name); - - if (data == nullptr) { - return; - } - const void* bytes_ = static_cast(data->GetMapping()); - void* bytes = const_cast(bytes_); - const intptr_t length = data->GetSize(); - void* peer = reinterpret_cast(data.release()); - Dart_Handle byte_buffer = Dart_NewExternalTypedDataWithFinalizer( - Dart_TypedData_kUint8, bytes, length, peer, length, FinalizeSkData); - - // Dart_Handle byte_buffer = - // tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); - tonic::DartInvoke(callback, {ToDart(byte_buffer)}); -} - -void Assets::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({ - {"loadAssetBytes", loadAssetBytes, 2, true}, - }); -} - -} // namespace flutter diff --git a/lib/ui/assets.dart b/lib/ui/assets.dart deleted file mode 100644 index 8a29e20ecb98b..0000000000000 --- a/lib/ui/assets.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// @dart = 2.10 - -part of dart.ui; - -/// Load the asset bytes specified by [assetKey]. -/// -/// The [assetKey] is generally the filepath of the asset which is bundled -/// into the flutter application. This API is not supported on the Web. -/// -/// If the [assetKey] does not correspond to a real asset, returns `null`. -ByteData? loadAsset(String assetKey) { - ByteData? result; - _loadAsset(assetKey, (Uint8List bytes) { - result = bytes.buffer.asByteData(); - }); - return result; -} - -void _loadAsset(String asseyKey, void Function(Uint8List) onData) native 'loadAssetBytes'; diff --git a/lib/ui/assets.h b/lib/ui/assets.h deleted file mode 100644 index e183d7db0fd42..0000000000000 --- a/lib/ui/assets.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_LIB_UI_ASSETS_H_ -#define FLUTTER_LIB_UI_ASSETS_H_ - -#include "flutter/assets/asset_manager.h" -#include "flutter/lib/ui/ui_dart_state.h" -#include "flutter/lib/ui/window/platform_configuration.h" -#include "third_party/tonic/dart_binding_macros.h" -#include "third_party/tonic/dart_library_natives.h" -#include "third_party/tonic/logging/dart_invoke.h" -#include "third_party/tonic/typed_data/dart_byte_data.h" -#include "third_party/tonic/typed_data/typed_list.h" - -namespace flutter { - -class Assets { - public: - static void loadAssetBytes(Dart_NativeArguments args); - - static void RegisterNatives(tonic::DartLibraryNatives* natives); -}; -} // namespace flutter -#endif // FLUTTER_LIB_UI_ASSETS_H_ diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index ba63404434414..c22b26b17d3f6 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -5,7 +5,6 @@ #include "flutter/lib/ui/dart_ui.h" #include "flutter/fml/build_config.h" -#include "flutter/lib/ui/assets.h" #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/compositing/scene_builder.h" #include "flutter/lib/ui/dart_runtime_hooks.h" @@ -85,7 +84,6 @@ void DartUI::InitForGlobal() { SemanticsUpdateBuilder::RegisterNatives(g_natives); Vertices::RegisterNatives(g_natives); PlatformConfiguration::RegisterNatives(g_natives); - Assets::RegisterNatives(g_natives); #if defined(LEGACY_FUCHSIA_EMBEDDER) SceneHost::RegisterNatives(g_natives); #endif diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index a8ebd7a632004..0a20df33b8a76 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4960,6 +4960,22 @@ class ImmutableBuffer extends NativeFieldWrapperClass2 { } void _init(Uint8List list, _Callback callback) native 'ImmutableBuffer_init'; + /// Create a buffer from the asset with key [assetKey]. + /// + /// Returns `null` if the asset does not exist. + static ImmutableBuffer? fromAsset(String assetKey) { + final ImmutableBuffer buffer = ImmutableBuffer._(0); + bool success = false; + _fromAsset(assetKey, buffer, (void result) { + success = true; + }); + if (!success) { + return null; + } + return buffer; + } + static void _fromAsset(String assetKey, ImmutableBuffer buffer, _Callback callback) native 'ImmutableBuffer_fromAsset'; + /// The length, in bytes, of the underlying data. final int length; diff --git a/lib/ui/painting/immutable_buffer.cc b/lib/ui/painting/immutable_buffer.cc index 6491785f6eae0..60ac5404af6ce 100644 --- a/lib/ui/painting/immutable_buffer.cc +++ b/lib/ui/painting/immutable_buffer.cc @@ -10,6 +10,8 @@ #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" +#include "flutter/lib/ui/ui_dart_state.h" +#include "flutter/lib/ui/window/platform_configuration.h" #if OS_ANDROID #include @@ -30,6 +32,9 @@ ImmutableBuffer::~ImmutableBuffer() {} void ImmutableBuffer::RegisterNatives(tonic::DartLibraryNatives* natives) { natives->Register({{"ImmutableBuffer_init", ImmutableBuffer::init, 3, true}, FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); + natives->Register({{"ImmutableBuffer_fromAsset", ImmutableBuffer::fromAsset, 3, true}, + FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); + } void ImmutableBuffer::init(Dart_NativeArguments args) { @@ -53,6 +58,49 @@ size_t ImmutableBuffer::GetAllocationSize() const { return sizeof(ImmutableBuffer) + data_->size(); } +void ImmutableBuffer::fromAsset(Dart_NativeArguments args) { + UIDartState::ThrowIfUIOperationsProhibited(); + Dart_Handle callback_handle = Dart_GetNativeArgument(args, 2); + if (!Dart_IsClosure(callback_handle)) { + Dart_SetReturnValue(args, tonic::ToDart("Callback must be a function")); + return; + } + Dart_Handle asset_name_handle = Dart_GetNativeArgument(args, 0); + uint8_t* chars = nullptr; + intptr_t asset_length = 0; + Dart_Handle result = + Dart_StringToUTF8(asset_name_handle, &chars, &asset_length); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + return; + } + Dart_Handle immutable_buffer = Dart_GetNativeArgument(args, 1); + + std::string asset_name = std::string{reinterpret_cast(chars), + static_cast(asset_length)}; + + std::shared_ptr asset_manager = UIDartState::Current() + ->platform_configuration() + ->client() + ->GetAssetManager(); + std::unique_ptr data = asset_manager->GetAsMapping(asset_name); + + if (data == nullptr) { + return; + } + const void* bytes = static_cast(data->GetMapping()); + void* peer = reinterpret_cast(data.release()); + auto size = data->GetSize(); + SkData::ReleaseProc proc = [](const void* ptr, void* context) { + // TODO: what do + }; + + auto sk_data = SkData::MakeWithProc(bytes, size, proc, peer); + auto buffer = fml::MakeRefCounted(sk_data); + buffer->AssociateWithDartWrapper(immutable_buffer); + tonic::DartInvoke(callback_handle, {Dart_TypeVoid()}); +} + #if OS_ANDROID // Compressed image buffers are allocated on the UI thread but are deleted on a diff --git a/lib/ui/painting/immutable_buffer.h b/lib/ui/painting/immutable_buffer.h index ff7299881d643..a5ae9144067c9 100644 --- a/lib/ui/painting/immutable_buffer.h +++ b/lib/ui/painting/immutable_buffer.h @@ -39,6 +39,15 @@ class ImmutableBuffer : public RefCountedDartWrappable { /// when the copy has completed. static void init(Dart_NativeArguments args); + /// Create a new ImmutableData from a Dart asset key. + /// + /// The zero indexed argument is the UTF8 encoded string which corresponds to + /// the asset manager key. + /// + /// The first indexed argument is a callback that can optionally be invoked + /// with the resulting ImmutableData. + static void fromAsset(Dart_NativeArguments args); + /// The length of the data in bytes. size_t length() const { FML_DCHECK(data_); diff --git a/lib/ui/ui.dart b/lib/ui/ui.dart index 64a7685789a4e..fe0e4fa16bcd6 100644 --- a/lib/ui/ui.dart +++ b/lib/ui/ui.dart @@ -24,7 +24,6 @@ import 'dart:nativewrappers'; import 'dart:typed_data'; part 'annotations.dart'; -part 'assets.dart'; part 'channel_buffers.dart'; part 'compositing.dart'; part 'geometry.dart';