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/shell/common/shell.h"
6
7#include "flutter/benchmarking/benchmarking.h"
8#include "flutter/fml/logging.h"
9#include "flutter/runtime/dart_vm.h"
10#include "flutter/shell/common/thread_host.h"
11#include "flutter/testing/elf_loader.h"
12#include "flutter/testing/testing.h"
13
14namespace flutter {
15
16static void StartupAndShutdownShell(benchmark::State& state,
17 bool measure_startup,
18 bool measure_shutdown) {
19 auto assets_dir = fml::OpenDirectory(path: testing::GetFixturesPath(), create_if_necessary: false,
20 permission: fml::FilePermission::kRead);
21 std::unique_ptr<Shell> shell;
22 std::unique_ptr<ThreadHost> thread_host;
23 testing::ELFAOTSymbols aot_symbols;
24
25 {
26 benchmarking::ScopedPauseTiming pause(state, !measure_startup);
27 Settings settings = {};
28 settings.task_observer_add = [](intptr_t, const fml::closure&) {};
29 settings.task_observer_remove = [](intptr_t) {};
30
31 if (DartVM::IsRunningPrecompiledCode()) {
32 aot_symbols = testing::LoadELFSymbolFromFixturesIfNeccessary(
33 elf_filename: testing::kDefaultAOTAppELFFileName);
34 FML_CHECK(
35 testing::PrepareSettingsForAOTWithSymbols(settings, aot_symbols))
36 << "Could not set up settings with AOT symbols.";
37 } else {
38 settings.application_kernels = [&]() {
39 std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
40 kernel_mappings.emplace_back(
41 args: fml::FileMapping::CreateReadOnly(base_fd: assets_dir, sub_path: "kernel_blob.bin"));
42 return kernel_mappings;
43 };
44 }
45
46 thread_host = std::make_unique<ThreadHost>(args: ThreadHost::ThreadHostConfig(
47 "io.flutter.bench.", ThreadHost::Type::Platform |
48 ThreadHost::Type::RASTER |
49 ThreadHost::Type::IO | ThreadHost::Type::UI));
50
51 TaskRunners task_runners("test",
52 thread_host->platform_thread->GetTaskRunner(),
53 thread_host->raster_thread->GetTaskRunner(),
54 thread_host->ui_thread->GetTaskRunner(),
55 thread_host->io_thread->GetTaskRunner());
56
57 shell = Shell::Create(
58 platform_data: flutter::PlatformData(), task_runners, settings,
59 on_create_platform_view: [](Shell& shell) {
60 return std::make_unique<PlatformView>(args&: shell, args: shell.GetTaskRunners());
61 },
62 on_create_rasterizer: [](Shell& shell) { return std::make_unique<Rasterizer>(args&: shell); });
63 }
64
65 FML_CHECK(shell);
66
67 {
68 // The ui thread could be busy processing tasks after shell created, e.g.,
69 // default font manager setup. The measurement of shell shutdown should be
70 // considered after those ui tasks have been done.
71 //
72 // However, if we're measuring the complete time from startup to shutdown,
73 // this time should still be included.
74 benchmarking::ScopedPauseTiming pause(
75 state, !measure_shutdown || !measure_startup);
76 fml::AutoResetWaitableEvent latch;
77 fml::TaskRunner::RunNowOrPostTask(runner: thread_host->ui_thread->GetTaskRunner(),
78 task: [&latch]() { latch.Signal(); });
79 latch.Wait();
80 }
81
82 {
83 benchmarking::ScopedPauseTiming pause(state, !measure_shutdown);
84 // Shutdown must occur synchronously on the platform thread.
85 fml::AutoResetWaitableEvent latch;
86 fml::TaskRunner::RunNowOrPostTask(
87 runner: thread_host->platform_thread->GetTaskRunner(),
88 task: [&shell, &latch]() mutable {
89 shell.reset();
90 latch.Signal();
91 });
92 latch.Wait();
93 thread_host.reset();
94 }
95
96 FML_CHECK(!shell);
97}
98
99static void BM_ShellInitialization(benchmark::State& state) {
100 while (state.KeepRunning()) {
101 StartupAndShutdownShell(state, measure_startup: true, measure_shutdown: false);
102 }
103}
104
105BENCHMARK(BM_ShellInitialization);
106
107static void BM_ShellShutdown(benchmark::State& state) {
108 while (state.KeepRunning()) {
109 StartupAndShutdownShell(state, measure_startup: false, measure_shutdown: true);
110 }
111}
112
113BENCHMARK(BM_ShellShutdown);
114
115static void BM_ShellInitializationAndShutdown(benchmark::State& state) {
116 while (state.KeepRunning()) {
117 StartupAndShutdownShell(state, measure_startup: true, measure_shutdown: true);
118 }
119}
120
121BENCHMARK(BM_ShellInitializationAndShutdown);
122
123} // namespace flutter
124

source code of flutter_engine/flutter/shell/common/shell_benchmarks.cc