1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/benchmarking/benchmarking.h"
6#include "flutter/common/settings.h"
7#include "flutter/lib/ui/window/platform_message_response_dart.h"
8#include "flutter/runtime/dart_vm_lifecycle.h"
9#include "flutter/shell/common/thread_host.h"
10#include "flutter/testing/dart_isolate_runner.h"
11#include "flutter/testing/fixture_test.h"
12
13#include <future>
14
15namespace flutter {
16
17class Fixture : public testing::FixtureTest {
18 void TestBody() override{};
19};
20
21static void BM_PlatformMessageResponseDartComplete(
22 benchmark::State& state) { // NOLINT
23 ThreadHost thread_host("test",
24 ThreadHost::Type::Platform | ThreadHost::Type::GPU |
25 ThreadHost::Type::IO | ThreadHost::Type::UI);
26 TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
27 thread_host.raster_thread->GetTaskRunner(),
28 thread_host.ui_thread->GetTaskRunner(),
29 thread_host.io_thread->GetTaskRunner());
30 Fixture fixture;
31 auto settings = fixture.CreateSettingsForFixture();
32 auto vm_ref = DartVMRef::Create(settings);
33 auto isolate =
34 testing::RunDartCodeInIsolate(vm_ref, settings, task_runners, "main", {},
35 testing::GetFixturesPath(), {});
36
37 while (state.KeepRunning()) {
38 state.PauseTiming();
39 bool successful = isolate->RunInIsolateScope([&]() -> bool {
40 // Simulate a message of 3 MB
41 std::vector<uint8_t> data(3 << 20, 0);
42 std::unique_ptr<fml::Mapping> mapping =
43 std::make_unique<fml::DataMapping>(data);
44
45 Dart_Handle library = Dart_RootLibrary();
46 Dart_Handle closure =
47 Dart_GetField(library, Dart_NewStringFromCString("messageCallback"));
48
49 auto message = fml::MakeRefCounted<PlatformMessageResponseDart>(
50 tonic::DartPersistentValue(isolate->get(), closure),
51 thread_host.ui_thread->GetTaskRunner());
52
53 message->Complete(std::move(mapping));
54
55 return true;
56 });
57 FML_CHECK(successful);
58 state.ResumeTiming();
59
60 // We skip timing everything above because the copy triggered by
61 // message->Complete is a task posted on the UI thread. The following wait
62 // for a UI task would let us know when that copy is done.
63 std::promise<bool> completed;
64 task_runners.GetUITaskRunner()->PostTask(
65 [&completed] { completed.set_value(true); });
66 completed.get_future().wait();
67 }
68}
69
70BENCHMARK(BM_PlatformMessageResponseDartComplete)
71 ->Unit(benchmark::kMicrosecond);
72
73} // namespace flutter
74