diff --git a/lib/ui/window/platform_message_response_dart.cc b/lib/ui/window/platform_message_response_dart.cc index dca1ab74f9d58..91681d074bce0 100644 --- a/lib/ui/window/platform_message_response_dart.cc +++ b/lib/ui/window/platform_message_response_dart.cc @@ -8,43 +8,12 @@ #include "flutter/common/task_runners.h" #include "flutter/fml/make_copyable.h" -#include "flutter/lib/ui/window/window.h" #include "third_party/tonic/dart_state.h" #include "third_party/tonic/logging/dart_invoke.h" +#include "third_party/tonic/typed_data/dart_byte_data.h" namespace flutter { -namespace { - -// Avoid copying the contents of messages beyond a certain size. -const int kMessageCopyThreshold = 1000; - -void MessageDataFinalizer(void* isolate_callback_data, - Dart_WeakPersistentHandle handle, - void* peer) { - std::vector* data = reinterpret_cast*>(peer); - delete data; -} - -Dart_Handle WrapByteData(std::vector data) { - if (data.size() < kMessageCopyThreshold) { - return ToByteData(data); - } else { - std::vector* heap_data = new std::vector(std::move(data)); - return Dart_NewExternalTypedDataWithFinalizer( - Dart_TypedData_kByteData, heap_data->data(), heap_data->size(), - heap_data, heap_data->size(), MessageDataFinalizer); - } -} - -Dart_Handle WrapByteData(std::unique_ptr mapping) { - std::vector data(mapping->GetSize()); - memcpy(data.data(), mapping->GetMapping(), mapping->GetSize()); - return WrapByteData(std::move(data)); -} - -} // anonymous namespace - PlatformMessageResponseDart::PlatformMessageResponseDart( tonic::DartPersistentValue callback, fml::RefPtr ui_task_runner) @@ -71,7 +40,8 @@ void PlatformMessageResponseDart::Complete(std::unique_ptr data) { return; tonic::DartState::Scope scope(dart_state); - Dart_Handle byte_buffer = WrapByteData(std::move(data)); + Dart_Handle byte_buffer = + tonic::DartByteData::Create(data->GetMapping(), data->GetSize()); tonic::DartInvoke(callback.Release(), {byte_buffer}); })); } diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc index 8e44378a6f3fa..c71e08e677277 100644 --- a/lib/ui/window/window.cc +++ b/lib/ui/window/window.cc @@ -166,25 +166,12 @@ void GetPersistentIsolateData(Dart_NativeArguments args) { persistent_isolate_data->GetSize())); } -} // namespace - Dart_Handle ToByteData(const std::vector& buffer) { - Dart_Handle data_handle = - Dart_NewTypedData(Dart_TypedData_kByteData, buffer.size()); - if (Dart_IsError(data_handle)) - return data_handle; - - Dart_TypedData_Type type; - void* data = nullptr; - intptr_t num_bytes = 0; - FML_CHECK(!Dart_IsError( - Dart_TypedDataAcquireData(data_handle, &type, &data, &num_bytes))); - - memcpy(data, buffer.data(), num_bytes); - Dart_TypedDataReleaseData(data_handle); - return data_handle; + return tonic::DartByteData::Create(buffer.data(), buffer.size()); } +} // namespace + WindowClient::~WindowClient() {} Window::Window(WindowClient* client) : client_(client) {} diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h index 3d7dc52574653..2549a4676c761 100644 --- a/lib/ui/window/window.h +++ b/lib/ui/window/window.h @@ -35,8 +35,6 @@ namespace flutter { class FontCollection; class Scene; -Dart_Handle ToByteData(const std::vector& buffer); - // Must match the AccessibilityFeatureFlag enum in window.dart. enum class AccessibilityFeatureFlag : int32_t { kAccessibleNavigation = 1 << 0, diff --git a/third_party/tonic/typed_data/dart_byte_data.cc b/third_party/tonic/typed_data/dart_byte_data.cc index 5556e37a06d46..b548b0a9c4f4c 100644 --- a/third_party/tonic/typed_data/dart_byte_data.cc +++ b/third_party/tonic/typed_data/dart_byte_data.cc @@ -8,10 +8,32 @@ namespace tonic { +namespace { + +// For large objects it is more efficient to use an external typed data object +// with a buffer allocated outside the Dart heap. +const int kExternalSizeThreshold = 1000; + +void FreeFinalizer(void* isolate_callback_data, + Dart_WeakPersistentHandle handle, + void* peer) { + free(peer); +} + +} // anonymous namespace + Dart_Handle DartByteData::Create(const void* data, size_t length) { - auto handle = DartByteData{data, length}.dart_handle(); - // The destructor should release the typed data. - return handle; + if (length < kExternalSizeThreshold) { + auto handle = DartByteData{data, length}.dart_handle(); + // The destructor should release the typed data. + return handle; + } else { + void* buf = ::malloc(length); + TONIC_DCHECK(buf); + ::memcpy(buf, data, length); + return Dart_NewExternalTypedDataWithFinalizer( + Dart_TypedData_kByteData, buf, length, buf, length, FreeFinalizer); + } } DartByteData::DartByteData()