| // 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::Platform | ThreadHost::Type::RASTER | |
| ThreadHost::Type::IO | ThreadHost::Type::UI)); |
| 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::Platform | ThreadHost::Type::RASTER | |
| ThreadHost::Type::IO | ThreadHost::Type::UI)); |
| 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 (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 |