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/volatile_path_tracker.h"
8#include "flutter/lib/ui/window/platform_message_response_dart.h"
9#include "flutter/runtime/dart_vm_lifecycle.h"
10#include "flutter/shell/common/thread_host.h"
11#include "flutter/testing/dart_isolate_runner.h"
12#include "flutter/testing/fixture_test.h"
13
14#include <future>
15
16namespace flutter {
17
18class Fixture : public testing::FixtureTest {
19 void TestBody() override{};
20};
21
22static void BM_PlatformMessageResponseDartComplete(benchmark::State& state) {
23 ThreadHost thread_host(ThreadHost::ThreadHostConfig(
24 "test", ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
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, entrypoint: "main", args: {},
35 fixtures_path: testing::GetDefaultKernelFilePath(), io_manager: {});
36
37 while (state.KeepRunning()) {
38 state.PauseTiming();
39 bool successful = isolate->RunInIsolateScope(closure: [&]() -> 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>(args&: data);
44
45 Dart_Handle library = Dart_RootLibrary();
46 Dart_Handle closure =
47 Dart_GetField(container: library, name: Dart_NewStringFromCString(str: "messageCallback"));
48
49 auto message = fml::MakeRefCounted<PlatformMessageResponseDart>(
50 args: tonic::DartPersistentValue(isolate->get(), closure),
51 args: thread_host.ui_thread->GetTaskRunner(), args: "");
52
53 message->Complete(data: 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 task: [&completed] { completed.set_value(true); });
66 completed.get_future().wait();
67 }
68}
69
70static void BM_PathVolatilityTracker(benchmark::State& state) {
71 ThreadHost thread_host(ThreadHost::ThreadHostConfig(
72 "test", ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
73 ThreadHost::Type::IO | ThreadHost::Type::UI));
74 TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
75 thread_host.raster_thread->GetTaskRunner(),
76 thread_host.ui_thread->GetTaskRunner(),
77 thread_host.io_thread->GetTaskRunner());
78
79 VolatilePathTracker tracker(task_runners.GetUITaskRunner(), true);
80
81 while (state.KeepRunning()) {
82 std::vector<std::shared_ptr<VolatilePathTracker::TrackedPath>> paths;
83 constexpr int path_count = 1000;
84 for (int i = 0; i < path_count; i++) {
85 auto path = std::make_shared<VolatilePathTracker::TrackedPath>();
86 path->path = SkPath();
87 path->path.setIsVolatile(true);
88 paths.push_back(x: std::move(path));
89 }
90
91 fml::AutoResetWaitableEvent latch;
92 task_runners.GetUITaskRunner()->PostTask(task: [&]() {
93 for (auto path : paths) {
94 tracker.Track(path);
95 }
96 latch.Signal();
97 });
98
99 latch.Wait();
100
101 task_runners.GetUITaskRunner()->PostTask(task: [&]() { tracker.OnFrame(); });
102
103 for (int i = 0; i < path_count - 10; ++i) {
104 paths[i].reset();
105 }
106
107 task_runners.GetUITaskRunner()->PostTask(task: [&]() { tracker.OnFrame(); });
108
109 latch.Reset();
110 task_runners.GetUITaskRunner()->PostTask(task: [&]() { latch.Signal(); });
111 latch.Wait();
112 }
113}
114
115BENCHMARK(BM_PlatformMessageResponseDartComplete)
116 ->Unit(unit: benchmark::kMicrosecond);
117
118BENCHMARK(BM_PathVolatilityTracker)->Unit(unit: benchmark::kMillisecond);
119
120} // namespace flutter
121

source code of flutter_engine/flutter/lib/ui/ui_benchmarks.cc