| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/benchmarking/benchmarking.h" | |
| #include "flutter/common/settings.h" | |
| #include "flutter/lib/ui/volatile_path_tracker.h" | |
| #include "flutter/lib/ui/window/platform_message_response_dart.h" | |
| #include "flutter/runtime/dart_vm_lifecycle.h" | |
| #include "flutter/shell/common/thread_host.h" | |
| #include "flutter/testing/dart_isolate_runner.h" | |
| #include "flutter/testing/fixture_test.h" | |
| #include <future> | |
| namespace flutter { | |
| class Fixture : public testing::FixtureTest { | |
| void TestBody() override {}; | |
| }; | |
| static void BM_PlatformMessageResponseDartComplete(benchmark::State& state) { | |
| ThreadHost thread_host(ThreadHost::ThreadHostConfig( | |
| "test", ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster | | |
| ThreadHost::Type::kIo | ThreadHost::Type::kUi)); | |
| TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), | |
| thread_host.raster_thread->GetTaskRunner(), | |
| thread_host.ui_thread->GetTaskRunner(), | |
| thread_host.io_thread->GetTaskRunner()); | |
| Fixture fixture; | |
| auto settings = fixture.CreateSettingsForFixture(); | |
| auto vm_ref = DartVMRef::Create(settings); | |
| auto isolate = | |
| testing::RunDartCodeInIsolate(vm_ref, settings, task_runners, "main", {}, | |
| testing::GetDefaultKernelFilePath(), {}); | |
| while (state.KeepRunning()) { | |
| state.PauseTiming(); | |
| bool successful = isolate->RunInIsolateScope([&]() -> bool { | |
| // Simulate a message of 3 MB | |
| std::vector<uint8_t> data(3 << 20, 0); | |
| std::unique_ptr<fml::Mapping> mapping = | |
| std::make_unique<fml::DataMapping>(data); | |
| Dart_Handle library = Dart_RootLibrary(); | |
| Dart_Handle closure = | |
| Dart_GetField(library, Dart_NewStringFromCString("messageCallback")); | |
| auto message = fml::MakeRefCounted<PlatformMessageResponseDart>( | |
| tonic::DartPersistentValue(isolate->get(), closure), | |
| thread_host.ui_thread->GetTaskRunner(), ""); | |
| message->Complete(std::move(mapping)); | |
| return true; | |
| }); | |
| FML_CHECK(successful); | |
| state.ResumeTiming(); | |
| // We skip timing everything above because the copy triggered by | |
| // message->Complete is a task posted on the UI thread. The following wait | |
| // for a UI task would let us know when that copy is done. | |
| std::promise<bool> completed; | |
| task_runners.GetUITaskRunner()->PostTask( | |
| [&completed] { completed.set_value(true); }); | |
| completed.get_future().wait(); | |
| } | |
| } | |
| static void BM_PathVolatilityTracker(benchmark::State& state) { | |
| ThreadHost thread_host(ThreadHost::ThreadHostConfig( | |
| "test", ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster | | |
| ThreadHost::Type::kIo | ThreadHost::Type::kUi)); | |
| TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), | |
| thread_host.raster_thread->GetTaskRunner(), | |
| thread_host.ui_thread->GetTaskRunner(), | |
| thread_host.io_thread->GetTaskRunner()); | |
| VolatilePathTracker tracker(task_runners.GetUITaskRunner(), true); | |
| while (state.KeepRunning()) { | |
| std::vector<std::shared_ptr<VolatilePathTracker::TrackedPath>> paths; | |
| constexpr int path_count = 1000; | |
| for (int i = 0; i < path_count; i++) { | |
| auto path = std::make_shared<VolatilePathTracker::TrackedPath>(); | |
| path->path = SkPath(); | |
| path->path.setIsVolatile(true); | |
| paths.push_back(std::move(path)); | |
| } | |
| fml::AutoResetWaitableEvent latch; | |
| task_runners.GetUITaskRunner()->PostTask([&]() { | |
| for (const auto& path : paths) { | |
| tracker.Track(path); | |
| } | |
| latch.Signal(); | |
| }); | |
| latch.Wait(); | |
| task_runners.GetUITaskRunner()->PostTask([&]() { tracker.OnFrame(); }); | |
| for (int i = 0; i < path_count - 10; ++i) { | |
| paths[i].reset(); | |
| } | |
| task_runners.GetUITaskRunner()->PostTask([&]() { tracker.OnFrame(); }); | |
| latch.Reset(); | |
| task_runners.GetUITaskRunner()->PostTask([&]() { latch.Signal(); }); | |
| latch.Wait(); | |
| } | |
| } | |
| BENCHMARK(BM_PlatformMessageResponseDartComplete) | |
| ->Unit(benchmark::kMicrosecond); | |
| BENCHMARK(BM_PathVolatilityTracker)->Unit(benchmark::kMillisecond); | |
| } // namespace flutter |