Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
tester_main.cc
Go to the documentation of this file.
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#define FML_USED_ON_EMBEDDER
6
7#include <cstdlib>
8#include <cstring>
9#include <iostream>
10
11#include "flutter/assets/asset_manager.h"
12#include "flutter/assets/directory_asset_bundle.h"
13#include "flutter/flow/embedded_views.h"
14#include "flutter/fml/build_config.h"
15#include "flutter/fml/file.h"
16#include "flutter/fml/make_copyable.h"
17#include "flutter/fml/message_loop.h"
18#include "flutter/fml/paths.h"
19#include "flutter/fml/synchronization/waitable_event.h"
20#include "flutter/fml/task_runner.h"
21#include "flutter/shell/common/platform_view.h"
22#include "flutter/shell/common/rasterizer.h"
23#include "flutter/shell/common/shell.h"
24#include "flutter/shell/common/switches.h"
25#include "flutter/shell/common/thread_host.h"
26#include "flutter/shell/gpu/gpu_surface_software.h"
27#include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h"
28
29#include "third_party/dart/runtime/include/bin/dart_io_api.h"
30#include "third_party/dart/runtime/include/dart_api.h"
32
33// Impeller should only be enabled if the Vulkan backend is enabled.
34#define ALLOW_IMPELLER (IMPELLER_SUPPORTS_RENDERING && IMPELLER_ENABLE_VULKAN)
35
36#if ALLOW_IMPELLER
37#include <vulkan/vulkan.h> // nogncheck
38#include "impeller/entity/vk/entity_shaders_vk.h" // nogncheck
39#include "impeller/entity/vk/framebuffer_blend_shaders_vk.h" // nogncheck
40#include "impeller/entity/vk/modern_shaders_vk.h" // nogncheck
43#include "impeller/renderer/context.h" // nogncheck
44#include "impeller/renderer/vk/compute_shaders_vk.h" // nogncheck
45#include "shell/gpu/gpu_surface_vulkan_impeller.h" // nogncheck
46#if IMPELLER_ENABLE_3D
47#include "impeller/scene/shaders/vk/scene_shaders_vk.h" // nogncheck
48#endif // IMPELLER_ENABLE_3D
49
50static std::vector<std::shared_ptr<fml::Mapping>> ShaderLibraryMappings() {
51 return {
52 std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
53 impeller_entity_shaders_vk_length),
54 std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
55 impeller_modern_shaders_vk_length),
56 std::make_shared<fml::NonOwnedMapping>(
57 impeller_framebuffer_blend_shaders_vk_data,
58 impeller_framebuffer_blend_shaders_vk_length),
59#if IMPELLER_ENABLE_3D
60 std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
61 impeller_scene_shaders_vk_length),
62#endif // IMPELLER_ENABLE_3D
63 std::make_shared<fml::NonOwnedMapping>(
64 impeller_compute_shaders_vk_data, impeller_compute_shaders_vk_length),
65 };
66}
67
71 std::shared_ptr<impeller::ContextVK> context;
72 std::shared_ptr<impeller::SurfaceContextVK> surface_context;
73
74 bool Initialize(bool enable_validation);
75};
76
77bool ImpellerVulkanContextHolder::Initialize(bool enable_validation) {
78 impeller::ContextVK::Settings context_settings;
80 context_settings.shader_libraries_data = ShaderLibraryMappings();
82 context_settings.enable_validation = enable_validation;
83
84 context = impeller::ContextVK::Create(std::move(context_settings));
85 if (!context || !context->IsValid()) {
86 VALIDATION_LOG << "Could not create Vulkan context.";
87 return false;
88 }
89
90 impeller::vk::SurfaceKHR vk_surface;
91 impeller::vk::HeadlessSurfaceCreateInfoEXT surface_create_info;
92 auto res = context->GetInstance().createHeadlessSurfaceEXT(
93 &surface_create_info, // surface create info
94 nullptr, // allocator
95 &vk_surface // surface
96 );
97 if (res != impeller::vk::Result::eSuccess) {
98 VALIDATION_LOG << "Could not create surface for tester "
99 << impeller::vk::to_string(res);
100 return false;
101 }
102
103 impeller::vk::UniqueSurfaceKHR surface{vk_surface, context->GetInstance()};
104 surface_context = context->CreateSurfaceContext();
105 if (!surface_context->SetWindowSurface(std::move(surface),
106 impeller::ISize{1, 1})) {
107 VALIDATION_LOG << "Could not set up surface for context.";
108 return false;
109 }
110 return true;
111}
112
113#else
115#endif // IMPELLER_SUPPORTS_RENDERING
116
117#if defined(FML_OS_WIN)
118#include <combaseapi.h>
119#endif // defined(FML_OS_WIN)
120
121#if defined(FML_OS_POSIX)
122#include <signal.h>
123#endif // defined(FML_OS_POSIX)
124
125namespace flutter {
126
127static absl::NoDestructor<std::unique_ptr<Shell>> g_shell;
128
129static constexpr int64_t kImplicitViewId = 0ll;
130
131static void ConfigureShell(Shell* shell) {
132 auto device_pixel_ratio = 3.0;
133 auto physical_width = 2400.0; // 800 at 3x resolution.
134 auto physical_height = 1800.0; // 600 at 3x resolution.
135
136 std::vector<std::unique_ptr<Display>> displays;
137 displays.push_back(std::make_unique<Display>(
138 0, 60, physical_width, physical_height, device_pixel_ratio));
139 shell->OnDisplayUpdates(std::move(displays));
140
141 flutter::ViewportMetrics metrics{};
142 metrics.device_pixel_ratio = device_pixel_ratio;
143 metrics.physical_width = physical_width;
144 metrics.physical_height = physical_height;
145 metrics.display_id = 0;
146 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId, metrics);
147}
148
150 // |ExternalViewEmbedder|
151 DlCanvas* GetRootCanvas() override { return nullptr; }
152
153 // |ExternalViewEmbedder|
154 void CancelFrame() override {}
155
156 // |ExternalViewEmbedder|
159 raster_thread_merger) override {}
160
161 // |ExternalViewEmbedder|
163 double device_pixel_ratio) override {}
164
165 // |ExternalViewEmbedder|
167 int64_t view_id,
168 std::unique_ptr<EmbeddedViewParams> params) override {}
169
170 // |ExternalViewEmbedder|
171 DlCanvas* CompositeEmbeddedView(int64_t view_id) override {
172 return &builder_;
173 }
174
175 private:
176 DisplayListBuilder builder_;
177};
178
180 public:
182 bool render_to_surface)
183 : GPUSurfaceSoftware(delegate, render_to_surface) {}
184
185 bool EnableRasterCache() const override { return false; }
186};
187
190 public:
192 const TaskRunners& task_runners,
193 ImpellerVulkanContextHolder&& impeller_context_holder)
194 : PlatformView(delegate, task_runners),
195 impeller_context_holder_(std::move(impeller_context_holder)) {}
196
198#if ALLOW_IMPELLER
199 if (impeller_context_holder_.context) {
200 impeller_context_holder_.context->Shutdown();
201 }
202#endif
203 }
204
205 // |PlatformView|
206 std::shared_ptr<impeller::Context> GetImpellerContext() const override {
207#if ALLOW_IMPELLER
208 return std::static_pointer_cast<impeller::Context>(
209 impeller_context_holder_.context);
210#else
211 return nullptr;
212#endif // ALLOW_IMPELLER
213 }
214
215 // |PlatformView|
216 std::unique_ptr<Surface> CreateRenderingSurface() override {
217#if ALLOW_IMPELLER
219 FML_DCHECK(impeller_context_holder_.context);
220 auto surface = std::make_unique<GPUSurfaceVulkanImpeller>(
221 impeller_context_holder_.surface_context);
222 FML_DCHECK(surface->IsValid());
223 return surface;
224 }
225#endif // ALLOW_IMPELLER
226 auto surface = std::make_unique<TesterGPUSurfaceSoftware>(
227 this, true /* render to surface */);
228 FML_DCHECK(surface->IsValid());
229 return surface;
230 }
231
232 // |GPUSurfaceSoftwareDelegate|
234 if (sk_surface_ != nullptr &&
235 SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
236 // The old and new surface sizes are the same. Nothing to do here.
237 return sk_surface_;
238 }
239
243 sk_surface_ = SkSurfaces::Raster(info, nullptr);
244
245 if (sk_surface_ == nullptr) {
247 << "Could not create backing store for software rendering.";
248 return nullptr;
249 }
250
251 return sk_surface_;
252 }
253
254 // |GPUSurfaceSoftwareDelegate|
255 bool PresentBackingStore(sk_sp<SkSurface> backing_store) override {
256 return true;
257 }
258
259 // |PlatformView|
260 std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder() override {
261 return external_view_embedder_;
262 }
263
264 private:
265 sk_sp<SkSurface> sk_surface_ = nullptr;
266 [[maybe_unused]] ImpellerVulkanContextHolder impeller_context_holder_;
267 std::shared_ptr<TesterExternalViewEmbedder> external_view_embedder_ =
268 std::make_shared<TesterExternalViewEmbedder>();
269};
270
271// Checks whether the engine's main Dart isolate has no pending work. If so,
272// then exit the given message loop.
274 public:
276 fml::RefPtr<fml::TaskRunner> main_task_runner,
277 bool run_forever)
278 : shell_(shell),
279 main_task_runner_(std::move(main_task_runner)),
280 run_forever_(run_forever) {}
281
283 return static_cast<int>(last_error_.value_or(DartErrorCode::NoError));
284 }
285
287 last_error_ = shell_.GetUIIsolateLastError();
288 if (shell_.EngineHasLivePorts()) {
289 // The UI isolate still has live ports and is running. Nothing to do
290 // just yet.
291 return;
292 }
293
294 if (run_forever_) {
295 // We need this script to run forever. We have already recorded the last
296 // error. Keep going.
297 return;
298 }
299
300 if (!has_terminated_) {
301 // Only try to terminate the loop once.
302 has_terminated_ = true;
303 fml::TaskRunner::RunNowOrPostTask(main_task_runner_, []() {
305 });
306 }
307 }
308
309 private:
310 Shell& shell_;
311 fml::RefPtr<fml::TaskRunner> main_task_runner_;
312 bool run_forever_ = false;
313 std::optional<DartErrorCode> last_error_;
314 bool has_terminated_ = false;
315
317};
318
319// Processes spawned via dart:io inherit their signal handling from the parent
320// process. As part of spawning, the spawner blocks signals temporarily, so we
321// need to explicitly unblock the signals we care about in the new process. In
322// particular, we need to unblock SIGPROF for CPU profiling to work on the
323// mutator thread in the main isolate in this process (threads spawned by the VM
324// know about this limitation and automatically have this signal unblocked).
325static void UnblockSIGPROF() {
326#if defined(FML_OS_POSIX)
327 sigset_t set;
328 sigemptyset(&set);
329 sigaddset(&set, SIGPROF);
330 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
331#endif // defined(FML_OS_POSIX)
332}
333
334int RunTester(const flutter::Settings& settings,
335 bool run_forever,
336 bool multithreaded) {
337 const auto thread_label = "io.flutter.test.";
338
339 // Necessary if we want to use the CPU profiler on the main isolate's mutator
340 // thread.
341 //
342 // OSX WARNING: avoid spawning additional threads before this call due to a
343 // kernel bug that may enable SIGPROF on an unintended thread in the process.
345
347
348 auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
349
350 std::unique_ptr<ThreadHost> threadhost;
351 fml::RefPtr<fml::TaskRunner> platform_task_runner;
352 fml::RefPtr<fml::TaskRunner> raster_task_runner;
353 fml::RefPtr<fml::TaskRunner> ui_task_runner;
354 fml::RefPtr<fml::TaskRunner> io_task_runner;
355
356 if (multithreaded) {
357 threadhost = std::make_unique<ThreadHost>(
360 platform_task_runner = current_task_runner;
361 raster_task_runner = threadhost->raster_thread->GetTaskRunner();
362 ui_task_runner = threadhost->ui_thread->GetTaskRunner();
363 io_task_runner = threadhost->io_thread->GetTaskRunner();
364 } else {
365 platform_task_runner = raster_task_runner = ui_task_runner =
366 io_task_runner = current_task_runner;
367 }
368
369 const flutter::TaskRunners task_runners(thread_label, // dart thread label
370 platform_task_runner, // platform
371 raster_task_runner, // raster
372 ui_task_runner, // ui
373 io_task_runner // io
374 );
375
376 ImpellerVulkanContextHolder impeller_context_holder;
377
378#if ALLOW_IMPELLER
379 if (settings.enable_impeller) {
380 if (!impeller_context_holder.Initialize(
381 settings.enable_vulkan_validation)) {
382 return EXIT_FAILURE;
383 }
384 }
385#endif // ALLOW_IMPELLER
386
387 Shell::CreateCallback<PlatformView> on_create_platform_view =
388 fml::MakeCopyable([impeller_context_holder = std::move(
389 impeller_context_holder)](Shell& shell) mutable {
390 return std::make_unique<TesterPlatformView>(
391 shell, shell.GetTaskRunners(), std::move(impeller_context_holder));
392 });
393
394 Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
395 return std::make_unique<Rasterizer>(
397 };
398
400 task_runners, //
401 settings, //
402 on_create_platform_view, //
403 on_create_rasterizer //
404 )
405 .release());
406 auto shell = g_shell->get();
407
408 if (!shell || !shell->IsSetup()) {
409 FML_LOG(ERROR) << "Could not set up the shell.";
410 return EXIT_FAILURE;
411 }
412
413 if (settings.application_kernel_asset.empty()) {
414 FML_LOG(ERROR) << "Dart kernel file not specified.";
415 return EXIT_FAILURE;
416 }
417
418 shell->GetPlatformView()->NotifyCreated();
419
420 // Initialize default testing locales. There is no platform to
421 // pass locales on the tester, so to retain expected locale behavior,
422 // we emulate it in here by passing in 'en_US' and 'zh_CN' as test locales.
423 const char* locale_json =
424 "{\"method\":\"setLocale\",\"args\":[\"en\",\"US\",\"\",\"\",\"zh\","
425 "\"CN\",\"\",\"\"]}";
426 auto locale_bytes = fml::MallocMapping::Copy(
427 locale_json, locale_json + std::strlen(locale_json));
429 shell->GetPlatformView()->DispatchPlatformMessage(
430 std::make_unique<flutter::PlatformMessage>(
431 "flutter/localization", std::move(locale_bytes), response));
432
433 std::initializer_list<fml::FileMapping::Protection> protection = {
435 auto main_dart_file_mapping = std::make_unique<fml::FileMapping>(
437 fml::paths::AbsolutePath(settings.application_kernel_asset).c_str(),
439 protection);
440
441 auto isolate_configuration =
442 IsolateConfiguration::CreateForKernel(std::move(main_dart_file_mapping));
443
444 if (!isolate_configuration) {
445 FML_LOG(ERROR) << "Could create isolate configuration.";
446 return EXIT_FAILURE;
447 }
448
449 auto asset_manager = std::make_shared<flutter::AssetManager>();
450 asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
451 fml::Duplicate(settings.assets_dir), true));
452 asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
453 fml::OpenDirectory(settings.assets_path.c_str(), false,
455 true));
456
457 RunConfiguration run_configuration(std::move(isolate_configuration),
458 std::move(asset_manager));
459
460 // The script completion task observer that will be installed on the UI thread
461 // that watched if the engine has any live ports.
462 ScriptCompletionTaskObserver completion_observer(
463 *shell, // a valid shell
465 .GetTaskRunner(), // the message loop to terminate
466 run_forever // should the exit be ignored
467 );
468
469 bool engine_did_run = false;
470
472 auto task_observer_add = [&completion_observer]() {
474 reinterpret_cast<intptr_t>(&completion_observer),
475 [&completion_observer]() { completion_observer.DidProcessTask(); });
476 };
477
478 auto task_observer_remove = [&completion_observer, &latch]() {
480 reinterpret_cast<intptr_t>(&completion_observer));
481 latch.Signal();
482 };
483
484 shell->RunEngine(std::move(run_configuration),
485 [&engine_did_run, &ui_task_runner,
486 &task_observer_add](Engine::RunStatus run_status) mutable {
487 if (run_status != flutter::Engine::RunStatus::Failure) {
488 engine_did_run = true;
489 // Now that our engine is initialized we can install the
490 // ScriptCompletionTaskObserver
492 task_observer_add);
493 }
494 });
495
496 ConfigureShell(shell);
497
498 // Run the message loop and wait for the script to do its thing.
500
501 // Cleanup the completion observer synchronously as it is living on the
502 // stack.
503 fml::TaskRunner::RunNowOrPostTask(ui_task_runner, task_observer_remove);
504 latch.Wait();
505
506 delete g_shell->release();
507
508 if (!engine_did_run) {
509 // If the engine itself didn't have a chance to run, there is no point in
510 // asking it if there was an error. Signal a failure unconditionally.
511 return EXIT_FAILURE;
512 }
513
514 return completion_observer.GetExitCodeForLastError();
515}
516
517#ifdef _WIN32
518#define EXPORTED __declspec(dllexport)
519#else
520#define EXPORTED __attribute__((visibility("default")))
521#endif
522
523extern "C" {
525 std::shared_ptr<fml::FileMapping> mapping =
527 if (!mapping) {
528 return Dart_Null();
529 }
531}
532
533EXPORTED Dart_Handle LookupEntryPoint(const char* uri, const char* name) {
534 if (!uri || !name) {
535 return Dart_Null();
536 }
538 if (Dart_IsError(lib)) {
539 return lib;
540 }
542}
543
544EXPORTED void Spawn(const char* entrypoint, const char* route) {
545 auto shell = g_shell->get();
546 auto isolate = Dart_CurrentIsolate();
547 auto spawn_task = [shell, entrypoint = std::string(entrypoint),
548 route = std::string(route)]() {
549 auto configuration = RunConfiguration::InferFromSettings(
550 shell->GetSettings(), /*io_worker=*/nullptr,
551 /*launch_type=*/IsolateLaunchType::kExistingGroup);
552 configuration.SetEntrypoint(entrypoint);
553
554 Shell::CreateCallback<PlatformView> on_create_platform_view =
555 fml::MakeCopyable([](Shell& shell) mutable {
556 ImpellerVulkanContextHolder impeller_context_holder;
557 return std::make_unique<TesterPlatformView>(
558 shell, shell.GetTaskRunners(),
559 std::move(impeller_context_holder));
560 });
561
562 Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
563 return std::make_unique<Rasterizer>(
565 };
566
567 // Spawn a shell, and keep it running until it has no live ports, then
568 // delete it on the platform thread.
569 auto spawned_shell =
570 shell
571 ->Spawn(std::move(configuration), route, on_create_platform_view,
572 on_create_rasterizer)
573 .release();
574
575 ConfigureShell(spawned_shell);
576
578 spawned_shell->GetTaskRunners().GetUITaskRunner(), [spawned_shell]() {
579 fml::MessageLoop::GetCurrent().AddTaskObserver(
580 reinterpret_cast<intptr_t>(spawned_shell), [spawned_shell]() {
581 if (spawned_shell->EngineHasLivePorts()) {
582 return;
583 }
584
585 fml::MessageLoop::GetCurrent().RemoveTaskObserver(
586 reinterpret_cast<intptr_t>(spawned_shell));
587 // Shell must be deleted on the platform task runner.
588 fml::TaskRunner::RunNowOrPostTask(
589 spawned_shell->GetTaskRunners().GetPlatformTaskRunner(),
590 [spawned_shell]() { delete spawned_shell; });
591 });
592 });
593 };
595 // The global shell pointer is never deleted, short of application exit.
596 // This UI task runner cannot be latched because it will block spawning a new
597 // shell in the case where flutter_tester is running multithreaded.
599 shell->GetTaskRunners().GetPlatformTaskRunner(), spawn_task);
600
601 Dart_EnterIsolate(isolate);
602}
603
605 // Enable Isolate.exit().
606 FML_DCHECK(Dart_CurrentIsolate() != nullptr);
607 Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
610 isolate_lib, tonic::ToDart("Isolate"), 0, nullptr);
613 Dart_SetField(isolate_type, tonic::ToDart("_mayExit"), Dart_True());
615}
616}
617
618} // namespace flutter
619
620int main(int argc, char* argv[]) {
623
624 auto command_line = fml::CommandLineFromPlatformOrArgcArgv(argc, argv);
625
626 if (command_line.HasOption(flutter::FlagForSwitch(flutter::Switch::Help))) {
627 flutter::PrintUsage("flutter_tester");
628 return EXIT_SUCCESS;
629 }
630
631 auto settings = flutter::SettingsFromCommandLine(command_line);
632 if (!command_line.positional_args().empty()) {
633 // The tester may not use the switch for the main dart file path. Specifying
634 // it as a positional argument instead.
635 settings.application_kernel_asset = command_line.positional_args()[0];
636 }
637
638 if (settings.application_kernel_asset.empty()) {
639 FML_LOG(ERROR) << "Dart kernel file not specified.";
640 return EXIT_FAILURE;
641 }
642
643 settings.leak_vm = false;
644 settings.enable_platform_isolates = true;
645
646 if (settings.icu_data_path.empty()) {
647 settings.icu_data_path = "icudtl.dat";
648 }
649
650 // The tools that read logs get confused if there is a log tag specified.
651 settings.log_tag = "";
652
653 settings.log_message_callback = [](const std::string& tag,
654 const std::string& message) {
655 if (!tag.empty()) {
656 std::cout << tag << ": ";
657 }
658 std::cout << message << std::endl;
659 };
660
661 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
663 };
664
665 settings.task_observer_remove = [](intptr_t key) {
667 };
668
669 settings.unhandled_exception_callback = [](const std::string& error,
670 const std::string& stack_trace) {
671 FML_LOG(ERROR) << "Unhandled exception" << std::endl
672 << "Exception: " << error << std::endl
673 << "Stack trace: " << stack_trace;
674 ::exit(1);
675 return true;
676 };
677
678#if defined(FML_OS_WIN)
679 CoInitializeEx(nullptr, COINIT_MULTITHREADED);
680#endif // defined(FML_OS_WIN)
681
682 return flutter::RunTester(settings,
683 command_line.HasOption(flutter::FlagForSwitch(
684 flutter::Switch::RunForever)),
685 command_line.HasOption(flutter::FlagForSwitch(
686 flutter::Switch::ForceMultithreading)));
687}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
static sk_sp< SkColorSpace > MakeSRGB()
int width() const
Definition SkSurface.h:178
int height() const
Definition SkSurface.h:184
static Dart_Handle LoadLibraryFromKernel(const std::shared_ptr< const fml::Mapping > &mapping)
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:37
RunStatus
Indicates the result of the call to Engine::Run.
Definition engine.h:78
Interface implemented by all platform surfaces that can present a software backing store to the "scre...
static std::unique_ptr< IsolateConfiguration > CreateForKernel(std::unique_ptr< const fml::Mapping > kernel)
Creates a JIT isolate configuration using the specified snapshot. This is a convenience method for th...
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
virtual const Settings & OnPlatformViewGetSettings() const =0
Called by the platform view on the platform thread to get the settings object associated with the pla...
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
PlatformView::Delegate & delegate_
Specifies all the configuration required by the runtime library to launch the root isolate....
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
ScriptCompletionTaskObserver(Shell &shell, fml::RefPtr< fml::TaskRunner > main_task_runner, bool run_forever)
std::optional< DartErrorCode > GetUIIsolateLastError() const
Used by embedders to get the last error from the Dart UI Isolate, if one exists.
Definition shell.cc:693
static std::unique_ptr< Shell > Create(const PlatformData &platform_data, const TaskRunners &task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer, bool is_gpu_disabled=false)
Creates a shell instance using the provided settings. The callbacks to create the various shell subco...
Definition shell.cc:167
bool EngineHasLivePorts() const
Used by embedders to check if the Engine is running and has any live ports remaining....
Definition shell.cc:713
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition shell.h:119
void PrepareFlutterView(SkISize frame_size, double device_pixel_ratio) override
void BeginFrame(GrDirectContext *context, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
DlCanvas * GetRootCanvas() override
void PrerollCompositeEmbeddedView(int64_t view_id, std::unique_ptr< EmbeddedViewParams > params) override
DlCanvas * CompositeEmbeddedView(int64_t view_id) override
bool EnableRasterCache() const override
TesterGPUSurfaceSoftware(GPUSurfaceSoftwareDelegate *delegate, bool render_to_surface)
std::shared_ptr< ExternalViewEmbedder > CreateExternalViewEmbedder() override
sk_sp< SkSurface > AcquireBackingStore(const SkISize &size) override
Called when the GPU surface needs a new buffer to render a new frame into.
std::unique_ptr< Surface > CreateRenderingSurface() override
std::shared_ptr< impeller::Context > GetImpellerContext() const override
bool PresentBackingStore(sk_sp< SkSurface > backing_store) override
Called by the platform when a frame has been rendered into the backing store and the platform must di...
TesterPlatformView(Delegate &delegate, const TaskRunners &task_runners, ImpellerVulkanContextHolder &&impeller_context_holder)
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
Definition mapping.cc:20
static MallocMapping Copy(const T *begin, const T *end)
Definition mapping.h:162
void RemoveTaskObserver(intptr_t key)
static void EnsureInitializedForCurrentThread()
void AddTaskObserver(intptr_t key, const fml::closure &callback)
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
static std::shared_ptr< ContextVK > Create(Settings settings)
DART_EXPORT Dart_Handle Dart_GetNonNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_Handle Dart_True(void)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT void Dart_ExitIsolate(void)
const EmbeddedViewParams * params
VkSurfaceKHR surface
Definition main.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_DCHECK(condition)
Definition logging.h:103
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
Win32Message message
char ** argv
Definition library.h:9
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
void SetExecutableName(const char *executable_name)
void SetExecutableArguments(int script_index, char **argv)
static void UnblockSIGPROF()
EXPORTED Dart_Handle LookupEntryPoint(const char *uri, const char *name)
@ NoError
No error has occurred.
int RunTester(const flutter::Settings &settings, bool run_forever, bool multithreaded)
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
Definition switches.cc:228
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition switches.h:32
constexpr FlutterViewId kImplicitViewId
EXPORTED void ForceShutdownIsolate()
static void ConfigureShell(Shell *shell)
static absl::NoDestructor< std::unique_ptr< Shell > > g_shell
EXPORTED void Spawn(const char *entrypoint, const char *route)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition switches.h:76
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however route
Definition switches.h:137
EXPORTED Dart_Handle LoadLibraryFromKernel(const char *path)
const std::string_view FlagForSwitch(Switch swtch)
Definition switches.cc:144
std::string AbsolutePath(const std::string &path)
fml::UniqueFD GetCachesDirectory()
fml::UniqueFD Duplicate(fml::UniqueFD::element_type descriptor)
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition file_posix.cc:97
internal::CopyableLambda< T > MakeCopyable(T lambda)
std::function< void()> closure
Definition closure.h:14
CommandLine CommandLineFromPlatformOrArgcArgv(int argc, const char *const *argv)
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition file_posix.cc:66
void Initialize(zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
Definition fuchsia.cc:103
Definition main.py:1
Definition ref_ptr.h:256
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
std::vector< std::shared_ptr< fml::Mapping > > shader_libraries_data
Definition context_vk.h:48
PFN_vkGetInstanceProcAddr proc_address_callback
Definition context_vk.h:47
#define EXPORTED
#define ERROR(message)
#define VALIDATION_LOG
Definition validation.h:73
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)