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