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 | |
15 | namespace flutter { |
16 | |
17 | class Fixture : public testing::FixtureTest { |
18 | void TestBody() override{}; |
19 | }; |
20 | |
21 | static 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 | |
70 | BENCHMARK(BM_PlatformMessageResponseDartComplete) |
71 | ->Unit(benchmark::kMicrosecond); |
72 | |
73 | } // namespace flutter |
74 | |