未验证 提交 9fcfec39 编写于 作者: J Jason Simmons 提交者: GitHub

Avoid creating a vector when constructing Dart typed data objects for platform messages (#18838)

上级 1551b742
......@@ -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<uint8_t>* data = reinterpret_cast<std::vector<uint8_t>*>(peer);
delete data;
}
Dart_Handle WrapByteData(std::vector<uint8_t> data) {
if (data.size() < kMessageCopyThreshold) {
return ToByteData(data);
} else {
std::vector<uint8_t>* heap_data = new std::vector<uint8_t>(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<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(
tonic::DartPersistentValue callback,
fml::RefPtr<fml::TaskRunner> ui_task_runner)
......@@ -71,7 +40,8 @@ void PlatformMessageResponseDart::Complete(std::unique_ptr<fml::Mapping> 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});
}));
}
......
......@@ -166,25 +166,12 @@ void GetPersistentIsolateData(Dart_NativeArguments args) {
persistent_isolate_data->GetSize()));
}
} // namespace
Dart_Handle ToByteData(const std::vector<uint8_t>& 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) {}
......
......@@ -35,8 +35,6 @@ namespace flutter {
class FontCollection;
class Scene;
Dart_Handle ToByteData(const std::vector<uint8_t>& buffer);
// Must match the AccessibilityFeatureFlag enum in window.dart.
enum class AccessibilityFeatureFlag : int32_t {
kAccessibleNavigation = 1 << 0,
......
......@@ -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()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册