Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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
15#include "flutter/fml/file.h"
18#include "flutter/fml/paths.h"
27
28#include "third_party/abseil-cpp/absl/base/no_destructor.h"
29#include "third_party/dart/runtime/include/bin/dart_io_api.h"
30#include "third_party/dart/runtime/include/dart_api.h"
31#include "third_party/skia/include/core/SkSurface.h"
32
37
38#if defined(FML_OS_WIN)
39#include <combaseapi.h>
40#endif // defined(FML_OS_WIN)
41
42#if defined(FML_OS_POSIX)
43#include <signal.h>
44#endif // defined(FML_OS_POSIX)
45
46namespace flutter {
47
48static absl::NoDestructor<std::unique_ptr<Shell>> g_shell;
49
50namespace {
51std::unique_ptr<TesterContext> CreateTesterContext(const Settings& settings) {
52 std::unique_ptr<TesterContext> tester_context;
53#if TESTER_ENABLE_METAL
54 if (settings.enable_impeller &&
55 settings.requested_rendering_backend == "metal") {
56 tester_context = TesterContextMTLFactory::Create();
57 }
58#endif
59#if TESTER_ENABLE_OPENGLES
60 if (settings.enable_impeller &&
61 settings.requested_rendering_backend == "opengles") {
62 tester_context = TesterContextGLESFactory::Create();
63 }
64#endif
65#if TESTER_ENABLE_VULKAN
66 if (settings.enable_impeller &&
67 (!settings.requested_rendering_backend.has_value() ||
68 settings.requested_rendering_backend == "vulkan")) {
69 tester_context =
71 }
72#endif
73 return tester_context;
74}
75} // namespace
76
77static constexpr int64_t kImplicitViewId = 0ll;
78
79static void ConfigureShell(Shell* shell) {
80 auto device_pixel_ratio = 3.0;
81 auto physical_width = 2400.0; // 800 at 3x resolution.
82 auto physical_height = 1800.0; // 600 at 3x resolution.
83
84 std::vector<std::unique_ptr<Display>> displays;
85 displays.push_back(std::make_unique<Display>(
86 0, 60, physical_width, physical_height, device_pixel_ratio));
87 shell->OnDisplayUpdates(std::move(displays));
88
90 metrics.device_pixel_ratio = device_pixel_ratio;
91 metrics.physical_width = physical_width;
92 metrics.physical_height = physical_height;
93 metrics.display_id = 0;
94 metrics.physical_min_width_constraint = physical_width;
95 metrics.physical_max_width_constraint = physical_width;
96 metrics.physical_min_height_constraint = physical_height;
97 metrics.physical_max_height_constraint = physical_height;
98 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId, metrics);
99}
100
102 // |ExternalViewEmbedder|
103 DlCanvas* GetRootCanvas() override { return nullptr; }
104
105 // |ExternalViewEmbedder|
106 void CancelFrame() override {}
107
108 // |ExternalViewEmbedder|
109 void BeginFrame(GrDirectContext* context,
111 raster_thread_merger) override {}
112
113 // |ExternalViewEmbedder|
114 void PrepareFlutterView(DlISize frame_size,
115 double device_pixel_ratio) override {}
116
117 // |ExternalViewEmbedder|
118 void PrerollCompositeEmbeddedView(
119 int64_t view_id,
120 std::unique_ptr<EmbeddedViewParams> params) override {}
121
122 // |ExternalViewEmbedder|
123 DlCanvas* CompositeEmbeddedView(int64_t view_id) override {
124 return &builder_;
125 }
126
127 private:
128 DisplayListBuilder builder_;
129};
130
132 public:
134 bool render_to_surface)
135 : GPUSurfaceSoftware(delegate, render_to_surface) {}
136
137 bool EnableRasterCache() const override { return false; }
138};
139
142 public:
144 const TaskRunners& task_runners,
145 std::unique_ptr<TesterContext> tester_context)
146 : PlatformView(delegate, task_runners),
147 tester_context_(std::move(tester_context)) {}
148
150 // TesterContext destructor handles shutdown
151 }
152
153 // |PlatformView|
154 std::shared_ptr<impeller::Context> GetImpellerContext() const override {
155 if (tester_context_) {
156 return tester_context_->GetImpellerContext();
157 }
158 return nullptr;
159 }
160
161 // |PlatformView|
162 std::unique_ptr<Surface> CreateRenderingSurface() override {
163 if (tester_context_ &&
165 return tester_context_->CreateRenderingSurface();
166 }
167 auto surface = std::make_unique<TesterGPUSurfaceSoftware>(
168 this, true /* render to surface */);
169 FML_DCHECK(surface->IsValid());
170 return surface;
171 }
172
173 // |GPUSurfaceSoftwareDelegate|
174 sk_sp<SkSurface> AcquireBackingStore(const DlISize& size) override {
175 if (sk_surface_ != nullptr && //
176 sk_surface_->width() == size.width &&
177 sk_surface_->height() == size.height) {
178 // The old and new surface sizes are the same. Nothing to do here.
179 return sk_surface_;
180 }
181
182 SkImageInfo info = SkImageInfo::MakeN32(
183 size.width, size.height, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
184 sk_surface_ = SkSurfaces::Raster(info, nullptr);
185
186 if (sk_surface_ == nullptr) {
187 FML_LOG(ERROR)
188 << "Could not create backing store for software rendering.";
189 return nullptr;
190 }
191
192 return sk_surface_;
193 }
194
195 // |GPUSurfaceSoftwareDelegate|
196 bool PresentBackingStore(sk_sp<SkSurface> backing_store) override {
197 return true;
198 }
199
200 // |PlatformView|
201 std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder() override {
202 return external_view_embedder_;
203 }
204
205 private:
206 sk_sp<SkSurface> sk_surface_ = nullptr;
207
208 std::shared_ptr<TesterContext> tester_context_;
209 std::shared_ptr<TesterExternalViewEmbedder> external_view_embedder_ =
210 std::make_shared<TesterExternalViewEmbedder>();
211};
212
213// Checks whether the engine's main Dart isolate has no pending work. If so,
214// then exit the given message loop.
216 public:
218 fml::RefPtr<fml::TaskRunner> main_task_runner,
219 fml::RefPtr<fml::TaskRunner> ui_task_runner,
220 bool run_forever)
221 : shell_(shell),
222 main_task_runner_(std::move(main_task_runner)),
223 ui_task_runner_(std::move(ui_task_runner)),
224 run_forever_(run_forever) {}
225
227 return static_cast<int>(last_error_.value_or(DartErrorCode::NoError));
228 }
229
231 last_error_ = shell_.GetUIIsolateLastError();
232 if (shell_.EngineHasLivePorts()) {
233 // The UI isolate still has live ports and is running. Nothing to do
234 // just yet.
235 return;
236 }
237 if (shell_.EngineHasPendingMicrotasks()) {
238 // Post an empty task to force a run of the engine task observer that
239 // drains the microtask queue.
240 ui_task_runner_->PostTask([] {});
241 return;
242 }
243
244 if (run_forever_) {
245 // We need this script to run forever. We have already recorded the last
246 // error. Keep going.
247 return;
248 }
249
250 if (!has_terminated_) {
251 // Only try to terminate the loop once.
252 has_terminated_ = true;
253 fml::TaskRunner::RunNowOrPostTask(main_task_runner_, []() {
255 });
256 }
257 }
258
259 private:
260 Shell& shell_;
261 fml::RefPtr<fml::TaskRunner> main_task_runner_;
262 fml::RefPtr<fml::TaskRunner> ui_task_runner_;
263 bool run_forever_ = false;
264 std::optional<DartErrorCode> last_error_;
265 bool has_terminated_ = false;
266
268};
269
270// Processes spawned via dart:io inherit their signal handling from the parent
271// process. As part of spawning, the spawner blocks signals temporarily, so we
272// need to explicitly unblock the signals we care about in the new process. In
273// particular, we need to unblock SIGPROF for CPU profiling to work on the
274// mutator thread in the main isolate in this process (threads spawned by the VM
275// know about this limitation and automatically have this signal unblocked).
276static void UnblockSIGPROF() {
277#if defined(FML_OS_POSIX)
278 sigset_t set;
279 sigemptyset(&set);
280 sigaddset(&set, SIGPROF);
281 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
282#endif // defined(FML_OS_POSIX)
283}
284
285int RunTester(const flutter::Settings& settings,
286 bool run_forever,
287 bool multithreaded) {
288 const auto thread_label = "io.flutter.test.";
289
290 // Necessary if we want to use the CPU profiler on the main isolate's mutator
291 // thread.
292 //
293 // OSX WARNING: avoid spawning additional threads before this call due to a
294 // kernel bug that may enable SIGPROF on an unintended thread in the process.
296
298
299 auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
300
301 std::unique_ptr<ThreadHost> threadhost;
302 fml::RefPtr<fml::TaskRunner> platform_task_runner;
303 fml::RefPtr<fml::TaskRunner> raster_task_runner;
304 fml::RefPtr<fml::TaskRunner> ui_task_runner;
305 fml::RefPtr<fml::TaskRunner> io_task_runner;
306
307 if (multithreaded) {
308 threadhost = std::make_unique<ThreadHost>(
311 platform_task_runner = current_task_runner;
312 raster_task_runner = threadhost->raster_thread->GetTaskRunner();
313 ui_task_runner = threadhost->ui_thread->GetTaskRunner();
314 io_task_runner = threadhost->io_thread->GetTaskRunner();
315 } else {
316 platform_task_runner = raster_task_runner = ui_task_runner =
317 io_task_runner = current_task_runner;
318 }
319
320 const flutter::TaskRunners task_runners(thread_label, // dart thread label
321 platform_task_runner, // platform
322 raster_task_runner, // raster
323 ui_task_runner, // ui
324 io_task_runner // io
325 );
326
327 std::unique_ptr<TesterContext> tester_context = CreateTesterContext(settings);
328 if (settings.enable_impeller && !tester_context) {
329 FML_LOG(ERROR) << "Could not create tester context.";
330 return EXIT_FAILURE;
331 }
332
333 Shell::CreateCallback<PlatformView> on_create_platform_view =
335 [tester_context = std::move(tester_context)](Shell& shell) mutable {
336 return std::make_unique<TesterPlatformView>(
337 shell, shell.GetTaskRunners(), std::move(tester_context));
338 });
339
340 Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
341 return std::make_unique<Rasterizer>(
343 };
344
346 task_runners, //
347 settings, //
348 on_create_platform_view, //
349 on_create_rasterizer //
350 )
351 .release());
352 auto shell = g_shell->get();
353
354 if (!shell || !shell->IsSetup()) {
355 FML_LOG(ERROR) << "Could not set up the shell.";
356 return EXIT_FAILURE;
357 }
358
359 if (settings.application_kernel_asset.empty()) {
360 FML_LOG(ERROR) << "Dart kernel file not specified.";
361 return EXIT_FAILURE;
362 }
363
364 shell->GetPlatformView()->NotifyCreated();
365
366 // Initialize default testing locales. There is no platform to
367 // pass locales on the tester, so to retain expected locale behavior,
368 // we emulate it in here by passing in 'en_US' and 'zh_CN' as test locales.
369 const char* locale_json =
370 "{\"method\":\"setLocale\",\"args\":[\"en\",\"US\",\"\",\"\",\"zh\","
371 "\"CN\",\"\",\"\"]}";
372 auto locale_bytes = fml::MallocMapping::Copy(
373 locale_json, locale_json + std::strlen(locale_json));
375 shell->GetPlatformView()->DispatchPlatformMessage(
376 std::make_unique<flutter::PlatformMessage>(
377 "flutter/localization", std::move(locale_bytes), response));
378
379 std::initializer_list<fml::FileMapping::Protection> protection = {
381 auto main_dart_file_mapping = std::make_unique<fml::FileMapping>(
385 protection);
386
387 auto isolate_configuration =
388 IsolateConfiguration::CreateForKernel(std::move(main_dart_file_mapping));
389
390 if (!isolate_configuration) {
391 FML_LOG(ERROR) << "Could create isolate configuration.";
392 return EXIT_FAILURE;
393 }
394
395 auto asset_manager = std::make_shared<flutter::AssetManager>();
396 asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
397 fml::Duplicate(settings.assets_dir), true));
398 asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
399 fml::OpenDirectory(settings.assets_path.c_str(), false,
401 true));
402
403 RunConfiguration run_configuration(std::move(isolate_configuration),
404 std::move(asset_manager));
405
406 // The script completion task observer that will be installed on the UI thread
407 // that watched if the engine has any live ports.
408 ScriptCompletionTaskObserver completion_observer(
409 *shell, // a valid shell
411 .GetTaskRunner(), // the message loop to terminate
412 ui_task_runner, // runner for Dart microtasks
413 run_forever // should the exit be ignored
414 );
415
416 bool engine_did_run = false;
417
419 auto task_observer_add = [&completion_observer]() {
421 reinterpret_cast<intptr_t>(&completion_observer),
422 [&completion_observer]() { completion_observer.DidProcessTask(); });
423 };
424
425 auto task_observer_remove = [&completion_observer, &latch]() {
427 reinterpret_cast<intptr_t>(&completion_observer));
428 latch.Signal();
429 };
430
431 shell->RunEngine(std::move(run_configuration),
432 [&engine_did_run, &ui_task_runner,
433 &task_observer_add](Engine::RunStatus run_status) mutable {
434 if (run_status != flutter::Engine::RunStatus::Failure) {
435 engine_did_run = true;
436 // Now that our engine is initialized we can install the
437 // ScriptCompletionTaskObserver
439 task_observer_add);
440 }
441 });
442
443 ConfigureShell(shell);
444
445 // Run the message loop and wait for the script to do its thing.
447
448 // Cleanup the completion observer synchronously as it is living on the
449 // stack.
450 fml::TaskRunner::RunNowOrPostTask(ui_task_runner, task_observer_remove);
451 latch.Wait();
452
453 delete g_shell->release();
454
455 if (!engine_did_run) {
456 // If the engine itself didn't have a chance to run, there is no point in
457 // asking it if there was an error. Signal a failure unconditionally.
458 return EXIT_FAILURE;
459 }
460
461 return completion_observer.GetExitCodeForLastError();
462}
463
464#ifdef _WIN32
465#define EXPORTED __declspec(dllexport)
466#else
467#define EXPORTED __attribute__((visibility("default")))
468#endif
469
470extern "C" {
471EXPORTED Dart_Handle LoadLibraryFromKernel(const char* path) {
472 std::shared_ptr<fml::FileMapping> mapping =
474 if (!mapping) {
475 return Dart_Null();
476 }
478}
479
480EXPORTED Dart_Handle LookupEntryPoint(const char* uri, const char* name) {
481 if (!uri || !name) {
482 return Dart_Null();
483 }
484 Dart_Handle lib = Dart_LookupLibrary(Dart_NewStringFromCString(uri));
485 if (Dart_IsError(lib)) {
486 return lib;
487 }
488 return Dart_GetField(lib, Dart_NewStringFromCString(name));
489}
490
491EXPORTED void Spawn(const char* entrypoint, const char* route) {
492 auto shell = g_shell->get();
493 auto isolate = Dart_CurrentIsolate();
494 auto spawn_task = [shell, entrypoint = std::string(entrypoint),
495 route = std::string(route)]() {
496 auto configuration = RunConfiguration::InferFromSettings(
497 shell->GetSettings(), /*io_worker=*/nullptr,
498 /*launch_type=*/IsolateLaunchType::kExistingGroup);
499 configuration.SetEntrypoint(entrypoint);
500
501 Shell::CreateCallback<PlatformView> on_create_platform_view =
502 fml::MakeCopyable([](Shell& shell) mutable {
503 std::unique_ptr<TesterContext> tester_context =
504 CreateTesterContext(shell.GetSettings());
505 return std::make_unique<TesterPlatformView>(
506 shell, shell.GetTaskRunners(), std::move(tester_context));
507 });
508
509 Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
510 return std::make_unique<Rasterizer>(
512 };
513
514 // Spawn a shell, and keep it running until it has no live ports, then
515 // delete it on the platform thread.
516 auto spawned_shell =
517 shell
518 ->Spawn(std::move(configuration), route, on_create_platform_view,
519 on_create_rasterizer)
520 .release();
521
522 ConfigureShell(spawned_shell);
523
525 spawned_shell->GetTaskRunners().GetUITaskRunner(), [spawned_shell]() {
526 fml::MessageLoop::GetCurrent().AddTaskObserver(
527 reinterpret_cast<intptr_t>(spawned_shell), [spawned_shell]() {
528 if (spawned_shell->EngineHasLivePorts()) {
529 return;
530 }
531
532 fml::MessageLoop::GetCurrent().RemoveTaskObserver(
533 reinterpret_cast<intptr_t>(spawned_shell));
534 // Shell must be deleted on the platform task runner.
535 fml::TaskRunner::RunNowOrPostTask(
536 spawned_shell->GetTaskRunners().GetPlatformTaskRunner(),
537 [spawned_shell]() { delete spawned_shell; });
538 });
539 });
540 };
541 Dart_ExitIsolate();
542 // The global shell pointer is never deleted, short of application exit.
543 // This UI task runner cannot be latched because it will block spawning a new
544 // shell in the case where flutter_tester is running multithreaded.
546 shell->GetTaskRunners().GetPlatformTaskRunner(), spawn_task);
547
548 Dart_EnterIsolate(isolate);
549}
550
552 // Enable Isolate.exit().
553 FML_DCHECK(Dart_CurrentIsolate() != nullptr);
554 Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
556 Dart_Handle isolate_type = Dart_GetNonNullableType(
557 isolate_lib, tonic::ToDart("Isolate"), 0, nullptr);
559 Dart_Handle result =
560 Dart_SetField(isolate_type, tonic::ToDart("_mayExit"), Dart_True());
562}
563}
564
565} // namespace flutter
566
567int main(int argc, char* argv[]) {
568 dart::bin::SetExecutableName(argv[0]);
569 dart::bin::SetExecutableArguments(argc - 1, argv);
570
571 auto command_line = fml::CommandLineFromPlatformOrArgcArgv(argc, argv);
572
573 if (command_line.HasOption(flutter::FlagForSwitch(flutter::Switch::Help))) {
574 flutter::PrintUsage("flutter_tester");
575 return EXIT_SUCCESS;
576 }
577
578 auto settings = flutter::SettingsFromCommandLine(command_line);
579 if (!command_line.positional_args().empty()) {
580 // The tester may not use the switch for the main dart file path. Specifying
581 // it as a positional argument instead.
582 settings.application_kernel_asset = command_line.positional_args()[0];
583 }
584
585 if (settings.application_kernel_asset.empty()) {
586 FML_LOG(ERROR) << "Dart kernel file not specified.";
587 return EXIT_FAILURE;
588 }
589
590 settings.leak_vm = false;
591 settings.enable_platform_isolates = true;
592
593 if (settings.icu_data_path.empty()) {
594 settings.icu_data_path = "icudtl.dat";
595 }
596
597 // The tools that read logs get confused if there is a log tag specified.
598 settings.log_tag = "";
599
600 settings.log_message_callback = [](const std::string& tag,
601 const std::string& message) {
602 if (!tag.empty()) {
603 std::cout << tag << ": ";
604 }
605 std::cout << message << std::endl;
606 };
607
608 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
611 callback);
612 return queue_id;
613 };
614
615 settings.task_observer_remove = [](fml::TaskQueueId queue_id, intptr_t key) {
617 key);
618 };
619
620 settings.unhandled_exception_callback = [](const std::string& error,
621 const std::string& stack_trace) {
622 FML_LOG(ERROR) << "Unhandled exception" << std::endl
623 << "Exception: " << error << std::endl
624 << "Stack trace: " << stack_trace;
625 ::exit(1);
626 return true;
627 };
628
629#if defined(FML_OS_WIN)
630 CoInitializeEx(nullptr, COINIT_MULTITHREADED);
631#endif // defined(FML_OS_WIN)
632
633 return flutter::RunTester(settings,
634 command_line.HasOption(flutter::FlagForSwitch(
635 flutter::Switch::RunForever)),
636 command_line.HasOption(flutter::FlagForSwitch(
637 flutter::Switch::ForceMultithreading)));
638}
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:32
RunStatus
Indicates the result of the call to Engine::Run.
Definition engine.h:74
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, fml::RefPtr< fml::TaskRunner > ui_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:797
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:222
bool EngineHasLivePorts() const
Used by embedders to check if the Engine is running and has any live ports remaining....
Definition shell.cc:817
void RunEngine(RunConfiguration run_configuration)
Starts an isolate for the given RunConfiguration.
Definition shell.cc:759
std::unique_ptr< Shell > Spawn(RunConfiguration run_configuration, const std::string &initial_route, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer) const
Creates one Shell from another Shell where the created Shell takes the opportunity to share any inter...
Definition shell.cc:677
bool EngineHasPendingMicrotasks() const
Used by embedders to check if the Engine is running and has any microtasks that have been queued but ...
Definition shell.cc:828
const Settings & GetSettings() const override
Definition shell.cc:912
void OnDisplayUpdates(std::vector< std::unique_ptr< Display > > displays)
Notifies the display manager of the updates.
Definition shell.cc:2419
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
Definition shell.cc:916
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition shell.h:121
bool IsSetup() const
Used by embedders to check if all shell subcomponents are initialized. It is the embedder's responsib...
Definition shell.cc:839
fml::WeakPtr< PlatformView > GetPlatformView()
Platform views may only be accessed on the platform task runner.
Definition shell.cc:935
static std::unique_ptr< TesterContext > Create()
static std::unique_ptr< TesterContext > Create()
static std::unique_ptr< TesterContext > Create(bool enable_validation)
bool EnableRasterCache() const override
TesterGPUSurfaceSoftware(GPUSurfaceSoftwareDelegate *delegate, bool render_to_surface)
std::shared_ptr< ExternalViewEmbedder > CreateExternalViewEmbedder() override
sk_sp< SkSurface > AcquireBackingStore(const DlISize &size) override
Called when the GPU surface needs a new buffer to render a new frame into.
TesterPlatformView(Delegate &delegate, const TaskRunners &task_runners, std::unique_ptr< TesterContext > tester_context)
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...
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 TaskQueueId GetCurrentTaskQueueId()
static MessageLoopTaskQueues * GetInstance()
void AddTaskObserver(TaskQueueId queue_id, intptr_t key, const fml::closure &callback)
void RemoveTaskObserver(TaskQueueId queue_id, intptr_t key)
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
virtual void PostTask(const fml::closure &task) override
const EmbeddedViewParams * params
VkSurfaceKHR surface
Definition main.cc:65
const char * message
const uint8_t uint32_t uint32_t GError ** error
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_DCHECK(condition)
Definition logging.h:122
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
char ** argv
Definition library.h:9
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)
void PrintUsage(const std::string &executable_name)
Definition switches.cc:89
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all 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
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 switch_defs.h:52
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
constexpr FlutterViewId kImplicitViewId
EXPORTED void ForceShutdownIsolate()
static void ConfigureShell(Shell *shell)
static absl::NoDestructor< std::unique_ptr< Shell > > g_shell
Settings SettingsFromCommandLine(const fml::CommandLine &command_line, bool require_merged_platform_ui_thread)
Definition switches.cc:230
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 switch_defs.h:71
EXPORTED void Spawn(const char *entrypoint, const char *route)
EXPORTED Dart_Handle LoadLibraryFromKernel(const char *path)
const std::string_view FlagForSwitch(Switch swtch)
Definition switches.cc:146
std::string AbsolutePath(const std::string &path)
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
Definition ref_ptr.h:261
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
std::vector< FlutterEngineDisplay > * displays
std::string application_kernel_asset
Definition settings.h:140
fml::UniqueFD::element_type assets_dir
Definition settings.h:331
std::string assets_path
Definition settings.h:333
bool enable_vulkan_validation
Definition settings.h:252
std::optional< std::string > requested_rendering_backend
Definition settings.h:248
int main(int argc, char *argv[])
#define EXPORTED