Flutter Engine
The Flutter Engine
embedder.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#define RAPIDJSON_HAS_STDSTRING 1
7
8#include <cstring>
9#include <iostream>
10#include <memory>
11#include <set>
12#include <string>
13#include <vector>
14
15#include "flutter/fml/build_config.h"
16#include "flutter/fml/closure.h"
17#include "flutter/fml/make_copyable.h"
18#include "flutter/fml/native_library.h"
19#include "flutter/fml/thread.h"
20#include "third_party/dart/runtime/bin/elf_loader.h"
21#include "third_party/dart/runtime/include/dart_native_api.h"
26
27#if !defined(FLUTTER_NO_EXPORT)
28#if FML_OS_WIN
29#define FLUTTER_EXPORT __declspec(dllexport)
30#else // FML_OS_WIN
31#define FLUTTER_EXPORT __attribute__((visibility("default")))
32#endif // FML_OS_WIN
33#endif // !FLUTTER_NO_EXPORT
34
35extern "C" {
36#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
37// Used for debugging dart:* sources.
38extern const uint8_t kPlatformStrongDill[];
39extern const intptr_t kPlatformStrongDillSize;
40#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
41}
42
43#include "flutter/assets/directory_asset_bundle.h"
44#include "flutter/common/graphics/persistent_cache.h"
45#include "flutter/common/task_runners.h"
46#include "flutter/fml/command_line.h"
47#include "flutter/fml/file.h"
48#include "flutter/fml/make_copyable.h"
49#include "flutter/fml/message_loop.h"
50#include "flutter/fml/paths.h"
51#include "flutter/fml/trace_event.h"
52#include "flutter/shell/common/rasterizer.h"
53#include "flutter/shell/common/switches.h"
54#include "flutter/shell/platform/embedder/embedder.h"
55#include "flutter/shell/platform/embedder/embedder_engine.h"
56#include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h"
57#include "flutter/shell/platform/embedder/embedder_platform_message_response.h"
58#include "flutter/shell/platform/embedder/embedder_render_target.h"
59#include "flutter/shell/platform/embedder/embedder_render_target_skia.h"
60#include "flutter/shell/platform/embedder/embedder_semantics_update.h"
61#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
62#include "flutter/shell/platform/embedder/embedder_task_runner.h"
63#include "flutter/shell/platform/embedder/embedder_thread_host.h"
64#include "flutter/shell/platform/embedder/pixel_formats.h"
65#include "flutter/shell/platform/embedder/platform_view_embedder.h"
66#include "rapidjson/rapidjson.h"
67#include "rapidjson/writer.h"
68
69// Note: the IMPELLER_SUPPORTS_RENDERING may be defined even when the
70// embedder/BUILD.gn variable impeller_supports_rendering is disabled.
71#ifdef SHELL_ENABLE_GL
72#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
75#ifdef IMPELLER_SUPPORTS_RENDERING
76#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" // nogncheck
77#include "flutter/shell/platform/embedder/embedder_surface_gl_impeller.h" // nogncheck
78#include "flutter/shell/platform/embedder/embedder_surface_gl_skia.h" // nogncheck
79#include "impeller/core/texture.h" // nogncheck
82#include "impeller/renderer/context.h" // nogncheck
83#include "impeller/renderer/render_target.h" // nogncheck
84#endif // IMPELLER_SUPPORTS_RENDERING
85#endif // SHELL_ENABLE_GL
86
87#ifdef SHELL_ENABLE_METAL
88#include "flutter/shell/platform/embedder/embedder_surface_metal_skia.h"
92#ifdef IMPELLER_SUPPORTS_RENDERING
93#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" // nogncheck
94#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" // nogncheck
95#include "impeller/core/texture.h" // nogncheck
97#include "impeller/renderer/render_target.h" // nogncheck
98#endif // IMPELLER_SUPPORTS_RENDERING
99#endif // SHELL_ENABLE_METAL
100
101#ifdef SHELL_ENABLE_VULKAN
103#endif // SHELL_ENABLE_VULKAN
104
107
109
110// A message channel to send platform-independent FlutterKeyData to the
111// framework.
112//
113// This should be kept in sync with the following variables:
114//
115// - lib/ui/platform_dispatcher.dart, _kFlutterKeyDataChannel
116// - shell/platform/darwin/ios/framework/Source/FlutterEngine.mm,
117// FlutterKeyDataChannel
118// - io/flutter/embedding/android/KeyData.java,
119// CHANNEL
120//
121// Not to be confused with "flutter/keyevent", which is used to send raw
122// key event data in a platform-dependent format.
123//
124// ## Format
125//
126// Send: KeyDataPacket.data().
127//
128// Expected reply: Whether the event is handled. Exactly 1 byte long, with value
129// 1 for handled, and 0 for not. Malformed value is considered false.
130const char* kFlutterKeyDataChannel = "flutter/keydata";
131
133 const char* reason,
134 const char* code_name,
135 const char* function,
136 const char* file,
137 int line) {
138#if FML_OS_WIN
139 constexpr char kSeparator = '\\';
140#else
141 constexpr char kSeparator = '/';
142#endif
143 const auto file_base =
144 (::strrchr(file, kSeparator) ? strrchr(file, kSeparator) + 1 : file);
145 char error[256] = {};
146 snprintf(error, (sizeof(error) / sizeof(char)),
147 "%s (%d): '%s' returned '%s'. %s", file_base, line, function,
148 code_name, reason);
149 std::cerr << error << std::endl;
150 return code;
151}
152
153#define LOG_EMBEDDER_ERROR(code, reason) \
154 LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)
155
157 if (config->type != kOpenGL) {
158 return false;
159 }
160
161 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
162
163 if (!SAFE_EXISTS(open_gl_config, make_current) ||
164 !SAFE_EXISTS(open_gl_config, clear_current) ||
165 !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback,
166 fbo_with_frame_info_callback) ||
167 !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) {
168 return false;
169 }
170
171 return true;
172}
173
175 if (config->type != kSoftware) {
176 return false;
177 }
178
179 const FlutterSoftwareRendererConfig* software_config = &config->software;
180
181 if (SAFE_ACCESS(software_config, surface_present_callback, nullptr) ==
182 nullptr) {
183 return false;
184 }
185
186 return true;
187}
188
190 if (config->type != kMetal) {
191 return false;
192 }
193
194 const FlutterMetalRendererConfig* metal_config = &config->metal;
195
196 bool device = SAFE_ACCESS(metal_config, device, nullptr);
197 bool command_queue =
198 SAFE_ACCESS(metal_config, present_command_queue, nullptr);
199
200 bool present = SAFE_ACCESS(metal_config, present_drawable_callback, nullptr);
201 bool get_texture =
202 SAFE_ACCESS(metal_config, get_next_drawable_callback, nullptr);
203
204 return device && command_queue && present && get_texture;
205}
206
208 if (config->type != kVulkan) {
209 return false;
210 }
211
212 const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan;
213
214 if (!SAFE_EXISTS(vulkan_config, instance) ||
215 !SAFE_EXISTS(vulkan_config, physical_device) ||
216 !SAFE_EXISTS(vulkan_config, device) ||
217 !SAFE_EXISTS(vulkan_config, queue) ||
218 !SAFE_EXISTS(vulkan_config, get_instance_proc_address_callback) ||
219 !SAFE_EXISTS(vulkan_config, get_next_image_callback) ||
220 !SAFE_EXISTS(vulkan_config, present_image_callback)) {
221 return false;
222 }
223
224 return true;
225}
226
227static bool IsRendererValid(const FlutterRendererConfig* config) {
228 if (config == nullptr) {
229 return false;
230 }
231
232 switch (config->type) {
233 case kOpenGL:
234 return IsOpenGLRendererConfigValid(config);
235 case kSoftware:
236 return IsSoftwareRendererConfigValid(config);
237 case kMetal:
238 return IsMetalRendererConfigValid(config);
239 case kVulkan:
240 return IsVulkanRendererConfigValid(config);
241 default:
242 return false;
243 }
244
245 return false;
246}
247
248#if FML_OS_LINUX || FML_OS_WIN
249static void* DefaultGLProcResolver(const char* name) {
250 static fml::RefPtr<fml::NativeLibrary> proc_library =
251#if FML_OS_LINUX
253#elif FML_OS_WIN // FML_OS_LINUX
254 fml::NativeLibrary::Create("opengl32.dll");
255#endif // FML_OS_WIN
256 return static_cast<void*>(
257 const_cast<uint8_t*>(proc_library->ResolveSymbol(name)));
258}
259#endif // FML_OS_LINUX || FML_OS_WIN
260
261#ifdef SHELL_ENABLE_GL
262// Auxiliary function used to translate rectangles of type SkIRect to
263// FlutterRect.
264static FlutterRect SkIRectToFlutterRect(const SkIRect sk_rect) {
265 FlutterRect flutter_rect = {static_cast<double>(sk_rect.fLeft),
266 static_cast<double>(sk_rect.fTop),
267 static_cast<double>(sk_rect.fRight),
268 static_cast<double>(sk_rect.fBottom)};
269 return flutter_rect;
270}
271
272// Auxiliary function used to translate rectangles of type FlutterRect to
273// SkIRect.
274static const SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) {
275 SkIRect rect = {static_cast<int32_t>(flutter_rect.left),
276 static_cast<int32_t>(flutter_rect.top),
277 static_cast<int32_t>(flutter_rect.right),
278 static_cast<int32_t>(flutter_rect.bottom)};
279 return rect;
280}
281#endif
282
285 const FlutterRendererConfig* config,
286 void* user_data,
288 platform_dispatch_table,
289 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
290 external_view_embedder,
291 bool enable_impeller) {
292#ifdef SHELL_ENABLE_GL
293 if (config->type != kOpenGL) {
294 return nullptr;
295 }
296
297 auto gl_make_current = [ptr = config->open_gl.make_current,
298 user_data]() -> bool { return ptr(user_data); };
299
300 auto gl_clear_current = [ptr = config->open_gl.clear_current,
301 user_data]() -> bool { return ptr(user_data); };
302
303 auto gl_present =
304 [present = config->open_gl.present,
305 present_with_info = config->open_gl.present_with_info,
306 user_data](flutter::GLPresentInfo gl_present_info) -> bool {
307 if (present) {
308 return present(user_data);
309 } else {
310 // Format the frame and buffer damages accordingly. Note that, since the
311 // current compute damage algorithm only returns one rectangle for damage
312 // we are assuming the number of rectangles provided in frame and buffer
313 // damage are always 1. Once the function that computes damage implements
314 // support for multiple damage rectangles, GLPresentInfo should also
315 // contain the number of damage rectangles.
316
317 std::optional<FlutterRect> frame_damage_rect;
318 if (gl_present_info.frame_damage) {
319 frame_damage_rect =
320 SkIRectToFlutterRect(*(gl_present_info.frame_damage));
321 }
322 std::optional<FlutterRect> buffer_damage_rect;
323 if (gl_present_info.buffer_damage) {
324 buffer_damage_rect =
325 SkIRectToFlutterRect(*(gl_present_info.buffer_damage));
326 }
327
328 FlutterDamage frame_damage{
329 .struct_size = sizeof(FlutterDamage),
330 .num_rects = frame_damage_rect ? size_t{1} : size_t{0},
331 .damage = frame_damage_rect ? &frame_damage_rect.value() : nullptr,
332 };
333 FlutterDamage buffer_damage{
334 .struct_size = sizeof(FlutterDamage),
335 .num_rects = buffer_damage_rect ? size_t{1} : size_t{0},
336 .damage = buffer_damage_rect ? &buffer_damage_rect.value() : nullptr,
337 };
338
339 // Construct the present information concerning the frame being rendered.
340 FlutterPresentInfo present_info = {
342 .fbo_id = gl_present_info.fbo_id,
343 .frame_damage = frame_damage,
344 .buffer_damage = buffer_damage,
345 };
346
347 return present_with_info(user_data, &present_info);
348 }
349 };
350
351 auto gl_fbo_callback =
352 [fbo_callback = config->open_gl.fbo_callback,
353 fbo_with_frame_info_callback =
355 user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
356 if (fbo_callback) {
357 return fbo_callback(user_data);
358 } else {
359 FlutterFrameInfo frame_info = {};
360 frame_info.struct_size = sizeof(FlutterFrameInfo);
361 frame_info.size = {gl_frame_info.width, gl_frame_info.height};
362 return fbo_with_frame_info_callback(user_data, &frame_info);
363 }
364 };
365
366 auto gl_populate_existing_damage =
367 [populate_existing_damage = config->open_gl.populate_existing_damage,
368 user_data](intptr_t id) -> flutter::GLFBOInfo {
369 // If no populate_existing_damage was provided, disable partial
370 // repaint.
371 if (!populate_existing_damage) {
372 return flutter::GLFBOInfo{
373 .fbo_id = static_cast<uint32_t>(id),
374 .existing_damage = std::nullopt,
375 };
376 }
377
378 // Given the FBO's ID, get its existing damage.
379 FlutterDamage existing_damage;
380 populate_existing_damage(user_data, id, &existing_damage);
381
382 std::optional<SkIRect> existing_damage_rect = std::nullopt;
383
384 // Verify that at least one damage rectangle was provided.
385 if (existing_damage.num_rects <= 0 || existing_damage.damage == nullptr) {
386 FML_LOG(INFO) << "No damage was provided. Forcing full repaint.";
387 } else {
388 existing_damage_rect = SkIRect::MakeEmpty();
389 for (size_t i = 0; i < existing_damage.num_rects; i++) {
390 existing_damage_rect->join(
391 FlutterRectToSkIRect(existing_damage.damage[i]));
392 }
393 }
394
395 // Pass the information about this FBO to the rendering backend.
396 return flutter::GLFBOInfo{
397 .fbo_id = static_cast<uint32_t>(id),
398 .existing_damage = existing_damage_rect,
399 };
400 };
401
402 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
403 std::function<bool()> gl_make_resource_current_callback = nullptr;
404 if (SAFE_ACCESS(open_gl_config, make_resource_current, nullptr) != nullptr) {
405 gl_make_resource_current_callback =
406 [ptr = config->open_gl.make_resource_current, user_data]() {
407 return ptr(user_data);
408 };
409 }
410
411 std::function<SkMatrix(void)> gl_surface_transformation_callback = nullptr;
412 if (SAFE_ACCESS(open_gl_config, surface_transformation, nullptr) != nullptr) {
413 gl_surface_transformation_callback =
414 [ptr = config->open_gl.surface_transformation, user_data]() {
415 FlutterTransformation transformation = ptr(user_data);
416 return SkMatrix::MakeAll(transformation.scaleX, //
417 transformation.skewX, //
418 transformation.transX, //
419 transformation.skewY, //
420 transformation.scaleY, //
421 transformation.transY, //
422 transformation.pers0, //
423 transformation.pers1, //
424 transformation.pers2 //
425 );
426 };
427
428 // If there is an external view embedder, ask it to apply the surface
429 // transformation to its surfaces as well.
430 if (external_view_embedder) {
431 external_view_embedder->SetSurfaceTransformationCallback(
432 gl_surface_transformation_callback);
433 }
434 }
435
436 flutter::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr;
437 if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) {
438 gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver,
439 user_data](const char* gl_proc_name) {
440 return ptr(user_data, gl_proc_name);
441 };
442 } else {
443#if FML_OS_LINUX || FML_OS_WIN
444 gl_proc_resolver = DefaultGLProcResolver;
445#endif
446 }
447
448 bool fbo_reset_after_present =
449 SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false);
450
452 gl_make_current, // gl_make_current_callback
453 gl_clear_current, // gl_clear_current_callback
454 gl_present, // gl_present_callback
455 gl_fbo_callback, // gl_fbo_callback
456 gl_make_resource_current_callback, // gl_make_resource_current_callback
457 gl_surface_transformation_callback, // gl_surface_transformation_callback
458 gl_proc_resolver, // gl_proc_resolver
459 gl_populate_existing_damage, // gl_populate_existing_damage
460 };
461
462 return fml::MakeCopyable(
463 [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table,
464 enable_impeller,
465 external_view_embedder =
466 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
467 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
468 std::move(external_view_embedder);
469 if (enable_impeller) {
470 return std::make_unique<flutter::PlatformViewEmbedder>(
471 shell, // delegate
472 shell.GetTaskRunners(), // task runners
473 std::make_unique<flutter::EmbedderSurfaceGLImpeller>(
474 gl_dispatch_table, fbo_reset_after_present,
475 view_embedder), // embedder_surface
476 platform_dispatch_table, // embedder platform dispatch table
477 view_embedder // external view embedder
478 );
479 }
480 return std::make_unique<flutter::PlatformViewEmbedder>(
481 shell, // delegate
482 shell.GetTaskRunners(), // task runners
483 std::make_unique<flutter::EmbedderSurfaceGLSkia>(
484 gl_dispatch_table, fbo_reset_after_present,
485 view_embedder), // embedder_surface
486 platform_dispatch_table, // embedder platform dispatch table
487 view_embedder // external view embedder
488 );
489 });
490#else
491 return nullptr;
492#endif
493}
494
497 const FlutterRendererConfig* config,
498 void* user_data,
500 platform_dispatch_table,
501 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
502 external_view_embedder,
503 bool enable_impeller) {
504 if (config->type != kMetal) {
505 return nullptr;
506 }
507
508#ifdef SHELL_ENABLE_METAL
510 [ptr = config->metal.present_drawable_callback,
512 FlutterMetalTexture embedder_texture;
513 embedder_texture.struct_size = sizeof(FlutterMetalTexture);
514 embedder_texture.texture = texture.texture;
515 embedder_texture.texture_id = texture.texture_id;
516 embedder_texture.user_data = texture.destruction_context;
517 embedder_texture.destruction_callback = texture.destruction_callback;
518 return ptr(user_data, &embedder_texture);
519 };
520 auto metal_get_texture =
521 [ptr = config->metal.get_next_drawable_callback,
522 user_data](const SkISize& frame_size) -> flutter::GPUMTLTextureInfo {
523 FlutterFrameInfo frame_info = {};
524 frame_info.struct_size = sizeof(FlutterFrameInfo);
525 frame_info.size = {static_cast<uint32_t>(frame_size.width()),
526 static_cast<uint32_t>(frame_size.height())};
527 flutter::GPUMTLTextureInfo texture_info;
528
529 FlutterMetalTexture metal_texture = ptr(user_data, &frame_info);
530 texture_info.texture_id = metal_texture.texture_id;
531 texture_info.texture = metal_texture.texture;
532 texture_info.destruction_callback = metal_texture.destruction_callback;
533 texture_info.destruction_context = metal_texture.user_data;
534 return texture_info;
535 };
536
537 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
538 std::move(external_view_embedder);
539
540 std::unique_ptr<flutter::EmbedderSurface> embedder_surface;
541
542 if (enable_impeller) {
544 metal_dispatch_table = {
545 .present = metal_present,
546 .get_texture = metal_get_texture,
547 };
548 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalImpeller>(
549 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
552 metal_dispatch_table, view_embedder);
553 } else {
554#if !SLIMPELLER
556 {
557 .present = metal_present,
558 .get_texture = metal_get_texture,
559 };
560 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalSkia>(
561 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
564 metal_dispatch_table, view_embedder);
565#else // !SLIMPELLER
566 FML_LOG(FATAL) << "Impeller opt-out unavailable.";
567#endif // !SLIMPELLER
568 }
569
570 // The static leak checker gets confused by the use of fml::MakeCopyable.
571 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
572 return fml::MakeCopyable(
573 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
574 external_view_embedder = view_embedder](flutter::Shell& shell) mutable {
575 return std::make_unique<flutter::PlatformViewEmbedder>(
576 shell, // delegate
577 shell.GetTaskRunners(), // task runners
578 std::move(embedder_surface), // embedder surface
579 platform_dispatch_table, // platform dispatch table
580 std::move(external_view_embedder) // external view embedder
581 );
582 });
583#else
584 return nullptr;
585#endif
586}
587
590 const FlutterRendererConfig* config,
591 void* user_data,
593 platform_dispatch_table,
594 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
595 external_view_embedder) {
596 if (config->type != kVulkan) {
597 return nullptr;
598 }
599
600#ifdef SHELL_ENABLE_VULKAN
601 std::function<void*(VkInstance, const char*)>
602 vulkan_get_instance_proc_address =
604 VkInstance instance, const char* proc_name) -> void* {
605 return ptr(user_data, instance, proc_name);
606 };
607
608 auto vulkan_get_next_image =
609 [ptr = config->vulkan.get_next_image_callback,
610 user_data](const SkISize& frame_size) -> FlutterVulkanImage {
611 FlutterFrameInfo frame_info = {
612 .struct_size = sizeof(FlutterFrameInfo),
613 .size = {static_cast<uint32_t>(frame_size.width()),
614 static_cast<uint32_t>(frame_size.height())},
615 };
616
617 return ptr(user_data, &frame_info);
618 };
619
620 auto vulkan_present_image_callback =
621 [ptr = config->vulkan.present_image_callback, user_data](
622 VkImage image, VkFormat format) -> bool {
623 FlutterVulkanImage image_desc = {
625 .image = reinterpret_cast<uint64_t>(image),
626 .format = static_cast<uint32_t>(format),
627 };
628 return ptr(user_data, &image_desc);
629 };
630
631 auto vk_instance = static_cast<VkInstance>(config->vulkan.instance);
632 auto proc_addr =
633 vulkan_get_instance_proc_address(vk_instance, "vkGetInstanceProcAddr");
634
637 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
638 .get_next_image = vulkan_get_next_image,
639 .present_image = vulkan_present_image_callback,
640 };
641
642 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
643 std::move(external_view_embedder);
644
645 std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
646 std::make_unique<flutter::EmbedderSurfaceVulkan>(
647 config->vulkan.version, vk_instance,
652 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
653 static_cast<VkDevice>(config->vulkan.device),
655 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
656 view_embedder);
657
658 return fml::MakeCopyable(
659 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
660 external_view_embedder =
661 std::move(view_embedder)](flutter::Shell& shell) mutable {
662 return std::make_unique<flutter::PlatformViewEmbedder>(
663 shell, // delegate
664 shell.GetTaskRunners(), // task runners
665 std::move(embedder_surface), // embedder surface
666 platform_dispatch_table, // platform dispatch table
667 std::move(external_view_embedder) // external view embedder
668 );
669 });
670#else
671 return nullptr;
672#endif
673}
674
677 const FlutterRendererConfig* config,
678 void* user_data,
680 platform_dispatch_table,
681 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
682 external_view_embedder) {
683 if (config->type != kSoftware) {
684 return nullptr;
685 }
686
687 auto software_present_backing_store =
689 const void* allocation, size_t row_bytes, size_t height) -> bool {
690 return ptr(user_data, allocation, row_bytes, height);
691 };
692
694 software_dispatch_table = {
695 software_present_backing_store, // required
696 };
697
698 return fml::MakeCopyable(
699 [software_dispatch_table, platform_dispatch_table,
700 external_view_embedder =
701 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
702 return std::make_unique<flutter::PlatformViewEmbedder>(
703 shell, // delegate
704 shell.GetTaskRunners(), // task runners
705 software_dispatch_table, // software dispatch table
706 platform_dispatch_table, // platform dispatch table
707 std::move(external_view_embedder) // external view embedder
708 );
709 });
710}
711
714 const FlutterRendererConfig* config,
715 void* user_data,
717 platform_dispatch_table,
718 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
719 external_view_embedder,
720 bool enable_impeller) {
721 if (config == nullptr) {
722 return nullptr;
723 }
724
725 switch (config->type) {
726 case kOpenGL:
728 config, user_data, platform_dispatch_table,
729 std::move(external_view_embedder), enable_impeller);
730 case kSoftware:
732 config, user_data, platform_dispatch_table,
733 std::move(external_view_embedder));
734 case kMetal:
736 config, user_data, platform_dispatch_table,
737 std::move(external_view_embedder), enable_impeller);
738 case kVulkan:
740 config, user_data, platform_dispatch_table,
741 std::move(external_view_embedder));
742 default:
743 return nullptr;
744 }
745 return nullptr;
746}
747
749 GrDirectContext* context,
750 const FlutterBackingStoreConfig& config,
752#ifdef SHELL_ENABLE_GL
753 GrGLTextureInfo texture_info;
754 texture_info.fTarget = texture->target;
755 texture_info.fID = texture->name;
756 texture_info.fFormat = texture->format;
757
758 GrBackendTexture backend_texture =
760 skgpu::Mipmapped::kNo, texture_info);
761
762 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
763
765 context, // context
766 backend_texture, // back-end texture
767 kBottomLeft_GrSurfaceOrigin, // surface origin
768 1, // sample count
769 kN32_SkColorType, // color type
770 SkColorSpace::MakeSRGB(), // color space
771 &surface_properties, // surface properties
773 texture->destruction_callback), // release proc
774 texture->user_data // release context
775 );
776
777 if (!surface) {
778 FML_LOG(ERROR) << "Could not wrap embedder supplied render texture.";
779 return nullptr;
780 }
781
782 return surface;
783#else
784 return nullptr;
785#endif
786}
787
789 GrDirectContext* context,
790 const FlutterBackingStoreConfig& config,
791 const FlutterOpenGLFramebuffer* framebuffer) {
792#ifdef SHELL_ENABLE_GL
793 GrGLFramebufferInfo framebuffer_info = {};
794 framebuffer_info.fFormat = framebuffer->target;
795 framebuffer_info.fFBOID = framebuffer->name;
796
797 auto backend_render_target =
799 config.size.height, // height
800 1, // sample count
801 0, // stencil bits
802 framebuffer_info // framebuffer info
803 );
804
805 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
806
808 context, // context
809 backend_render_target, // backend render target
810 kBottomLeft_GrSurfaceOrigin, // surface origin
811 kN32_SkColorType, // color type
812 SkColorSpace::MakeSRGB(), // color space
813 &surface_properties, // surface properties
815 framebuffer->destruction_callback), // release proc
816 framebuffer->user_data // release context
817 );
818
819 if (!surface) {
820 FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
821 return nullptr;
822 }
823 return surface;
824#else
825 return nullptr;
826#endif
827}
828
830 GrDirectContext* context,
831 const FlutterBackingStoreConfig& config,
832 const FlutterSoftwareBackingStore* software) {
833 const auto image_info =
835
836 struct Captures {
837 VoidCallback destruction_callback;
838 void* user_data;
839 };
840 auto captures = std::make_unique<Captures>();
841 captures->destruction_callback = software->destruction_callback;
842 captures->user_data = software->user_data;
843 auto release_proc = [](void* pixels, void* context) {
844 auto captures = reinterpret_cast<Captures*>(context);
845 if (captures->destruction_callback) {
846 captures->destruction_callback(captures->user_data);
847 }
848 delete captures;
849 };
850
851 auto surface =
852 SkSurfaces::WrapPixels(image_info, // image info
853 const_cast<void*>(software->allocation), // pixels
854 software->row_bytes, // row bytes
855 release_proc, // release proc
856 captures.get() // get context
857 );
858
859 if (!surface) {
861 << "Could not wrap embedder supplied software render buffer.";
862 if (software->destruction_callback) {
863 software->destruction_callback(software->user_data);
864 }
865 return nullptr;
866 }
867 if (surface) {
868 captures.release(); // Skia has assumed ownership of the struct.
869 }
870 return surface;
871}
872
874 GrDirectContext* context,
875 const FlutterBackingStoreConfig& config,
876 const FlutterSoftwareBackingStore2* software) {
877 const auto color_info = getSkColorInfo(software->pixel_format);
878 if (!color_info) {
879 return nullptr;
880 }
881
882 const auto image_info = SkImageInfo::Make(
883 SkISize::Make(config.size.width, config.size.height), *color_info);
884
885 struct Captures {
886 VoidCallback destruction_callback;
887 void* user_data;
888 };
889 auto captures = std::make_unique<Captures>();
890 captures->destruction_callback = software->destruction_callback;
891 captures->user_data = software->user_data;
892 auto release_proc = [](void* pixels, void* context) {
893 auto captures = reinterpret_cast<Captures*>(context);
894 if (captures->destruction_callback) {
895 captures->destruction_callback(captures->user_data);
896 }
897 };
898
899 auto surface =
900 SkSurfaces::WrapPixels(image_info, // image info
901 const_cast<void*>(software->allocation), // pixels
902 software->row_bytes, // row bytes
903 release_proc, // release proc
904 captures.release() // release context
905 );
906
907 if (!surface) {
909 << "Could not wrap embedder supplied software render buffer.";
910 if (software->destruction_callback) {
911 software->destruction_callback(software->user_data);
912 }
913 return nullptr;
914 }
915 return surface;
916}
917
919 GrDirectContext* context,
920 const FlutterBackingStoreConfig& config,
921 const FlutterMetalBackingStore* metal) {
922#if defined(SHELL_ENABLE_METAL) && !SLIMPELLER
923 GrMtlTextureInfo texture_info;
924 if (!metal->texture.texture) {
925 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
926 return nullptr;
927 }
928 sk_cfp<FlutterMetalTextureHandle> mtl_texture;
929 mtl_texture.retain(metal->texture.texture);
930 texture_info.fTexture = mtl_texture;
931 GrBackendTexture backend_texture =
933 config.size.height, //
935 texture_info //
936 );
937
938 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
939
941 context, // context
942 backend_texture, // back-end texture
943 kTopLeft_GrSurfaceOrigin, // surface origin
944 1, // sample count
945 kBGRA_8888_SkColorType, // color type
946 nullptr, // color space
947 &surface_properties, // surface properties
949 metal->texture.destruction_callback), // release proc
950 metal->texture.user_data // release context
951 );
952
953 if (!surface) {
954 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
955 return nullptr;
956 }
957
958 return surface;
959#else
960 return nullptr;
961#endif
962}
963
964static std::unique_ptr<flutter::EmbedderRenderTarget>
966 FlutterBackingStore backing_store,
967 const fml::closure& on_release,
968 const std::shared_ptr<impeller::AiksContext>& aiks_context,
969 const FlutterBackingStoreConfig& config,
970 const FlutterOpenGLFramebuffer* framebuffer) {
971#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
972
973 const auto& gl_context =
974 impeller::ContextGLES::Cast(*aiks_context->GetContext());
975 const auto size = impeller::ISize(config.size.width, config.size.height);
976
980 color0_tex.size = size;
981 color0_tex.usage = static_cast<impeller::TextureUsageMask>(
985
988 gl_context.GetReactor(), color0_tex, framebuffer->name);
992
993 impeller::TextureDescriptor depth_stencil_texture_desc;
994 depth_stencil_texture_desc.type = impeller::TextureType::kTexture2D;
995 depth_stencil_texture_desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
996 depth_stencil_texture_desc.size = size;
997 depth_stencil_texture_desc.usage = static_cast<impeller::TextureUsageMask>(
999 depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount1;
1000
1001 auto depth_stencil_tex = std::make_shared<impeller::TextureGLES>(
1002 gl_context.GetReactor(), depth_stencil_texture_desc,
1004
1006 depth0.clear_depth = 0;
1007 depth0.texture = depth_stencil_tex;
1010
1012 stencil0.clear_stencil = 0;
1013 stencil0.texture = depth_stencil_tex;
1016
1017 impeller::RenderTarget render_target_desc;
1018
1019 render_target_desc.SetColorAttachment(color0, 0u);
1020 render_target_desc.SetDepthAttachment(depth0);
1021 render_target_desc.SetStencilAttachment(stencil0);
1022
1023 fml::closure framebuffer_destruct =
1024 [callback = framebuffer->destruction_callback,
1025 user_data = framebuffer->user_data]() { callback(user_data); };
1026
1027 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1028 backing_store, aiks_context,
1029 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1030 on_release, framebuffer_destruct);
1031#else
1032 return nullptr;
1033#endif
1034}
1035
1036static std::unique_ptr<flutter::EmbedderRenderTarget>
1038 FlutterBackingStore backing_store,
1039 const fml::closure& on_release,
1040 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1041 const FlutterBackingStoreConfig& config,
1042 const FlutterMetalBackingStore* metal) {
1043#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING)
1044 if (!metal->texture.texture) {
1045 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
1046 return nullptr;
1047 }
1048
1049 const auto size = impeller::ISize(config.size.width, config.size.height);
1050
1051 impeller::TextureDescriptor resolve_tex_desc;
1052 resolve_tex_desc.size = size;
1055 resolve_tex_desc.usage = impeller::TextureUsage::kRenderTarget |
1057
1058 auto resolve_tex = impeller::WrapTextureMTL(
1059 resolve_tex_desc, metal->texture.texture,
1061 user_data = metal->texture.user_data]() { callback(user_data); });
1062 if (!resolve_tex) {
1063 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
1064 return nullptr;
1065 }
1066 resolve_tex->SetLabel("ImpellerBackingStoreResolve");
1067
1068 impeller::TextureDescriptor msaa_tex_desc;
1072 msaa_tex_desc.format = resolve_tex->GetTextureDescriptor().format;
1073 msaa_tex_desc.size = size;
1075
1076 auto msaa_tex =
1077 aiks_context->GetContext()->GetResourceAllocator()->CreateTexture(
1078 msaa_tex_desc);
1079 if (!msaa_tex) {
1080 FML_LOG(ERROR) << "Could not allocate MSAA color texture.";
1081 return nullptr;
1082 }
1083 msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA");
1084
1086 color0.texture = msaa_tex;
1090 color0.resolve_texture = resolve_tex;
1091
1092 impeller::RenderTarget render_target_desc;
1093 render_target_desc.SetColorAttachment(color0, 0u);
1094
1095 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1096 backing_store, aiks_context,
1097 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1098 on_release, fml::closure());
1099#else
1100 return nullptr;
1101#endif
1102}
1103
1105 GrDirectContext* context,
1106 const FlutterBackingStoreConfig& config,
1108#ifdef SHELL_ENABLE_VULKAN
1109 if (!vulkan->image) {
1110 FML_LOG(ERROR) << "Embedder supplied null Vulkan image.";
1111 return nullptr;
1112 }
1113 GrVkImageInfo image_info = {
1114 .fImage = reinterpret_cast<VkImage>(vulkan->image->image),
1115 .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
1116 .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1117 .fFormat = static_cast<VkFormat>(vulkan->image->format),
1118 .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
1122 .fSampleCount = 1,
1123 .fLevelCount = 1,
1124 };
1125 auto backend_texture = GrBackendTextures::MakeVk(
1126 config.size.width, config.size.height, image_info);
1127
1128 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
1129
1131 context, // context
1132 backend_texture, // back-end texture
1133 kTopLeft_GrSurfaceOrigin, // surface origin
1134 1, // sample count
1136 static_cast<VkFormat>(vulkan->image->format)), // color type
1137 SkColorSpace::MakeSRGB(), // color space
1138 &surface_properties, // surface properties
1139 static_cast<SkSurfaces::TextureReleaseProc>(
1140 vulkan->destruction_callback), // release proc
1141 vulkan->user_data // release context
1142 );
1143
1144 if (!surface) {
1145 FML_LOG(ERROR) << "Could not wrap embedder supplied Vulkan render texture.";
1146 return nullptr;
1147 }
1148
1149 return surface;
1150#else
1151 return nullptr;
1152#endif
1153}
1154
1155static std::unique_ptr<flutter::EmbedderRenderTarget>
1157 sk_sp<SkSurface> skia_surface,
1158 fml::closure on_release) {
1159 if (!skia_surface) {
1160 return nullptr;
1161 }
1162 return std::make_unique<flutter::EmbedderRenderTargetSkia>(
1163 backing_store, std::move(skia_surface), std::move(on_release));
1164}
1165
1166static std::unique_ptr<flutter::EmbedderRenderTarget>
1168 const FlutterCompositor* compositor,
1169 const FlutterBackingStoreConfig& config,
1170 GrDirectContext* context,
1171 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1172 bool enable_impeller) {
1173 FlutterBackingStore backing_store = {};
1174 backing_store.struct_size = sizeof(backing_store);
1175
1176 // Safe access checks on the compositor struct have been performed in
1177 // InferExternalViewEmbedderFromArgs and are not necessary here.
1178 auto c_create_callback = compositor->create_backing_store_callback;
1179 auto c_collect_callback = compositor->collect_backing_store_callback;
1180
1181 {
1182 TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
1183 if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
1184 FML_LOG(ERROR) << "Could not create the embedder backing store.";
1185 return nullptr;
1186 }
1187 }
1188
1189 if (backing_store.struct_size != sizeof(backing_store)) {
1190 FML_LOG(ERROR) << "Embedder modified the backing store struct size.";
1191 return nullptr;
1192 }
1193
1194 // In case we return early without creating an embedder render target, the
1195 // embedder has still given us ownership of its baton which we must return
1196 // back to it. If this method is successful, the closure is released when the
1197 // render target is eventually released.
1198 fml::ScopedCleanupClosure collect_callback(
1199 [c_collect_callback, backing_store, user_data = compositor->user_data]() {
1200 TRACE_EVENT0("flutter", "FlutterCompositorCollectBackingStore");
1201 c_collect_callback(&backing_store, user_data);
1202 });
1203
1204 // No safe access checks on the renderer are necessary since we allocated
1205 // the struct.
1206
1207 std::unique_ptr<flutter::EmbedderRenderTarget> render_target;
1208
1209 switch (backing_store.type) {
1211 switch (backing_store.open_gl.type) {
1213 auto skia_surface = MakeSkSurfaceFromBackingStore(
1214 context, config, &backing_store.open_gl.texture);
1215 render_target = MakeRenderTargetFromSkSurface(
1216 backing_store, std::move(skia_surface),
1217 collect_callback.Release());
1218 break;
1219 }
1221 if (enable_impeller) {
1223 backing_store, collect_callback.Release(), aiks_context, config,
1224 &backing_store.open_gl.framebuffer);
1225 break;
1226 } else {
1227 auto skia_surface = MakeSkSurfaceFromBackingStore(
1228 context, config, &backing_store.open_gl.framebuffer);
1229 render_target = MakeRenderTargetFromSkSurface(
1230 backing_store, std::move(skia_surface),
1231 collect_callback.Release());
1232 break;
1233 }
1234 }
1235 }
1236 break;
1237 }
1239 auto skia_surface = MakeSkSurfaceFromBackingStore(
1240 context, config, &backing_store.software);
1241 render_target = MakeRenderTargetFromSkSurface(
1242 backing_store, std::move(skia_surface), collect_callback.Release());
1243 break;
1244 }
1246 auto skia_surface = MakeSkSurfaceFromBackingStore(
1247 context, config, &backing_store.software2);
1248 render_target = MakeRenderTargetFromSkSurface(
1249 backing_store, std::move(skia_surface), collect_callback.Release());
1250 break;
1251 }
1253 if (enable_impeller) {
1255 backing_store, collect_callback.Release(), aiks_context, config,
1256 &backing_store.metal);
1257 } else {
1258 auto skia_surface = MakeSkSurfaceFromBackingStore(context, config,
1259 &backing_store.metal);
1260 render_target = MakeRenderTargetFromSkSurface(
1261 backing_store, std::move(skia_surface), collect_callback.Release());
1262 }
1263 break;
1264 }
1266 auto skia_surface =
1267 MakeSkSurfaceFromBackingStore(context, config, &backing_store.vulkan);
1268 render_target = MakeRenderTargetFromSkSurface(
1269 backing_store, std::move(skia_surface), collect_callback.Release());
1270 break;
1271 }
1272 };
1273
1274 if (!render_target) {
1275 FML_LOG(ERROR) << "Could not create a surface from an embedder provided "
1276 "render target.";
1277 }
1278 return render_target;
1279}
1280
1281static std::pair<std::unique_ptr<flutter::EmbedderExternalViewEmbedder>,
1282 bool /* halt engine launch if true */>
1284 bool enable_impeller) {
1285 if (compositor == nullptr) {
1286 return {nullptr, false};
1287 }
1288
1289 auto c_create_callback =
1290 SAFE_ACCESS(compositor, create_backing_store_callback, nullptr);
1291 auto c_collect_callback =
1292 SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
1293 auto c_present_callback =
1294 SAFE_ACCESS(compositor, present_layers_callback, nullptr);
1295 auto c_present_view_callback =
1296 SAFE_ACCESS(compositor, present_view_callback, nullptr);
1297 bool avoid_backing_store_cache =
1298 SAFE_ACCESS(compositor, avoid_backing_store_cache, false);
1299
1300 // Make sure the required callbacks are present
1301 if (!c_create_callback || !c_collect_callback) {
1302 FML_LOG(ERROR) << "Required compositor callbacks absent.";
1303 return {nullptr, true};
1304 }
1305 // Either the present view or the present layers callback must be provided.
1306 if ((!c_present_view_callback && !c_present_callback) ||
1307 (c_present_view_callback && c_present_callback)) {
1308 FML_LOG(ERROR) << "Either present_layers_callback or present_view_callback "
1309 "must be provided but not both.";
1310 return {nullptr, true};
1311 }
1312
1313 FlutterCompositor captured_compositor = *compositor;
1314
1316 create_render_target_callback =
1317 [captured_compositor, enable_impeller](
1318 GrDirectContext* context,
1319 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1320 const auto& config) {
1321 return CreateEmbedderRenderTarget(&captured_compositor, config,
1322 context, aiks_context,
1323 enable_impeller);
1324 };
1325
1327 if (c_present_callback) {
1328 present_callback = [c_present_callback, user_data = compositor->user_data](
1329 FlutterViewId view_id, const auto& layers) {
1330 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1331 return c_present_callback(const_cast<const FlutterLayer**>(layers.data()),
1332 layers.size(), user_data);
1333 };
1334 } else {
1335 FML_DCHECK(c_present_view_callback != nullptr);
1336 present_callback = [c_present_view_callback,
1337 user_data = compositor->user_data](
1338 FlutterViewId view_id, const auto& layers) {
1339 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1340
1342 .struct_size = sizeof(FlutterPresentViewInfo),
1343 .view_id = view_id,
1344 .layers = const_cast<const FlutterLayer**>(layers.data()),
1345 .layers_count = layers.size(),
1346 .user_data = user_data,
1347 };
1348
1349 return c_present_view_callback(&info);
1350 };
1351 }
1352
1353 return {std::make_unique<flutter::EmbedderExternalViewEmbedder>(
1354 avoid_backing_store_cache, create_render_target_callback,
1355 present_callback),
1356 false};
1357}
1358
1359// Translates embedder metrics to engine metrics, or returns a string on error.
1360static std::variant<flutter::ViewportMetrics, std::string>
1362 const FlutterWindowMetricsEvent* flutter_metrics) {
1363 if (flutter_metrics == nullptr) {
1364 return "Invalid metrics handle.";
1365 }
1366
1368
1369 metrics.physical_width = SAFE_ACCESS(flutter_metrics, width, 0.0);
1370 metrics.physical_height = SAFE_ACCESS(flutter_metrics, height, 0.0);
1371 metrics.device_pixel_ratio = SAFE_ACCESS(flutter_metrics, pixel_ratio, 1.0);
1372 metrics.physical_view_inset_top =
1373 SAFE_ACCESS(flutter_metrics, physical_view_inset_top, 0.0);
1375 SAFE_ACCESS(flutter_metrics, physical_view_inset_right, 0.0);
1377 SAFE_ACCESS(flutter_metrics, physical_view_inset_bottom, 0.0);
1378 metrics.physical_view_inset_left =
1379 SAFE_ACCESS(flutter_metrics, physical_view_inset_left, 0.0);
1380 metrics.display_id = SAFE_ACCESS(flutter_metrics, display_id, 0);
1381
1382 if (metrics.device_pixel_ratio <= 0.0) {
1383 return "Device pixel ratio was invalid. It must be greater than zero.";
1384 }
1385
1386 if (metrics.physical_view_inset_top < 0 ||
1387 metrics.physical_view_inset_right < 0 ||
1388 metrics.physical_view_inset_bottom < 0 ||
1389 metrics.physical_view_inset_left < 0) {
1390 return "Physical view insets are invalid. They must be non-negative.";
1391 }
1392
1393 if (metrics.physical_view_inset_top > metrics.physical_height ||
1394 metrics.physical_view_inset_right > metrics.physical_width ||
1395 metrics.physical_view_inset_bottom > metrics.physical_height ||
1396 metrics.physical_view_inset_left > metrics.physical_width) {
1397 return "Physical view insets are invalid. They cannot be greater than "
1398 "physical height or width.";
1399 }
1400
1401 return metrics;
1402}
1403
1405 std::unique_ptr<flutter::PlatformMessage> message;
1406};
1407
1410 if (elf) {
1411 ::Dart_UnloadELF(elf);
1412 }
1413 }
1414};
1415
1416using UniqueLoadedElf = std::unique_ptr<Dart_LoadedElf, LoadedElfDeleter>;
1417
1420 const uint8_t* vm_snapshot_data = nullptr;
1421 const uint8_t* vm_snapshot_instrs = nullptr;
1422 const uint8_t* vm_isolate_data = nullptr;
1423 const uint8_t* vm_isolate_instrs = nullptr;
1424};
1425
1428 FlutterEngineAOTData* data_out) {
1431 "AOT data can only be created in AOT mode.");
1432 } else if (!source) {
1433 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null source specified.");
1434 } else if (!data_out) {
1435 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null data_out specified.");
1436 }
1437
1438 switch (source->type) {
1440 if (!source->elf_path || !fml::IsFile(source->elf_path)) {
1442 "Invalid ELF path specified.");
1443 }
1444
1445 auto aot_data = std::make_unique<_FlutterEngineAOTData>();
1446 const char* error = nullptr;
1447
1448#if OS_FUCHSIA
1449 // TODO(gw280): https://github.com/flutter/flutter/issues/50285
1450 // Dart doesn't implement Dart_LoadELF on Fuchsia
1451 Dart_LoadedElf* loaded_elf = nullptr;
1452#else
1453 Dart_LoadedElf* loaded_elf = Dart_LoadELF(
1454 source->elf_path, // file path
1455 0, // file offset
1456 &error, // error (out)
1457 &aot_data->vm_snapshot_data, // vm snapshot data (out)
1458 &aot_data->vm_snapshot_instrs, // vm snapshot instr (out)
1459 &aot_data->vm_isolate_data, // vm isolate data (out)
1460 &aot_data->vm_isolate_instrs // vm isolate instr (out)
1461 );
1462#endif
1463
1464 if (loaded_elf == nullptr) {
1466 }
1467
1468 aot_data->loaded_elf.reset(loaded_elf);
1469
1470 *data_out = aot_data.release();
1471 return kSuccess;
1472 }
1473 }
1474
1475 return LOG_EMBEDDER_ERROR(
1477 "Invalid FlutterEngineAOTDataSourceType type specified.");
1478}
1479
1481 if (!data) {
1482 // Deleting a null object should be a no-op.
1483 return kSuccess;
1484 }
1485
1486 // Created in a unique pointer in `FlutterEngineCreateAOTData`.
1487 delete data;
1488 return kSuccess;
1489}
1490
1491// Constructs appropriate mapping callbacks if JIT snapshot locations have been
1492// explictly specified.
1495 auto make_mapping_callback = [](const char* path, bool executable) {
1496 return [path, executable]() {
1497 if (executable) {
1499 } else {
1501 }
1502 };
1503 };
1504
1505 // Users are allowed to specify only certain snapshots if they so desire.
1506 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1507 settings.vm_snapshot_data = make_mapping_callback(
1508 reinterpret_cast<const char*>(args->vm_snapshot_data), false);
1509 }
1510
1511 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1512 settings.vm_snapshot_instr = make_mapping_callback(
1513 reinterpret_cast<const char*>(args->vm_snapshot_instructions), true);
1514 }
1515
1516 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1517 settings.isolate_snapshot_data = make_mapping_callback(
1518 reinterpret_cast<const char*>(args->isolate_snapshot_data), false);
1519 }
1520
1521 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1522 settings.isolate_snapshot_instr = make_mapping_callback(
1523 reinterpret_cast<const char*>(args->isolate_snapshot_instructions),
1524 true);
1525 }
1526
1527#if !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
1528 settings.dart_library_sources_kernel = []() {
1529 return std::make_unique<fml::NonOwnedMapping>(kPlatformStrongDill,
1531 };
1532#endif // !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE ==
1533 // FLUTTER_RUNTIME_MODE_DEBUG)
1534}
1535
1537 const FlutterProjectArgs* args,
1538 flutter::Settings& settings) { // NOLINT(google-runtime-references)
1539 // There are no ownership concerns here as all mappings are owned by the
1540 // embedder and not the engine.
1541 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
1542 return [mapping, size]() {
1543 return std::make_unique<fml::NonOwnedMapping>(mapping, size);
1544 };
1545 };
1546
1547 if (SAFE_ACCESS(args, aot_data, nullptr) != nullptr) {
1548 settings.vm_snapshot_data =
1549 make_mapping_callback(args->aot_data->vm_snapshot_data, 0);
1550
1551 settings.vm_snapshot_instr =
1552 make_mapping_callback(args->aot_data->vm_snapshot_instrs, 0);
1553
1554 settings.isolate_snapshot_data =
1555 make_mapping_callback(args->aot_data->vm_isolate_data, 0);
1556
1557 settings.isolate_snapshot_instr =
1558 make_mapping_callback(args->aot_data->vm_isolate_instrs, 0);
1559 }
1560
1561 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1562 settings.vm_snapshot_data = make_mapping_callback(
1563 args->vm_snapshot_data, SAFE_ACCESS(args, vm_snapshot_data_size, 0));
1564 }
1565
1566 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1567 settings.vm_snapshot_instr = make_mapping_callback(
1568 args->vm_snapshot_instructions,
1569 SAFE_ACCESS(args, vm_snapshot_instructions_size, 0));
1570 }
1571
1572 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1573 settings.isolate_snapshot_data =
1574 make_mapping_callback(args->isolate_snapshot_data,
1575 SAFE_ACCESS(args, isolate_snapshot_data_size, 0));
1576 }
1577
1578 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1579 settings.isolate_snapshot_instr = make_mapping_callback(
1580 args->isolate_snapshot_instructions,
1581 SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0));
1582 }
1583}
1584
1585// Create a callback to notify the embedder of semantic updates
1586// using the legacy embedder callbacks 'update_semantics_node_callback' and
1587// 'update_semantics_custom_action_callback'.
1590 FlutterUpdateSemanticsNodeCallback update_semantics_node_callback,
1592 update_semantics_custom_action_callback,
1593 void* user_data) {
1594 return [update_semantics_node_callback,
1595 update_semantics_custom_action_callback,
1599 FlutterSemanticsUpdate* update_ptr = update.get();
1600
1601 // First, queue all node and custom action updates.
1602 if (update_semantics_node_callback != nullptr) {
1603 for (size_t i = 0; i < update_ptr->nodes_count; i++) {
1604 update_semantics_node_callback(&update_ptr->nodes[i], user_data);
1605 }
1606 }
1607
1608 if (update_semantics_custom_action_callback != nullptr) {
1609 for (size_t i = 0; i < update_ptr->custom_actions_count; i++) {
1610 update_semantics_custom_action_callback(&update_ptr->custom_actions[i],
1611 user_data);
1612 }
1613 }
1614
1615 // Second, mark node and action batches completed now that all
1616 // updates are queued.
1617 if (update_semantics_node_callback != nullptr) {
1618 const FlutterSemanticsNode batch_end_sentinel = {
1619 sizeof(FlutterSemanticsNode),
1621 };
1622 update_semantics_node_callback(&batch_end_sentinel, user_data);
1623 }
1624
1625 if (update_semantics_custom_action_callback != nullptr) {
1626 const FlutterSemanticsCustomAction batch_end_sentinel = {
1629 };
1630 update_semantics_custom_action_callback(&batch_end_sentinel, user_data);
1631 }
1632 };
1633}
1634
1635// Create a callback to notify the embedder of semantic updates
1636// using the deprecated embedder callback 'update_semantics_callback'.
1639 FlutterUpdateSemanticsCallback update_semantics_callback,
1640 void* user_data) {
1641 return [update_semantics_callback, user_data](
1642 const flutter::SemanticsNodeUpdates& nodes,
1645
1646 update_semantics_callback(update.get(), user_data);
1647 };
1648}
1649
1650// Create a callback to notify the embedder of semantic updates
1651// using the new embedder callback 'update_semantics_callback2'.
1654 FlutterUpdateSemanticsCallback2 update_semantics_callback,
1655 void* user_data) {
1656 return [update_semantics_callback, user_data](
1657 const flutter::SemanticsNodeUpdates& nodes,
1660
1661 update_semantics_callback(update.get(), user_data);
1662 };
1663}
1664
1665// Creates a callback that receives semantic updates from the engine
1666// and notifies the embedder's callback(s). Returns null if the embedder
1667// did not register any callbacks.
1670 void* user_data) {
1671 // There are three variants for the embedder API's semantic update callbacks.
1672 // Create a callback that maps to the embedder's desired semantic update API.
1673 //
1674 // Handle the case where the embedder registered the callback
1675 // 'updated_semantics_callback2'
1676 if (SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr) {
1678 args->update_semantics_callback2, user_data);
1679 }
1680
1681 // Handle the case where the embedder registered the deprecated callback
1682 // 'update_semantics_callback'.
1683 if (SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr) {
1685 args->update_semantics_callback, user_data);
1686 }
1687
1688 // Handle the case where the embedder registered the deprecated callbacks
1689 // 'update_semantics_node_callback' and
1690 // 'update_semantics_custom_action_callback'.
1691 FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
1692 if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
1693 update_semantics_node_callback = args->update_semantics_node_callback;
1694 }
1695
1697 update_semantics_custom_action_callback = nullptr;
1698 if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
1699 nullptr) {
1700 update_semantics_custom_action_callback =
1701 args->update_semantics_custom_action_callback;
1702 }
1703
1704 if (update_semantics_node_callback != nullptr ||
1705 update_semantics_custom_action_callback != nullptr) {
1707 update_semantics_node_callback, update_semantics_custom_action_callback,
1708 user_data);
1709 }
1710
1711 // Handle the case where the embedder registered no callbacks.
1712 return nullptr;
1713}
1714
1716 const FlutterRendererConfig* config,
1717 const FlutterProjectArgs* args,
1718 void* user_data,
1720 engine_out) {
1721 auto result =
1722 FlutterEngineInitialize(version, config, args, user_data, engine_out);
1723
1724 if (result != kSuccess) {
1725 return result;
1726 }
1727
1728 return FlutterEngineRunInitialized(*engine_out);
1729}
1730
1732 const FlutterRendererConfig* config,
1733 const FlutterProjectArgs* args,
1734 void* user_data,
1736 engine_out) {
1737 // Step 0: Figure out arguments for shell creation.
1739 return LOG_EMBEDDER_ERROR(
1741 "Flutter embedder version mismatch. There has been a breaking change. "
1742 "Please consult the changelog and update the embedder.");
1743 }
1744
1745 if (engine_out == nullptr) {
1747 "The engine out parameter was missing.");
1748 }
1749
1750 if (args == nullptr) {
1752 "The Flutter project arguments were missing.");
1753 }
1754
1755 if (SAFE_ACCESS(args, assets_path, nullptr) == nullptr) {
1756 return LOG_EMBEDDER_ERROR(
1758 "The assets path in the Flutter project arguments was missing.");
1759 }
1760
1761 if (SAFE_ACCESS(args, main_path__unused__, nullptr) != nullptr) {
1762 FML_LOG(WARNING)
1763 << "FlutterProjectArgs.main_path is deprecated and should be set null.";
1764 }
1765
1766 if (SAFE_ACCESS(args, packages_path__unused__, nullptr) != nullptr) {
1767 FML_LOG(WARNING) << "FlutterProjectArgs.packages_path is deprecated and "
1768 "should be set null.";
1769 }
1770
1771 if (!IsRendererValid(config)) {
1773 "The renderer configuration was invalid.");
1774 }
1775
1776 std::string icu_data_path;
1777 if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
1778 icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
1779 }
1780
1781#if !SLIMPELLER
1782 if (SAFE_ACCESS(args, persistent_cache_path, nullptr) != nullptr) {
1783 std::string persistent_cache_path =
1784 SAFE_ACCESS(args, persistent_cache_path, nullptr);
1786 }
1787
1788 if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) {
1790 }
1791#endif // !SLIMPELLER
1792
1793 fml::CommandLine command_line;
1794 if (SAFE_ACCESS(args, command_line_argc, 0) != 0 &&
1795 SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) {
1796 command_line = fml::CommandLineFromArgcArgv(
1797 SAFE_ACCESS(args, command_line_argc, 0),
1798 SAFE_ACCESS(args, command_line_argv, nullptr));
1799 }
1800
1802
1803 if (SAFE_ACCESS(args, aot_data, nullptr)) {
1804 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) ||
1808 return LOG_EMBEDDER_ERROR(
1810 "Multiple AOT sources specified. Embedders should provide either "
1811 "*_snapshot_* buffers or aot_data, not both.");
1812 }
1813 }
1814
1817 } else {
1819 }
1820
1821 settings.icu_data_path = icu_data_path;
1822 settings.assets_path = args->assets_path;
1823 settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false);
1824 settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1);
1825
1827 // Verify the assets path contains Dart 2 kernel assets.
1828 const std::string kApplicationKernelSnapshotFileName = "kernel_blob.bin";
1829 std::string application_kernel_path = fml::paths::JoinPaths(
1831 if (!fml::IsFile(application_kernel_path)) {
1832 return LOG_EMBEDDER_ERROR(
1834 "Not running in AOT mode but could not resolve the kernel binary.");
1835 }
1836 settings.application_kernel_asset = kApplicationKernelSnapshotFileName;
1837 }
1838
1839 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
1841 };
1842 settings.task_observer_remove = [](intptr_t key) {
1844 };
1845 if (SAFE_ACCESS(args, root_isolate_create_callback, nullptr) != nullptr) {
1847 SAFE_ACCESS(args, root_isolate_create_callback, nullptr);
1848 settings.root_isolate_create_callback =
1849 [callback, user_data](const auto& isolate) { callback(user_data); };
1850 }
1851 if (SAFE_ACCESS(args, log_message_callback, nullptr) != nullptr) {
1853 SAFE_ACCESS(args, log_message_callback, nullptr);
1854 settings.log_message_callback = [callback, user_data](
1855 const std::string& tag,
1856 const std::string& message) {
1857 callback(tag.c_str(), message.c_str(), user_data);
1858 };
1859 }
1860 if (SAFE_ACCESS(args, log_tag, nullptr) != nullptr) {
1861 settings.log_tag = SAFE_ACCESS(args, log_tag, nullptr);
1862 }
1863
1864 bool has_update_semantics_2_callback =
1865 SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr;
1866 bool has_update_semantics_callback =
1867 SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr;
1868 bool has_legacy_update_semantics_callback =
1869 SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr ||
1870 SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
1871 nullptr;
1872
1873 int semantic_callback_count = (has_update_semantics_2_callback ? 1 : 0) +
1874 (has_update_semantics_callback ? 1 : 0) +
1875 (has_legacy_update_semantics_callback ? 1 : 0);
1876
1877 if (semantic_callback_count > 1) {
1878 return LOG_EMBEDDER_ERROR(
1880 "Multiple semantics update callbacks provided. "
1881 "Embedders should provide either `update_semantics_callback2`, "
1882 "`update_semantics_callback`, or both "
1883 "`update_semantics_node_callback` and "
1884 "`update_semantics_custom_action_callback`.");
1885 }
1886
1888 update_semantics_callback =
1890
1892 platform_message_response_callback = nullptr;
1893 if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
1894 platform_message_response_callback =
1895 [ptr = args->platform_message_callback,
1896 user_data](std::unique_ptr<flutter::PlatformMessage> message) {
1897 auto handle = new FlutterPlatformMessageResponseHandle();
1898 const FlutterPlatformMessage incoming_message = {
1899 sizeof(FlutterPlatformMessage), // struct_size
1900 message->channel().c_str(), // channel
1901 message->data().GetMapping(), // message
1902 message->data().GetSize(), // message_size
1903 handle, // response_handle
1904 };
1905 handle->message = std::move(message);
1906 return ptr(&incoming_message, user_data);
1907 };
1908 }
1909
1910 flutter::VsyncWaiterEmbedder::VsyncCallback vsync_callback = nullptr;
1911 if (SAFE_ACCESS(args, vsync_callback, nullptr) != nullptr) {
1912 vsync_callback = [ptr = args->vsync_callback, user_data](intptr_t baton) {
1913 return ptr(user_data, baton);
1914 };
1915 }
1916
1918 compute_platform_resolved_locale_callback = nullptr;
1919 if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
1920 nullptr) {
1921 compute_platform_resolved_locale_callback =
1922 [ptr = args->compute_platform_resolved_locale_callback](
1923 const std::vector<std::string>& supported_locales_data) {
1924 const size_t number_of_strings_per_locale = 3;
1925 size_t locale_count =
1926 supported_locales_data.size() / number_of_strings_per_locale;
1927 std::vector<FlutterLocale> supported_locales;
1928 std::vector<const FlutterLocale*> supported_locales_ptr;
1929 for (size_t i = 0; i < locale_count; ++i) {
1930 supported_locales.push_back(
1931 {.struct_size = sizeof(FlutterLocale),
1932 .language_code =
1933 supported_locales_data[i * number_of_strings_per_locale +
1934 0]
1935 .c_str(),
1936 .country_code =
1937 supported_locales_data[i * number_of_strings_per_locale +
1938 1]
1939 .c_str(),
1940 .script_code =
1941 supported_locales_data[i * number_of_strings_per_locale +
1942 2]
1943 .c_str(),
1944 .variant_code = nullptr});
1945 supported_locales_ptr.push_back(&supported_locales[i]);
1946 }
1947
1948 const FlutterLocale* result =
1949 ptr(supported_locales_ptr.data(), locale_count);
1950
1951 std::unique_ptr<std::vector<std::string>> out =
1952 std::make_unique<std::vector<std::string>>();
1953 if (result) {
1954 std::string language_code(SAFE_ACCESS(result, language_code, ""));
1955 if (language_code != "") {
1956 out->push_back(language_code);
1957 out->emplace_back(SAFE_ACCESS(result, country_code, ""));
1958 out->emplace_back(SAFE_ACCESS(result, script_code, ""));
1959 }
1960 }
1961 return out;
1962 };
1963 }
1964
1966 on_pre_engine_restart_callback = nullptr;
1967 if (SAFE_ACCESS(args, on_pre_engine_restart_callback, nullptr) != nullptr) {
1968 on_pre_engine_restart_callback = [ptr =
1969 args->on_pre_engine_restart_callback,
1970 user_data]() { return ptr(user_data); };
1971 }
1972
1974 nullptr;
1975 if (SAFE_ACCESS(args, channel_update_callback, nullptr) != nullptr) {
1976 channel_update_callback = [ptr = args->channel_update_callback, user_data](
1977 const std::string& name, bool listening) {
1979 listening};
1980 ptr(&update, user_data);
1981 };
1982 }
1983
1984 auto external_view_embedder_result = InferExternalViewEmbedderFromArgs(
1985 SAFE_ACCESS(args, compositor, nullptr), settings.enable_impeller);
1986 if (external_view_embedder_result.second) {
1988 "Compositor arguments were invalid.");
1989 }
1990
1992 {
1993 update_semantics_callback, //
1994 platform_message_response_callback, //
1995 vsync_callback, //
1996 compute_platform_resolved_locale_callback, //
1997 on_pre_engine_restart_callback, //
1998 channel_update_callback, //
1999 };
2000
2001 auto on_create_platform_view = InferPlatformViewCreationCallback(
2002 config, user_data, platform_dispatch_table,
2003 std::move(external_view_embedder_result.first), settings.enable_impeller);
2004
2005 if (!on_create_platform_view) {
2006 return LOG_EMBEDDER_ERROR(
2008 "Could not infer platform view creation callback.");
2009 }
2010
2012 [](flutter::Shell& shell) {
2013 return std::make_unique<flutter::Rasterizer>(shell);
2014 };
2015
2016 using ExternalTextureResolver = flutter::EmbedderExternalTextureResolver;
2017 std::unique_ptr<ExternalTextureResolver> external_texture_resolver;
2018 external_texture_resolver = std::make_unique<ExternalTextureResolver>();
2019
2020#ifdef SHELL_ENABLE_GL
2022 external_texture_callback;
2023 if (config->type == kOpenGL) {
2024 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
2025 if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
2026 nullptr) != nullptr) {
2027 external_texture_callback =
2028 [ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
2029 int64_t texture_identifier, size_t width,
2030 size_t height) -> std::unique_ptr<FlutterOpenGLTexture> {
2031 std::unique_ptr<FlutterOpenGLTexture> texture =
2032 std::make_unique<FlutterOpenGLTexture>();
2033 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2034 return nullptr;
2035 }
2036 return texture;
2037 };
2038 external_texture_resolver =
2039 std::make_unique<ExternalTextureResolver>(external_texture_callback);
2040 }
2041 }
2042#endif
2043#ifdef SHELL_ENABLE_METAL
2045 external_texture_metal_callback;
2046 if (config->type == kMetal) {
2047 const FlutterMetalRendererConfig* metal_config = &config->metal;
2048 if (SAFE_ACCESS(metal_config, external_texture_frame_callback, nullptr)) {
2049 external_texture_metal_callback =
2050 [ptr = metal_config->external_texture_frame_callback, user_data](
2051 int64_t texture_identifier, size_t width,
2052 size_t height) -> std::unique_ptr<FlutterMetalExternalTexture> {
2053 std::unique_ptr<FlutterMetalExternalTexture> texture =
2054 std::make_unique<FlutterMetalExternalTexture>();
2055 texture->struct_size = sizeof(FlutterMetalExternalTexture);
2056 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2057 return nullptr;
2058 }
2059 return texture;
2060 };
2061 external_texture_resolver = std::make_unique<ExternalTextureResolver>(
2062 external_texture_metal_callback);
2063 }
2064 }
2065#endif
2066 auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr);
2067 auto thread_config_callback = [&custom_task_runners](
2068 const fml::Thread::ThreadConfig& config) {
2070 if (!custom_task_runners || !custom_task_runners->thread_priority_setter) {
2071 return;
2072 }
2074 switch (config.priority) {
2077 break;
2080 break;
2083 break;
2086 break;
2087 }
2088 custom_task_runners->thread_priority_setter(priority);
2089 };
2090 auto thread_host =
2092 custom_task_runners, thread_config_callback);
2093
2094 if (!thread_host || !thread_host->IsValid()) {
2096 "Could not set up or infer thread configuration "
2097 "to run the Flutter engine on.");
2098 }
2099
2100 auto task_runners = thread_host->GetTaskRunners();
2101
2102 if (!task_runners.IsValid()) {
2104 "Task runner configuration was invalid.");
2105 }
2106
2107 auto run_configuration =
2109
2110 if (SAFE_ACCESS(args, custom_dart_entrypoint, nullptr) != nullptr) {
2111 auto dart_entrypoint = std::string{args->custom_dart_entrypoint};
2112 if (!dart_entrypoint.empty()) {
2113 run_configuration.SetEntrypoint(std::move(dart_entrypoint));
2114 }
2115 }
2116
2117 if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
2118 if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
2120 "Could not determine Dart entrypoint arguments "
2121 "as dart_entrypoint_argc "
2122 "was set, but dart_entrypoint_argv was null.");
2123 }
2124 std::vector<std::string> arguments(args->dart_entrypoint_argc);
2125 for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
2126 arguments[i] = std::string{args->dart_entrypoint_argv[i]};
2127 }
2128 run_configuration.SetEntrypointArgs(std::move(arguments));
2129 }
2130
2131 if (!run_configuration.IsValid()) {
2132 return LOG_EMBEDDER_ERROR(
2134 "Could not infer the Flutter project to run from given arguments.");
2135 }
2136
2137 // Create the engine but don't launch the shell or run the root isolate.
2138 auto embedder_engine = std::make_unique<flutter::EmbedderEngine>(
2139 std::move(thread_host), //
2140 std::move(task_runners), //
2141 std::move(settings), //
2142 std::move(run_configuration), //
2143 on_create_platform_view, //
2144 on_create_rasterizer, //
2145 std::move(external_texture_resolver) //
2146 );
2147
2148 // Release the ownership of the embedder engine to the caller.
2149 *engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(
2150 embedder_engine.release());
2151 return kSuccess;
2152}
2153
2156 if (!engine) {
2157 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2158 }
2159
2160 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2161
2162 // The engine must not already be running. Initialize may only be called
2163 // once on an engine instance.
2164 if (embedder_engine->IsValid()) {
2165 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2166 }
2167
2168 // Step 1: Launch the shell.
2169 if (!embedder_engine->LaunchShell()) {
2171 "Could not launch the engine using supplied "
2172 "initialization arguments.");
2173 }
2174
2175 // Step 2: Tell the platform view to initialize itself.
2176 if (!embedder_engine->NotifyCreated()) {
2178 "Could not create platform view components.");
2179 }
2180
2181 // Step 3: Launch the root isolate.
2182 if (!embedder_engine->RunRootIsolate()) {
2183 return LOG_EMBEDDER_ERROR(
2185 "Could not run the root isolate of the Flutter application using the "
2186 "project arguments specified.");
2187 }
2188
2189 return kSuccess;
2190}
2191
2194 engine,
2195 const FlutterAddViewInfo* info) {
2196 if (!engine) {
2197 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2198 }
2199 if (!info || !info->view_metrics || !info->add_view_callback) {
2201 "Add view info handle was invalid.");
2202 }
2203
2204 FlutterViewId view_id = info->view_id;
2205 if (view_id == kFlutterImplicitViewId) {
2206 return LOG_EMBEDDER_ERROR(
2208 "Add view info was invalid. The implicit view cannot be added.");
2209 }
2210 if (SAFE_ACCESS(info->view_metrics, view_id, kFlutterImplicitViewId) !=
2211 view_id) {
2212 if (view_id == kFlutterImplicitViewId) {
2214 "Add view info was invalid. The info and "
2215 "window metric view IDs must match.");
2216 }
2217 }
2218
2219 // TODO(loicsharma): Return an error if the engine was initialized with
2220 // callbacks that are incompatible with multiple views.
2221 // https://github.com/flutter/flutter/issues/144806
2222
2223 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2225
2226 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2227 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2228 }
2229
2230 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2231
2232 // The engine must be running to add a view.
2233 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2234 if (!embedder_engine->IsValid()) {
2235 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2236 }
2237
2239 [c_callback = info->add_view_callback,
2240 user_data = info->user_data](bool added) {
2242 result.struct_size = sizeof(FlutterAddViewResult);
2243 result.added = added;
2244 result.user_data = user_data;
2245 c_callback(&result);
2246 };
2247
2248 embedder_engine->GetShell().GetPlatformView()->AddView(view_id, metrics,
2249 callback);
2250 return kSuccess;
2251}
2252
2255 engine,
2256 const FlutterRemoveViewInfo* info) {
2257 if (!engine) {
2258 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2259 }
2260 if (!info || !info->remove_view_callback) {
2262 "Remove view info handle was invalid.");
2263 }
2264
2265 if (info->view_id == kFlutterImplicitViewId) {
2266 return LOG_EMBEDDER_ERROR(
2268 "Remove view info was invalid. The implicit view cannot be removed.");
2269 }
2270
2271 // TODO(loicsharma): Return an error if the engine was initialized with
2272 // callbacks that are incompatible with multiple views.
2273 // https://github.com/flutter/flutter/issues/144806
2274
2275 // The engine must be running to remove a view.
2276 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2277 if (!embedder_engine->IsValid()) {
2278 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2279 }
2280
2282 [c_callback = info->remove_view_callback,
2283 user_data = info->user_data](bool removed) {
2285 result.struct_size = sizeof(FlutterRemoveViewResult);
2286 result.removed = removed;
2287 result.user_data = user_data;
2288 c_callback(&result);
2289 };
2290
2291 embedder_engine->GetShell().GetPlatformView()->RemoveView(info->view_id,
2292 callback);
2293 return kSuccess;
2294}
2295
2298 engine) {
2299 if (engine == nullptr) {
2300 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2301 }
2302
2303 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2304 embedder_engine->NotifyDestroyed();
2305 embedder_engine->CollectShell();
2306 return kSuccess;
2307}
2308
2310 engine) {
2312 if (result != kSuccess) {
2313 return result;
2314 }
2315 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2316 delete embedder_engine;
2317 return kSuccess;
2318}
2319
2322 const FlutterWindowMetricsEvent* flutter_metrics) {
2323 if (engine == nullptr || flutter_metrics == nullptr) {
2324 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2325 }
2326 FlutterViewId view_id =
2327 SAFE_ACCESS(flutter_metrics, view_id, kFlutterImplicitViewId);
2328
2329 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2330 MakeViewportMetricsFromWindowMetrics(flutter_metrics);
2331 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2332 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2333 }
2334
2335 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2336
2337 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
2338 view_id, metrics)
2339 ? kSuccess
2341 "Viewport metrics were invalid.");
2342}
2343
2344// Returns the flutter::PointerData::Change for the given FlutterPointerPhase.
2346 FlutterPointerPhase phase) {
2347 switch (phase) {
2348 case kCancel:
2350 case kUp:
2352 case kDown:
2354 case kMove:
2356 case kAdd:
2358 case kRemove:
2360 case kHover:
2362 case kPanZoomStart:
2364 case kPanZoomUpdate:
2366 case kPanZoomEnd:
2368 }
2370}
2371
2372// Returns the flutter::PointerData::DeviceKind for the given
2373// FlutterPointerDeviceKind.
2375 FlutterPointerDeviceKind device_kind) {
2376 switch (device_kind) {
2385 }
2387}
2388
2389// Returns the flutter::PointerData::SignalKind for the given
2390// FlutterPointerSignaKind.
2393 switch (kind) {
2402 }
2404}
2405
2406// Returns the buttons to synthesize for a PointerData from a
2407// FlutterPointerEvent with no type or buttons set.
2410 switch (change) {
2413 // These kinds of change must have a non-zero `buttons`, otherwise
2414 // gesture recognizers will ignore these events.
2424 return 0;
2425 }
2426 return 0;
2427}
2428
2431 const FlutterPointerEvent* pointers,
2432 size_t events_count) {
2433 if (engine == nullptr) {
2434 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2435 }
2436
2437 if (pointers == nullptr || events_count == 0) {
2438 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid pointer events.");
2439 }
2440
2441 auto packet = std::make_unique<flutter::PointerDataPacket>(events_count);
2442
2443 const FlutterPointerEvent* current = pointers;
2444
2445 for (size_t i = 0; i < events_count; ++i) {
2446 flutter::PointerData pointer_data;
2447 pointer_data.Clear();
2448 // this is currely in use only on android embedding.
2449 pointer_data.embedder_id = 0;
2450 pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
2451 pointer_data.change = ToPointerDataChange(
2452 SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
2453 pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
2454 pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
2455 // Delta will be generated in pointer_data_packet_converter.cc.
2456 pointer_data.physical_delta_x = 0.0;
2457 pointer_data.physical_delta_y = 0.0;
2458 pointer_data.device = SAFE_ACCESS(current, device, 0);
2459 // Pointer identifier will be generated in
2460 // pointer_data_packet_converter.cc.
2461 pointer_data.pointer_identifier = 0;
2462 pointer_data.signal_kind = ToPointerDataSignalKind(
2463 SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
2464 pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
2465 pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
2466 FlutterPointerDeviceKind device_kind =
2467 SAFE_ACCESS(current, device_kind, kFlutterPointerDeviceKindMouse);
2468 // For backwards compatibility with embedders written before the device
2469 // kind and buttons were exposed, if the device kind is not set treat it
2470 // as a mouse, with a synthesized primary button state based on the phase.
2471 if (device_kind == 0) {
2473 pointer_data.buttons =
2475
2476 } else {
2477 pointer_data.kind = ToPointerDataKind(device_kind);
2478 if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
2479 // For touch events, set the button internally rather than requiring
2480 // it at the API level, since it's a confusing construction to expose.
2481 if (pointer_data.change == flutter::PointerData::Change::kDown ||
2484 }
2485 } else {
2486 // Buttons use the same mask values, so pass them through directly.
2487 pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
2488 }
2489 }
2490 pointer_data.pan_x = SAFE_ACCESS(current, pan_x, 0.0);
2491 pointer_data.pan_y = SAFE_ACCESS(current, pan_y, 0.0);
2492 // Delta will be generated in pointer_data_packet_converter.cc.
2493 pointer_data.pan_delta_x = 0.0;
2494 pointer_data.pan_delta_y = 0.0;
2495 pointer_data.scale = SAFE_ACCESS(current, scale, 0.0);
2496 pointer_data.rotation = SAFE_ACCESS(current, rotation, 0.0);
2497 pointer_data.view_id =
2498 SAFE_ACCESS(current, view_id, kFlutterImplicitViewId);
2499 packet->SetPointerData(i, pointer_data);
2500 current = reinterpret_cast<const FlutterPointerEvent*>(
2501 reinterpret_cast<const uint8_t*>(current) + current->struct_size);
2502 }
2503
2504 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2505 ->DispatchPointerDataPacket(std::move(packet))
2506 ? kSuccess
2508 "Could not dispatch pointer events to the "
2509 "running Flutter application.");
2510}
2511
2513 FlutterKeyEventType event_kind) {
2514 switch (event_kind) {
2521 }
2523}
2524
2526 FlutterKeyEventDeviceType event_kind) {
2527 switch (event_kind) {
2538 }
2540}
2541
2542// Send a platform message to the framework.
2543//
2544// The `data_callback` will be invoked with `user_data`, and must not be empty.
2547 const char* channel,
2548 const uint8_t* data,
2549 size_t size,
2550 FlutterDataCallback data_callback,
2551 void* user_data) {
2553
2554 FlutterPlatformMessageResponseHandle* response_handle;
2556 engine, data_callback, user_data, &response_handle);
2557 if (result != kSuccess) {
2558 return result;
2559 }
2560
2562 sizeof(FlutterPlatformMessage), // struct_size
2563 channel, // channel
2564 data, // message
2565 size, // message_size
2566 response_handle, // response_handle
2567 };
2568
2570 // Whether `SendPlatformMessage` succeeds or not, the response handle must be
2571 // released.
2572 FlutterEngineResult release_result =
2574 if (result != kSuccess) {
2575 return result;
2576 }
2577
2578 return release_result;
2579}
2580
2582 engine,
2583 const FlutterKeyEvent* event,
2585 void* user_data) {
2586 if (engine == nullptr) {
2587 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2588 }
2589
2590 if (event == nullptr) {
2591 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid key event.");
2592 }
2593
2594 const char* character = SAFE_ACCESS(event, character, nullptr);
2595
2596 flutter::KeyData key_data;
2597 key_data.Clear();
2598 key_data.timestamp = static_cast<uint64_t>(SAFE_ACCESS(event, timestamp, 0));
2599 key_data.type = MapKeyEventType(
2601 key_data.physical = SAFE_ACCESS(event, physical, 0);
2602 key_data.logical = SAFE_ACCESS(event, logical, 0);
2603 key_data.synthesized = SAFE_ACCESS(event, synthesized, false);
2605 event, device_type,
2607
2608 auto packet = std::make_unique<flutter::KeyDataPacket>(key_data, character);
2609
2610 struct MessageData {
2612 void* user_data;
2613 };
2614
2615 MessageData* message_data =
2616 new MessageData{.callback = callback, .user_data = user_data};
2617
2619 engine, kFlutterKeyDataChannel, packet->data().data(),
2620 packet->data().size(),
2621 [](const uint8_t* data, size_t size, void* user_data) {
2622 auto message_data = std::unique_ptr<MessageData>(
2623 reinterpret_cast<MessageData*>(user_data));
2624 if (message_data->callback == nullptr) {
2625 return;
2626 }
2627 bool handled = false;
2628 if (size == 1) {
2629 handled = *data != 0;
2630 }
2631 message_data->callback(handled, message_data->user_data);
2632 },
2633 message_data);
2634}
2635
2638 const FlutterPlatformMessage* flutter_message) {
2639 if (engine == nullptr) {
2640 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2641 }
2642
2643 if (flutter_message == nullptr) {
2644 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid message argument.");
2645 }
2646
2647 if (SAFE_ACCESS(flutter_message, channel, nullptr) == nullptr) {
2648 return LOG_EMBEDDER_ERROR(
2649 kInvalidArguments, "Message argument did not specify a valid channel.");
2650 }
2651
2652 size_t message_size = SAFE_ACCESS(flutter_message, message_size, 0);
2653 const uint8_t* message_data = SAFE_ACCESS(flutter_message, message, nullptr);
2654
2655 if (message_size != 0 && message_data == nullptr) {
2656 return LOG_EMBEDDER_ERROR(
2658 "Message size was non-zero but the message data was nullptr.");
2659 }
2660
2661 const FlutterPlatformMessageResponseHandle* response_handle =
2662 SAFE_ACCESS(flutter_message, response_handle, nullptr);
2663
2665 if (response_handle && response_handle->message) {
2666 response = response_handle->message->response();
2667 }
2668
2669 std::unique_ptr<flutter::PlatformMessage> message;
2670 if (message_size == 0) {
2671 message = std::make_unique<flutter::PlatformMessage>(
2672 flutter_message->channel, response);
2673 } else {
2674 message = std::make_unique<flutter::PlatformMessage>(
2675 flutter_message->channel,
2676 fml::MallocMapping::Copy(message_data, message_size), response);
2677 }
2678
2679 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2680 ->SendPlatformMessage(std::move(message))
2681 ? kSuccess
2683 "Could not send a message to the running "
2684 "Flutter application.");
2685}
2686
2689 FlutterDataCallback data_callback,
2690 void* user_data,
2691 FlutterPlatformMessageResponseHandle** response_out) {
2692 if (engine == nullptr) {
2693 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2694 }
2695
2696 if (data_callback == nullptr || response_out == nullptr) {
2697 return LOG_EMBEDDER_ERROR(
2698 kInvalidArguments, "Data callback or the response handle was invalid.");
2699 }
2700
2702 [user_data, data_callback](const uint8_t* data, size_t size) {
2703 data_callback(data, size, user_data);
2704 };
2705
2706 auto platform_task_runner = reinterpret_cast<flutter::EmbedderEngine*>(engine)
2707 ->GetTaskRunners()
2708 .GetPlatformTaskRunner();
2709
2710 auto handle = new FlutterPlatformMessageResponseHandle();
2711
2712 handle->message = std::make_unique<flutter::PlatformMessage>(
2713 "", // The channel is empty and unused as the response handle is going
2714 // to referenced directly in the |FlutterEngineSendPlatformMessage|
2715 // with the container message discarded.
2716 fml::MakeRefCounted<flutter::EmbedderPlatformMessageResponse>(
2717 std::move(platform_task_runner), response_callback));
2718 *response_out = handle;
2719 return kSuccess;
2720}
2721
2725 if (engine == nullptr) {
2726 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2727 }
2728
2729 if (response == nullptr) {
2730 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid response handle.");
2731 }
2732 delete response;
2733 return kSuccess;
2734}
2735
2736// Note: This can execute on any thread.
2740 const uint8_t* data,
2741 size_t data_length) {
2742 if (data_length != 0 && data == nullptr) {
2743 return LOG_EMBEDDER_ERROR(
2745 "Data size was non zero but the pointer to the data was null.");
2746 }
2747
2748 auto response = handle->message->response();
2749
2750 if (response) {
2751 if (data_length == 0) {
2752 response->CompleteEmpty();
2753 } else {
2754 response->Complete(std::make_unique<fml::DataMapping>(
2755 std::vector<uint8_t>({data, data + data_length})));
2756 }
2757 }
2758
2759 delete handle;
2760
2761 return kSuccess;
2762}
2763
2766 return kSuccess;
2767}
2768
2771 int64_t texture_identifier) {
2772 if (engine == nullptr) {
2773 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2774 }
2775
2776 if (texture_identifier == 0) {
2778 "Texture identifier was invalid.");
2779 }
2780 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->RegisterTexture(
2781 texture_identifier)) {
2783 "Could not register the specified texture.");
2784 }
2785 return kSuccess;
2786}
2787
2790 int64_t texture_identifier) {
2791 if (engine == nullptr) {
2792 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2793 }
2794
2795 if (texture_identifier == 0) {
2797 "Texture identifier was invalid.");
2798 }
2799
2800 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->UnregisterTexture(
2801 texture_identifier)) {
2803 "Could not un-register the specified texture.");
2804 }
2805
2806 return kSuccess;
2807}
2808
2811 int64_t texture_identifier) {
2812 if (engine == nullptr) {
2813 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2814 }
2815 if (texture_identifier == 0) {
2816 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid texture identifier.");
2817 }
2818 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
2819 ->MarkTextureFrameAvailable(texture_identifier)) {
2820 return LOG_EMBEDDER_ERROR(
2822 "Could not mark the texture frame as being available.");
2823 }
2824 return kSuccess;
2825}
2826
2829 bool enabled) {
2830 if (engine == nullptr) {
2831 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2832 }
2833 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetSemanticsEnabled(
2834 enabled)) {
2836 "Could not update semantics state.");
2837 }
2838 return kSuccess;
2839}
2840
2844 if (engine == nullptr) {
2845 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2846 }
2847 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
2850 "Could not update accessibility features.");
2851 }
2852 return kSuccess;
2853}
2854
2857 uint64_t node_id,
2859 const uint8_t* data,
2860 size_t data_length) {
2861 if (engine == nullptr) {
2862 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2863 }
2864 auto engine_action = static_cast<flutter::SemanticsAction>(action);
2865 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
2867 node_id, engine_action,
2868 fml::MallocMapping::Copy(data, data_length))) {
2870 "Could not dispatch semantics action.");
2871 }
2872 return kSuccess;
2873}
2874
2876 engine,
2877 intptr_t baton,
2878 uint64_t frame_start_time_nanos,
2879 uint64_t frame_target_time_nanos) {
2880 if (engine == nullptr) {
2881 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2882 }
2883
2884 TRACE_EVENT0("flutter", "FlutterEngineOnVsync");
2885
2886 auto start_time = fml::TimePoint::FromEpochDelta(
2887 fml::TimeDelta::FromNanoseconds(frame_start_time_nanos));
2888
2889 auto target_time = fml::TimePoint::FromEpochDelta(
2890 fml::TimeDelta::FromNanoseconds(frame_target_time_nanos));
2891
2892 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->OnVsyncEvent(
2893 baton, start_time, target_time)) {
2894 return LOG_EMBEDDER_ERROR(
2896 "Could not notify the running engine instance of a Vsync event.");
2897 }
2898
2899 return kSuccess;
2900}
2901
2904 if (engine == nullptr) {
2905 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2906 }
2907
2908 TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");
2909
2910 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
2911 ->ReloadSystemFonts()) {
2913 "Could not reload system fonts.");
2914 }
2915
2916 return kSuccess;
2917}
2918
2920 fml::tracing::TraceEvent0("flutter", name, /*flow_id_count=*/0,
2921 /*flow_ids=*/nullptr);
2922}
2923
2926}
2927
2929 fml::tracing::TraceEventInstant0("flutter", name, /*flow_id_count=*/0,
2930 /*flow_ids=*/nullptr);
2931}
2932
2936 void* baton) {
2937 if (engine == nullptr) {
2938 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2939 }
2940
2941 if (callback == nullptr) {
2943 "Render thread callback was null.");
2944 }
2945
2946 auto task = [callback, baton]() { callback(baton); };
2947
2948 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2949 ->PostRenderThreadTask(task)
2950 ? kSuccess
2952 "Could not post the render thread task.");
2953}
2954
2957}
2958
2960 engine,
2961 const FlutterTask* task) {
2962 if (engine == nullptr) {
2963 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2964 }
2965
2966 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->RunTask(task)
2967 ? kSuccess
2969 "Could not run the specified task.");
2970}
2971
2973 engine,
2974 const rapidjson::Document& document,
2975 const std::string& channel_name) {
2976 if (channel_name.empty()) {
2977 return false;
2978 }
2979
2980 rapidjson::StringBuffer buffer;
2981 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
2982
2983 if (!document.Accept(writer)) {
2984 return false;
2985 }
2986
2987 const char* message = buffer.GetString();
2988
2989 if (message == nullptr || buffer.GetSize() == 0) {
2990 return false;
2991 }
2992
2993 auto platform_message = std::make_unique<flutter::PlatformMessage>(
2994 channel_name.c_str(), // channel
2996 buffer.GetSize()), // message
2997 nullptr // response
2998 );
2999
3000 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3001 ->SendPlatformMessage(std::move(platform_message));
3002}
3003
3005 engine,
3006 const FlutterLocale** locales,
3007 size_t locales_count) {
3008 if (engine == nullptr) {
3009 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3010 }
3011
3012 if (locales_count == 0) {
3013 return kSuccess;
3014 }
3015
3016 if (locales == nullptr) {
3017 return LOG_EMBEDDER_ERROR(kInvalidArguments, "No locales were specified.");
3018 }
3019
3020 rapidjson::Document document;
3021 auto& allocator = document.GetAllocator();
3022
3023 document.SetObject();
3024 document.AddMember("method", "setLocale", allocator);
3025
3026 rapidjson::Value args(rapidjson::kArrayType);
3027 args.Reserve(locales_count * 4, allocator);
3028 for (size_t i = 0; i < locales_count; ++i) {
3029 const FlutterLocale* locale = locales[i];
3030 const char* language_code_str = SAFE_ACCESS(locale, language_code, nullptr);
3031 if (language_code_str == nullptr || ::strlen(language_code_str) == 0) {
3032 return LOG_EMBEDDER_ERROR(
3034 "Language code is required but not present in FlutterLocale.");
3035 }
3036
3037 const char* country_code_str = SAFE_ACCESS(locale, country_code, "");
3038 const char* script_code_str = SAFE_ACCESS(locale, script_code, "");
3039 const char* variant_code_str = SAFE_ACCESS(locale, variant_code, "");
3040
3041 rapidjson::Value language_code, country_code, script_code, variant_code;
3042
3043 language_code.SetString(language_code_str, allocator);
3044 country_code.SetString(country_code_str ? country_code_str : "", allocator);
3045 script_code.SetString(script_code_str ? script_code_str : "", allocator);
3046 variant_code.SetString(variant_code_str ? variant_code_str : "", allocator);
3047
3048 // Required.
3049 args.PushBack(language_code, allocator);
3050 args.PushBack(country_code, allocator);
3051 args.PushBack(script_code, allocator);
3052 args.PushBack(variant_code, allocator);
3053 }
3054 document.AddMember("args", args, allocator);
3055
3056 return DispatchJSONPlatformMessage(engine, document, "flutter/localization")
3057 ? kSuccess
3059 "Could not send message to update locale of "
3060 "a running Flutter application.");
3061}
3062
3065}
3066
3070 const FlutterEngineDartObject* object) {
3071 if (engine == nullptr) {
3072 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3073 }
3074
3075 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->IsValid()) {
3076 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine not running.");
3077 }
3078
3079 if (port == ILLEGAL_PORT) {
3081 "Attempted to post to an illegal port.");
3082 }
3083
3084 if (object == nullptr) {
3086 "Invalid Dart object to post.");
3087 }
3088
3089 Dart_CObject dart_object = {};
3090 fml::ScopedCleanupClosure typed_data_finalizer;
3091
3092 switch (object->type) {
3094 dart_object.type = Dart_CObject_kNull;
3095 break;
3097 dart_object.type = Dart_CObject_kBool;
3098 dart_object.value.as_bool = object->bool_value;
3099 break;
3101 dart_object.type = Dart_CObject_kInt32;
3102 dart_object.value.as_int32 = object->int32_value;
3103 break;
3105 dart_object.type = Dart_CObject_kInt64;
3106 dart_object.value.as_int64 = object->int64_value;
3107 break;
3109 dart_object.type = Dart_CObject_kDouble;
3110 dart_object.value.as_double = object->double_value;
3111 break;
3113 if (object->string_value == nullptr) {
3115 "kFlutterEngineDartObjectTypeString must be "
3116 "a null terminated string but was null.");
3117 }
3118 dart_object.type = Dart_CObject_kString;
3119 dart_object.value.as_string = const_cast<char*>(object->string_value);
3120 break;
3122 auto* buffer = SAFE_ACCESS(object->buffer_value, buffer, nullptr);
3123 if (buffer == nullptr) {
3125 "kFlutterEngineDartObjectTypeBuffer must "
3126 "specify a buffer but found nullptr.");
3127 }
3128 auto buffer_size = SAFE_ACCESS(object->buffer_value, buffer_size, 0);
3129 auto callback =
3130 SAFE_ACCESS(object->buffer_value, buffer_collect_callback, nullptr);
3131 auto user_data = SAFE_ACCESS(object->buffer_value, user_data, nullptr);
3132
3133 // The user has provided a callback, let them manage the lifecycle of
3134 // the underlying data. If not, copy it out from the provided buffer.
3135
3136 if (callback == nullptr) {
3137 dart_object.type = Dart_CObject_kTypedData;
3139 dart_object.value.as_typed_data.length = buffer_size;
3140 dart_object.value.as_typed_data.values = buffer;
3141 } else {
3142 struct ExternalTypedDataPeer {
3143 void* user_data = nullptr;
3144 VoidCallback trampoline = nullptr;
3145 };
3146 auto peer = new ExternalTypedDataPeer();
3147 peer->user_data = user_data;
3148 peer->trampoline = callback;
3149 // This finalizer is set so that in case of failure of the
3150 // Dart_PostCObject below, we collect the peer. The embedder is still
3151 // responsible for collecting the buffer in case of non-kSuccess
3152 // returns from this method. This finalizer must be released in case
3153 // of kSuccess returns from this method.
3154 typed_data_finalizer.SetClosure([peer]() {
3155 // This is the tiny object we use as the peer to the Dart call so
3156 // that we can attach the a trampoline to the embedder supplied
3157 // callback. In case of error, we need to collect this object lest
3158 // we introduce a tiny leak.
3159 delete peer;
3160 });
3165 dart_object.value.as_external_typed_data.peer = peer;
3167 +[](void* unused_isolate_callback_data, void* peer) {
3168 auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
3169 typed_peer->trampoline(typed_peer->user_data);
3170 delete typed_peer;
3171 };
3172 }
3173 } break;
3174 default:
3175 return LOG_EMBEDDER_ERROR(
3177 "Invalid FlutterEngineDartObjectType type specified.");
3178 }
3179
3180 if (!Dart_PostCObject(port, &dart_object)) {
3182 "Could not post the object to the Dart VM.");
3183 }
3184
3185 // On a successful call, the VM takes ownership of and is responsible for
3186 // invoking the finalizer.
3187 typed_data_finalizer.Release();
3188 return kSuccess;
3189}
3190
3192 FLUTTER_API_SYMBOL(FlutterEngine) raw_engine) {
3193 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3194 if (engine == nullptr || !engine->IsValid()) {
3195 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
3196 }
3197
3198 engine->GetShell().NotifyLowMemoryWarning();
3199
3200 rapidjson::Document document;
3201 auto& allocator = document.GetAllocator();
3202
3203 document.SetObject();
3204 document.AddMember("type", "memoryPressure", allocator);
3205
3206 return DispatchJSONPlatformMessage(raw_engine, document, "flutter/system")
3207 ? kSuccess
3210 "Could not dispatch the low memory notification message.");
3211}
3212
3216 void* user_data) {
3217 if (engine == nullptr) {
3218 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3219 }
3220
3221 if (callback == nullptr) {
3223 "Invalid native thread callback.");
3224 }
3225
3226 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3227 ->PostTaskOnEngineManagedNativeThreads(
3230 })
3231 ? kSuccess
3233 "Internal error while attempting to post "
3234 "tasks to all threads.");
3235}
3236
3237namespace {
3238static bool ValidDisplayConfiguration(const FlutterEngineDisplay* displays,
3239 size_t display_count) {
3240 std::set<FlutterEngineDisplayId> display_ids;
3241 for (size_t i = 0; i < display_count; i++) {
3242 if (displays[i].single_display && display_count != 1) {
3243 return false;
3244 }
3245 display_ids.insert(displays[i].display_id);
3246 }
3247
3248 return display_ids.size() == display_count;
3249}
3250} // namespace
3251
3254 const FlutterEngineDisplaysUpdateType update_type,
3255 const FlutterEngineDisplay* embedder_displays,
3256 size_t display_count) {
3257 if (raw_engine == nullptr) {
3258 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3259 }
3260
3261 if (!ValidDisplayConfiguration(embedder_displays, display_count)) {
3262 return LOG_EMBEDDER_ERROR(
3264 "Invalid FlutterEngineDisplay configuration specified.");
3265 }
3266
3267 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3268
3269 switch (update_type) {
3271 std::vector<std::unique_ptr<flutter::Display>> displays;
3272 const auto* display = embedder_displays;
3273 for (size_t i = 0; i < display_count; i++) {
3274 displays.push_back(std::make_unique<flutter::Display>(
3275 SAFE_ACCESS(display, display_id, i), //
3276 SAFE_ACCESS(display, refresh_rate, 0), //
3277 SAFE_ACCESS(display, width, 0), //
3278 SAFE_ACCESS(display, height, 0), //
3279 SAFE_ACCESS(display, device_pixel_ratio, 1)));
3280 display = reinterpret_cast<const FlutterEngineDisplay*>(
3281 reinterpret_cast<const uint8_t*>(display) + display->struct_size);
3282 }
3283 engine->GetShell().OnDisplayUpdates(std::move(displays));
3284 return kSuccess;
3285 }
3286 default:
3287 return LOG_EMBEDDER_ERROR(
3289 "Invalid FlutterEngineDisplaysUpdateType type specified.");
3290 }
3291}
3292
3294 engine) {
3295 if (engine == nullptr) {
3296 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3297 }
3298
3299 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->ScheduleFrame()
3300 ? kSuccess
3302 "Could not schedule frame.");
3303}
3304
3308 void* user_data) {
3309 if (engine == nullptr) {
3310 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3311 }
3312
3313 if (callback == nullptr) {
3315 "Next frame callback was null.");
3316 }
3317
3318 flutter::EmbedderEngine* embedder_engine =
3319 reinterpret_cast<flutter::EmbedderEngine*>(engine);
3320
3321 fml::WeakPtr<flutter::PlatformView> weak_platform_view =
3322 embedder_engine->GetShell().GetPlatformView();
3323
3324 if (!weak_platform_view) {
3326 "Platform view unavailable.");
3327 }
3328
3329 weak_platform_view->SetNextFrameCallback(
3331
3332 return kSuccess;
3333}
3334
3337 if (!table) {
3338 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null table specified.");
3339 }
3340#define SET_PROC(member, function) \
3341 if (STRUCT_HAS_MEMBER(table, member)) { \
3342 table->member = &function; \
3343 }
3344
3345 SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
3346 SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
3350 SET_PROC(Deinitialize, FlutterEngineDeinitialize);
3351 SET_PROC(RunInitialized, FlutterEngineRunInitialized);
3352 SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent);
3353 SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent);
3354 SET_PROC(SendKeyEvent, FlutterEngineSendKeyEvent);
3355 SET_PROC(SendPlatformMessage, FlutterEngineSendPlatformMessage);
3356 SET_PROC(PlatformMessageCreateResponseHandle,
3358 SET_PROC(PlatformMessageReleaseResponseHandle,
3360 SET_PROC(SendPlatformMessageResponse,
3362 SET_PROC(RegisterExternalTexture, FlutterEngineRegisterExternalTexture);
3363 SET_PROC(UnregisterExternalTexture, FlutterEngineUnregisterExternalTexture);
3364 SET_PROC(MarkExternalTextureFrameAvailable,
3366 SET_PROC(UpdateSemanticsEnabled, FlutterEngineUpdateSemanticsEnabled);
3367 SET_PROC(UpdateAccessibilityFeatures,
3371 SET_PROC(ReloadSystemFonts, FlutterEngineReloadSystemFonts);
3372 SET_PROC(TraceEventDurationBegin, FlutterEngineTraceEventDurationBegin);
3373 SET_PROC(TraceEventDurationEnd, FlutterEngineTraceEventDurationEnd);
3374 SET_PROC(TraceEventInstant, FlutterEngineTraceEventInstant);
3375 SET_PROC(PostRenderThreadTask, FlutterEnginePostRenderThreadTask);
3378 SET_PROC(UpdateLocales, FlutterEngineUpdateLocales);
3379 SET_PROC(RunsAOTCompiledDartCode, FlutterEngineRunsAOTCompiledDartCode);
3380 SET_PROC(PostDartObject, FlutterEnginePostDartObject);
3382 SET_PROC(PostCallbackOnAllNativeThreads,
3384 SET_PROC(NotifyDisplayUpdate, FlutterEngineNotifyDisplayUpdate);
3386 SET_PROC(SetNextFrameCallback, FlutterEngineSetNextFrameCallback);
3388 SET_PROC(RemoveView, FlutterEngineRemoveView);
3389#undef SET_PROC
3390
3391 return kSuccess;
3392}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kUnknown_SkPixelGeometry
SI F table(const skcms_Curve *curve, F v)
GLenum type
static sk_sp< SkColorSpace > MakeSRGB()
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition: SkMatrix.h:179
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:205
bool DispatchSemanticsAction(int node_id, flutter::SemanticsAction action, fml::MallocMapping args)
std::function< std::unique_ptr< FlutterOpenGLTexture >(int64_t, size_t, size_t)> ExternalTextureCallback
std::function< std::unique_ptr< FlutterMetalExternalTexture >(int64_t, size_t, size_t)> ExternalTextureCallback
std::function< bool(FlutterViewId view_id, const std::vector< const FlutterLayer * > &layers)> PresentCallback
std::function< std::unique_ptr< EmbedderRenderTarget >(GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, const FlutterBackingStoreConfig &config)> CreateRenderTargetCallback
std::function< void(const uint8_t *data, size_t size)> Callback
static std::unique_ptr< EmbedderThreadHost > CreateEmbedderOrEngineManagedThreadHost(const FlutterCustomTaskRunners *custom_task_runners, const flutter::ThreadConfigSetter &config_setter=fml::Thread::SetCurrentThreadName)
std::function< void *(const char *)> GLProcResolver
static SkColorType ColorTypeFromFormat(const VkFormat format)
static void SetCacheDirectoryPath(std::string path)
std::function< void()> OnPreEngineRestartCallback
std::function< void(std::unique_ptr< PlatformMessage >)> PlatformMessageResponseCallback
std::function< std::unique_ptr< std::vector< std::string > >(const std::vector< std::string > &supported_locale_data)> ComputePlatformResolvedLocaleCallback
std::function< void(const std::string &, bool)> ChanneUpdateCallback
std::function< void(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions)> UpdateSemanticsCallback
std::function< void(bool removed)> RemoveViewCallback
Definition: platform_view.h:54
void SetNextFrameCallback(const fml::closure &closure)
Sets a callback that gets executed when the rasterizer renders the next frame. Due to the asynchronou...
std::function< void(bool added)> AddViewCallback
Definition: platform_view.h:53
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...
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition: shell.h:120
fml::WeakPtr< PlatformView > GetPlatformView()
Platform views may only be accessed on the platform task runner.
Definition: shell.cc:824
std::function< void(intptr_t)> VsyncCallback
static std::unique_ptr< FileMapping > CreateReadExecute(const std::string &path)
Definition: mapping.cc:44
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)
Definition: message_loop.cc:68
void AddTaskObserver(intptr_t key, const fml::closure &callback)
Definition: message_loop.cc:64
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
void RunExpiredTasksNow()
Definition: message_loop.cc:72
static fml::RefPtr< NativeLibrary > CreateForCurrentProcess()
static fml::RefPtr< NativeLibrary > Create(const char *path)
const uint8_t * ResolveSymbol(const char *symbol)
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
fml::closure SetClosure(const fml::closure &closure)
Definition: closure.h:50
fml::closure Release()
Definition: closure.h:56
@ kNormal
Default priority level.
@ kRaster
Suitable for thread which raster data.
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
@ kDisplay
Suitable for threads which generate data for the display.
static void SetCurrentThreadName(const ThreadConfig &config)
Definition: thread.cc:135
static constexpr TimeDelta FromNanoseconds(int64_t nanos)
Definition: time_delta.h:40
constexpr int64_t ToNanoseconds() const
Definition: time_delta.h:61
TimeDelta ToEpochDelta() const
Definition: time_point.h:52
static TimePoint Now()
Definition: time_point.cc:49
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
Definition: time_point.h:43
static ContextGLES & Cast(Context &base)
Definition: backend_cast.h:13
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
static std::shared_ptr< TextureGLES > WrapFBO(ReactorGLES::Ref reactor, TextureDescriptor desc, GLuint fbo)
#define ILLEGAL_PORT
Definition: dart_api.h:1535
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
@ Dart_CObject_kInt64
@ Dart_CObject_kDouble
@ Dart_CObject_kTypedData
@ Dart_CObject_kString
@ Dart_CObject_kNull
@ Dart_CObject_kExternalTypedData
@ Dart_CObject_kInt32
@ Dart_CObject_kBool
DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject *message)
SkRect sk_rect
#define SET_PROC(member, function)
void FlutterEngineTraceEventInstant(const char *name)
A profiling utility. Logs a trace duration instant event to the timeline. If the timeline is unavaila...
Definition: embedder.cc:2928
static FlutterEngineResult InternalSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const char *channel, const uint8_t *data, size_t size, FlutterDataCallback data_callback, void *user_data)
Definition: embedder.cc:2545
FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Mark that a new texture frame is available for a given texture identifier.
Definition: embedder.cc:2809
FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterTask *task)
Inform the engine to run the specified task. This task has been given to the engine via the FlutterTa...
Definition: embedder.cc:2959
FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, intptr_t baton, uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos)
Notify the engine that a vsync event occurred. A baton passed to the platform via the vsync callback ...
Definition: embedder.cc:2875
const int32_t kFlutterSemanticsNodeIdBatchEnd
Definition: embedder.cc:105
const int32_t kFlutterSemanticsCustomActionIdBatchEnd
Definition: embedder.cc:106
static bool IsMetalRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:189
FlutterEngineResult FlutterEngineRun(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize and run a Flutter engine instance and return a handle to it. This is a convenience method ...
Definition: embedder.cc:1715
FlutterEngineResult FlutterEngineRegisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Register an external texture with a unique (per engine) identifier. Only rendering backends that supp...
Definition: embedder.cc:2769
FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterLocale **locales, size_t locales_count)
Notify a running engine instance that the locale has been updated. The preferred locale must be the f...
Definition: embedder.cc:3004
const uint8_t kPlatformStrongDill[]
static flutter::Shell::CreateCallback< flutter::PlatformView > InferPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
Definition: embedder.cc:713
FlutterEngineResult FlutterEngineGetProcAddresses(FlutterEngineProcTable *table)
Gets the table of engine function pointers.
Definition: embedder.cc:3335
static flutter::Shell::CreateCallback< flutter::PlatformView > InferVulkanPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:589
static bool DispatchJSONPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const rapidjson::Document &document, const std::string &channel_name)
Definition: embedder.cc:2972
FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Schedule a new frame to redraw the content.
Definition: embedder.cc:3293
void FlutterEngineTraceEventDurationBegin(const char *name)
A profiling utility. Logs a trace duration begin event to the timeline. If the timeline is unavailabl...
Definition: embedder.cc:2919
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
Definition: embedder.cc:2320
flutter::PointerData::SignalKind ToPointerDataSignalKind(FlutterPointerSignalKind kind)
Definition: embedder.cc:2391
static std::pair< std::unique_ptr< flutter::EmbedderExternalViewEmbedder >, bool > InferExternalViewEmbedderFromArgs(const FlutterCompositor *compositor, bool enable_impeller)
Definition: embedder.cc:1283
uint64_t FlutterEngineGetCurrentTime()
Get the current time in nanoseconds from the clock used by the flutter engine. This is the system mon...
Definition: embedder.cc:2955
static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:156
FlutterEngineResult FlutterEngineSetNextFrameCallback(FLUTTER_API_SYMBOL(FlutterEngine) engine, VoidCallback callback, void *user_data)
Schedule a callback to be called after the next frame is drawn. This must be called from the platform...
Definition: embedder.cc:3305
FlutterEngineResult __FlutterEngineFlushPendingTasksNow()
This API is only meant to be used by platforms that need to flush tasks on a message loop not control...
Definition: embedder.cc:2764
#define LOG_EMBEDDER_ERROR(code, reason)
Definition: embedder.cc:153
FlutterEngineResult FlutterEnginePostRenderThreadTask(FLUTTER_API_SYMBOL(FlutterEngine) engine, VoidCallback callback, void *baton)
Posts a task onto the Flutter render thread. Typically, this may be called from any thread as long as...
Definition: embedder.cc:2933
static flutter::KeyEventDeviceType MapKeyEventDeviceType(FlutterKeyEventDeviceType event_kind)
Definition: embedder.cc:2525
static bool IsRendererValid(const FlutterRendererConfig *config)
Definition: embedder.cc:227
static std::unique_ptr< flutter::EmbedderRenderTarget > MakeRenderTargetFromBackingStoreImpeller(FlutterBackingStore backing_store, const fml::closure &on_release, const std::shared_ptr< impeller::AiksContext > &aiks_context, const FlutterBackingStoreConfig &config, const FlutterOpenGLFramebuffer *framebuffer)
Definition: embedder.cc:965
std::unique_ptr< Dart_LoadedElf, LoadedElfDeleter > UniqueLoadedElf
Definition: embedder.cc:1416
FlutterEngineResult FlutterEngineDispatchSemanticsAction(FLUTTER_API_SYMBOL(FlutterEngine) engine, uint64_t node_id, FlutterSemanticsAction action, const uint8_t *data, size_t data_length)
Dispatch a semantics action to the specified semantics node.
Definition: embedder.cc:2855
FlutterEngineResult FlutterEnginePostDartObject(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterEngineDartPort port, const FlutterEngineDartObject *object)
Posts a Dart object to specified send port. The corresponding receive port for send port can be in an...
Definition: embedder.cc:3067
flutter::PointerData::DeviceKind ToPointerDataKind(FlutterPointerDeviceKind device_kind)
Definition: embedder.cc:2374
FLUTTER_EXPORT FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Stops running the Flutter engine instance. After this call, the embedder is also guaranteed that no m...
Definition: embedder.cc:2297
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore(GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLTexture *texture)
Definition: embedder.cc:748
flutter::PointerData::Change ToPointerDataChange(FlutterPointerPhase phase)
Definition: embedder.cc:2345
static constexpr FlutterViewId kFlutterImplicitViewId
Definition: embedder.cc:108
FlutterEngineResult FlutterEnginePostCallbackOnAllNativeThreads(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterNativeThreadCallback callback, void *user_data)
Schedule a callback to be run on all engine managed threads. The engine will attempt to service this ...
Definition: embedder.cc:3213
FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterAddViewInfo *info)
Adds a view.
Definition: embedder.cc:2193
FlutterEngineResult FlutterEngineInitialize(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize a Flutter engine instance. This does not run the Flutter application code till the Flutter...
Definition: embedder.cc:1731
static std::unique_ptr< flutter::EmbedderRenderTarget > CreateEmbedderRenderTarget(const FlutterCompositor *compositor, const FlutterBackingStoreConfig &config, GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, bool enable_impeller)
Definition: embedder.cc:1167
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV3(FlutterUpdateSemanticsCallback2 update_semantics_callback, void *user_data)
Definition: embedder.cc:1653
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterAccessibilityFeature flags)
Sets additional accessibility features.
Definition: embedder.cc:2841
FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Shuts down a Flutter engine instance. The engine handle is no longer valid for any calls in the embed...
Definition: embedder.cc:2309
static std::unique_ptr< flutter::EmbedderRenderTarget > MakeRenderTargetFromSkSurface(FlutterBackingStore backing_store, sk_sp< SkSurface > skia_surface, fml::closure on_release)
Definition: embedder.cc:1156
FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterDataCallback data_callback, void *user_data, FlutterPlatformMessageResponseHandle **response_out)
Creates a platform message response handle that allows the embedder to set a native callback for a re...
Definition: embedder.cc:2687
FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data)
Collects the AOT data.
Definition: embedder.cc:1480
FlutterEngineResult FlutterEngineNotifyDisplayUpdate(FLUTTER_API_SYMBOL(FlutterEngine) raw_engine, const FlutterEngineDisplaysUpdateType update_type, const FlutterEngineDisplay *embedder_displays, size_t display_count)
Posts updates corresponding to display changes to a running engine instance.
Definition: embedder.cc:3252
FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
Definition: embedder.cc:2636
bool FlutterEngineRunsAOTCompiledDartCode(void)
Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading re...
Definition: embedder.cc:3063
FlutterEngineResult FlutterEngineReloadSystemFonts(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Reloads the system fonts in engine.
Definition: embedder.cc:2902
static flutter::KeyEventType MapKeyEventType(FlutterKeyEventType event_kind)
Definition: embedder.cc:2512
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallback(const FlutterProjectArgs *args, void *user_data)
Definition: embedder.cc:1669
static flutter::Shell::CreateCallback< flutter::PlatformView > InferSoftwarePlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:676
const intptr_t kPlatformStrongDillSize
#define FLUTTER_EXPORT
Definition: embedder.cc:31
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV1(FlutterUpdateSemanticsNodeCallback update_semantics_node_callback, FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback, void *user_data)
Definition: embedder.cc:1589
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
Definition: embedder.cc:2429
FlutterEngineResult FlutterEngineRunInitialized(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize....
Definition: embedder.cc:2154
static bool IsSoftwareRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:174
static flutter::Shell::CreateCallback< flutter::PlatformView > InferOpenGLPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
Definition: embedder.cc:284
void PopulateJITSnapshotMappingCallbacks(const FlutterProjectArgs *args, flutter::Settings &settings)
Definition: embedder.cc:1493
static bool IsVulkanRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:207
FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(FLUTTER_API_SYMBOL(FlutterEngine) raw_engine)
Posts a low memory notification to a running engine instance. The engine will do its best to release ...
Definition: embedder.cc:3191
FlutterEngineResult FlutterEngineUnregisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Unregister a previous texture registration.
Definition: embedder.cc:2788
FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled)
Enable or disable accessibility semantics.
Definition: embedder.cc:2827
FlutterEngineResult FlutterEngineSendKeyEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Sends a key event to the engine. The framework will decide whether to handle this event in a synchron...
Definition: embedder.cc:2581
static flutter::Shell::CreateCallback< flutter::PlatformView > InferMetalPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
Definition: embedder.cc:496
static FlutterEngineResult LogEmbedderError(FlutterEngineResult code, const char *reason, const char *code_name, const char *function, const char *file, int line)
Definition: embedder.cc:132
void FlutterEngineTraceEventDurationEnd(const char *name)
A profiling utility. Logs a trace duration end event to the timeline. If the timeline is unavailable ...
Definition: embedder.cc:2924
FlutterEngineResult FlutterEngineSendPlatformMessageResponse(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
Send a response from the native side to a platform message from the Dart Flutter application.
Definition: embedder.cc:2737
const char * kFlutterKeyDataChannel
Definition: embedder.cc:130
FLUTTER_EXPORT FlutterEngineResult FlutterEngineRemoveView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterRemoveViewInfo *info)
Removes a view.
Definition: embedder.cc:2254
int64_t PointerDataButtonsForLegacyEvent(flutter::PointerData::Change change)
Definition: embedder.cc:2408
void PopulateAOTSnapshotMappingCallbacks(const FlutterProjectArgs *args, flutter::Settings &settings)
Definition: embedder.cc:1536
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
Definition: embedder.cc:2722
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV2(FlutterUpdateSemanticsCallback update_semantics_callback, void *user_data)
Definition: embedder.cc:1638
static std::variant< flutter::ViewportMetrics, std::string > MakeViewportMetricsFromWindowMetrics(const FlutterWindowMetricsEvent *flutter_metrics)
Definition: embedder.cc:1361
FlutterEngineResult FlutterEngineCreateAOTData(const FlutterEngineAOTDataSource *source, FlutterEngineAOTData *data_out)
Creates the necessary data structures to launch a Flutter Dart application in AOT mode....
Definition: embedder.cc:1426
FlutterKeyEventDeviceType
Definition: embedder.h:1080
@ kFlutterKeyEventDeviceTypeKeyboard
Definition: embedder.h:1081
@ kFlutterKeyEventDeviceTypeDirectionalPad
Definition: embedder.h:1082
@ kFlutterKeyEventDeviceTypeHdmi
Definition: embedder.h:1085
@ kFlutterKeyEventDeviceTypeJoystick
Definition: embedder.h:1084
@ kFlutterKeyEventDeviceTypeGamepad
Definition: embedder.h:1083
void(* FlutterUpdateSemanticsCustomActionCallback)(const FlutterSemanticsCustomAction *, void *)
Definition: embedder.h:1522
void(* FlutterUpdateSemanticsCallback)(const FlutterSemanticsUpdate *, void *)
Definition: embedder.h:1526
@ kFlutterEngineAOTDataSourceTypeElfPath
Definition: embedder.h:2110
struct _FlutterPlatformMessageResponseHandle FlutterPlatformMessageResponseHandle
Definition: embedder.h:1159
@ kVulkan
Definition: embedder.h:86
@ kOpenGL
Definition: embedder.h:80
@ kMetal
Definition: embedder.h:85
@ kSoftware
Definition: embedder.h:81
struct _FlutterEngine * FLUTTER_API_SYMBOL(FlutterEngine)
Definition: embedder.h:269
void(* FlutterDataCallback)(const uint8_t *, size_t, void *)
Definition: embedder.h:1181
FlutterPointerPhase
The phase of the pointer event.
Definition: embedder.h:965
@ kPanZoomUpdate
The pan/zoom updated.
Definition: embedder.h:1001
@ kHover
The pointer moved while up.
Definition: embedder.h:997
@ kUp
Definition: embedder.h:973
@ kPanZoomStart
A pan/zoom started on this pointer.
Definition: embedder.h:999
@ kRemove
Definition: embedder.h:995
@ kCancel
Definition: embedder.h:966
@ kDown
Definition: embedder.h:980
@ kAdd
Definition: embedder.h:990
@ kMove
Definition: embedder.h:985
@ kPanZoomEnd
The pan/zoom ended.
Definition: embedder.h:1003
FlutterAccessibilityFeature
Definition: embedder.h:91
void(* FlutterNativeThreadCallback)(FlutterNativeThreadType type, void *user_data)
Definition: embedder.h:2105
@ kFlutterEngineDartObjectTypeString
Definition: embedder.h:2018
@ kFlutterEngineDartObjectTypeBool
Definition: embedder.h:2014
@ kFlutterEngineDartObjectTypeDouble
Definition: embedder.h:2017
@ kFlutterEngineDartObjectTypeInt32
Definition: embedder.h:2015
@ kFlutterEngineDartObjectTypeBuffer
Definition: embedder.h:2021
@ kFlutterEngineDartObjectTypeInt64
Definition: embedder.h:2016
@ kFlutterEngineDartObjectTypeNull
Definition: embedder.h:2013
void(* FlutterLogMessageCallback)(const char *, const char *, void *)
Definition: embedder.h:2130
FlutterEngineResult
Definition: embedder.h:72
@ kInternalInconsistency
Definition: embedder.h:76
@ kInvalidLibraryVersion
Definition: embedder.h:74
@ kInvalidArguments
Definition: embedder.h:75
@ kSuccess
Definition: embedder.h:73
FlutterNativeThreadType
Definition: embedder.h:2086
FlutterPointerSignalKind
The type of a pointer signal.
Definition: embedder.h:1027
@ kFlutterPointerSignalKindScale
Definition: embedder.h:1031
@ kFlutterPointerSignalKindScrollInertiaCancel
Definition: embedder.h:1030
@ kFlutterPointerSignalKindScroll
Definition: embedder.h:1029
@ kFlutterPointerSignalKindNone
Definition: embedder.h:1028
void(* FlutterUpdateSemanticsNodeCallback)(const FlutterSemanticsNode *, void *)
Definition: embedder.h:1518
FlutterEngineDisplaysUpdateType
Definition: embedder.h:2000
@ kFlutterEngineDisplaysUpdateTypeStartup
Definition: embedder.h:2006
FlutterThreadPriority
Valid values for priority of Thread.
Definition: embedder.h:258
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
Definition: embedder.h:260
@ kDisplay
Suitable for threads which generate data for the display.
Definition: embedder.h:264
@ kNormal
Default priority level.
Definition: embedder.h:262
@ kRaster
Suitable for thread which raster data.
Definition: embedder.h:266
FlutterSemanticsAction
Definition: embedder.h:113
void(* FlutterKeyEventCallback)(bool, void *)
Definition: embedder.h:1155
int64_t FlutterViewId
Definition: embedder.h:275
FlutterKeyEventType
Definition: embedder.h:1074
@ kFlutterKeyEventTypeDown
Definition: embedder.h:1076
@ kFlutterKeyEventTypeUp
Definition: embedder.h:1075
@ kFlutterKeyEventTypeRepeat
Definition: embedder.h:1077
void(* FlutterUpdateSemanticsCallback2)(const FlutterSemanticsUpdate2 *, void *)
Definition: embedder.h:1530
int64_t FlutterEngineDartPort
Definition: embedder.h:2010
@ kFlutterOpenGLTargetTypeFramebuffer
Definition: embedder.h:306
@ kFlutterOpenGLTargetTypeTexture
Definition: embedder.h:303
@ kFlutterBackingStoreTypeSoftware2
Definition: embedder.h:1751
@ kFlutterBackingStoreTypeMetal
Specifies a Metal backing store. This is backed by a Metal texture.
Definition: embedder.h:1746
@ kFlutterBackingStoreTypeVulkan
Specifies a Vulkan backing store. This is backed by a Vulkan VkImage.
Definition: embedder.h:1748
@ kFlutterBackingStoreTypeSoftware
Specified an software allocation for Flutter to render into using the CPU.
Definition: embedder.h:1744
@ kFlutterBackingStoreTypeOpenGL
Definition: embedder.h:1742
#define FLUTTER_ENGINE_VERSION
Definition: embedder.h:70
FlutterPointerDeviceKind
The device type that created a pointer event.
Definition: embedder.h:1007
@ kFlutterPointerDeviceKindTouch
Definition: embedder.h:1009
@ kFlutterPointerDeviceKindTrackpad
Definition: embedder.h:1011
@ kFlutterPointerDeviceKindStylus
Definition: embedder.h:1010
@ kFlutterPointerDeviceKindMouse
Definition: embedder.h:1008
#define SAFE_EXISTS(pointer, member)
Checks if the member exists and is non-null.
#define SAFE_ACCESS(pointer, member, default_value)
#define SAFE_EXISTS_ONE_OF(pointer, member1, member2)
Checks if exactly one of member1 or member2 exists and is non-null.
VkPhysicalDevice physical_device
Definition: main.cc:51
VkDevice device
Definition: main.cc:53
FlutterEngine engine
Definition: main.cc:68
VkInstance instance
Definition: main.cc:48
VkQueue queue
Definition: main.cc:55
VkSurfaceKHR surface
Definition: main.cc:49
SkBitmap source
Definition: examples.cpp:28
#define FATAL(error)
FlutterSemanticsFlag flags
if(end==-1)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t uint32_t * format
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
Dart_NativeFunction function
Definition: fuchsia.cc:51
static const char * kApplicationKernelSnapshotFileName
Win32Message message
FlTexture * texture
double y
double x
SK_API GrBackendRenderTarget MakeGL(int width, int height, int sampleCnt, int stencilBits, const GrGLFramebufferInfo &glInfo)
SK_API GrBackendTexture MakeGL(int width, int height, skgpu::Mipmapped, const GrGLTextureInfo &glInfo, std::string_view label={})
SK_API GrBackendTexture MakeMtl(int width, int height, skgpu::Mipmapped, const GrMtlTextureInfo &mtlInfo, std::string_view label={})
SK_API GrBackendTexture MakeVk(int width, int height, const GrVkImageInfo &, std::string_view label={})
sk_sp< const SkImage > image
Definition: SkRecords.h:269
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SK_API sk_sp< SkSurface > WrapPixels(const SkImageInfo &imageInfo, void *pixels, size_t rowBytes, const SkSurfaceProps *surfaceProps=nullptr)
SK_API sk_sp< SkSurface > WrapBackendRenderTarget(GrRecordingContext *context, const GrBackendRenderTarget &backendRenderTarget, GrSurfaceOrigin origin, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, RenderTargetReleaseProc releaseProc=nullptr, ReleaseContext releaseContext=nullptr)
void(*)(ReleaseContext) RenderTargetReleaseProc
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
void(*)(ReleaseContext) TextureReleaseProc
const uint8_t * isolate_snapshot_data
Definition: gen_snapshot.cc:69
const uint8_t * vm_snapshot_data
Definition: main_impl.cc:52
const uint8_t * vm_snapshot_instructions
Definition: main_impl.cc:53
static void Shutdown(Dart_NativeArguments args)
const uint8_t * isolate_snapshot_instructions
Definition: gen_snapshot.cc:70
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 port
Definition: switches.h:87
static void DispatchPointerDataPacket(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject buffer, jint position)
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
Definition: switches.cc:228
@ kPointerButtonMousePrimary
Definition: pointer_data.h:14
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
static void DispatchSemanticsAction(JNIEnv *env, jobject jcaller, jlong shell_holder, jint id, jint action, jobject args, jint args_position)
static void MarkTextureFrameAvailable(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
static void SetSemanticsEnabled(JNIEnv *env, jobject jcaller, jlong shell_holder, jboolean enabled)
@ kPointerButtonTouchContact
Definition: pointer_data.h:22
KeyEventType
Definition: key_data.h:22
static void NotifyLowMemoryWarning(JNIEnv *env, jobject obj, jlong shell_holder)
KeyEventDeviceType
Definition: key_data.h:34
static void SetViewportMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder, jfloat devicePixelRatio, jint physicalWidth, jint physicalHeight, jint physicalPaddingTop, jint physicalPaddingRight, jint physicalPaddingBottom, jint physicalPaddingLeft, jint physicalViewInsetTop, jint physicalViewInsetRight, jint physicalViewInsetBottom, jint physicalViewInsetLeft, jint systemGestureInsetTop, jint systemGestureInsetRight, jint systemGestureInsetBottom, jint systemGestureInsetLeft, jint physicalTouchSlop, jintArray javaDisplayFeaturesBounds, jintArray javaDisplayFeaturesType, jintArray javaDisplayFeaturesState)
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 buffer
Definition: switches.h:126
static void ScheduleFrame(JNIEnv *env, jobject jcaller, jlong shell_holder)
static void SetAccessibilityFeatures(JNIEnv *env, jobject jcaller, jlong shell_holder, jint flags)
void * GPUMTLCommandQueueHandle
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
static void UnregisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
static void RegisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject surface_texture)
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
void TraceEventInstant0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
Definition: trace_event.cc:460
void TraceEvent0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
Definition: trace_event.cc:408
void TraceEventEnd(TraceArg name)
Definition: trace_event.cc:429
CommandLine CommandLineFromArgcArgv(int argc, const char *const *argv)
Definition: command_line.h:233
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
bool IsFile(const std::string &path)
Definition: file_posix.cc:146
std::function< void()> closure
Definition: closure.h:14
void Initialize(zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
Definition: fuchsia.cc:103
std::shared_ptr< Texture > WrapTextureMTL(TextureDescriptor desc, const void *mtl_texture, std::function< void()> deletion_proc=nullptr)
ISize64 ISize
Definition: size.h:140
Definition: update.py:1
std::optional< SkColorInfo > getSkColorInfo(FlutterSoftwarePixelFormat pixfmt)
int32_t height
int32_t width
const Scalar scale
FlutterSize size
The size of the render target the engine expects to render into.
Definition: embedder.h:1784
FlutterVulkanBackingStore vulkan
Definition: embedder.h:1776
FlutterMetalBackingStore metal
Definition: embedder.h:1774
FlutterBackingStoreType type
Specifies the type of backing store.
Definition: embedder.h:1762
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition: embedder.h:1768
FlutterSoftwareBackingStore software
The description of the software backing store.
Definition: embedder.h:1770
FlutterSoftwareBackingStore2 software2
The description of the software backing store.
Definition: embedder.h:1772
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStore).
Definition: embedder.h:1756
An update to whether a message channel has a listener set or not.
Definition: embedder.h:1535
FlutterBackingStoreCreateCallback create_backing_store_callback
Definition: embedder.h:1903
FlutterBackingStoreCollectCallback collect_backing_store_callback
Definition: embedder.h:1908
A structure to represent a damage region.
Definition: embedder.h:460
size_t num_rects
The number of rectangles within the damage region.
Definition: embedder.h:464
size_t struct_size
The size of this struct. Must be sizeof(FlutterDamage).
Definition: embedder.h:462
FlutterRect * damage
The actual damage region(s) in question.
Definition: embedder.h:466
FlutterEngineDartObjectType type
Definition: embedder.h:2069
const char * string_value
Definition: embedder.h:2078
const FlutterEngineDartBuffer * buffer_value
Definition: embedder.h:2079
Function-pointer-based versions of the APIs above.
Definition: embedder.h:3319
size_t struct_size
The size of this struct. Must be sizeof(FlutterFrameInfo).
Definition: embedder.h:477
FlutterUIntSize size
The size of the surface that will be backed by the fbo.
Definition: embedder.h:479
FlutterSize size
The size of the layer (in physical pixels).
Definition: embedder.h:1837
FlutterMetalTexture texture
Definition: embedder.h:1665
FlutterMetalTextureFrameCallback external_texture_frame_callback
Definition: embedder.h:704
FlutterMetalCommandQueueHandle present_command_queue
Alias for id<MTLCommandQueue>.
Definition: embedder.h:689
FlutterMetalDeviceHandle device
Alias for id<MTLDevice>.
Definition: embedder.h:687
FlutterMetalPresentCallback present_drawable_callback
Definition: embedder.h:699
FlutterMetalTextureCallback get_next_drawable_callback
Definition: embedder.h:694
FlutterMetalTextureHandle texture
Definition: embedder.h:661
size_t struct_size
The size of this struct. Must be sizeof(FlutterMetalTexture).
Definition: embedder.h:651
int64_t texture_id
Definition: embedder.h:656
VoidCallback destruction_callback
Definition: embedder.h:668
FlutterOpenGLTexture texture
A texture for Flutter to render into.
Definition: embedder.h:1613
FlutterOpenGLTargetType type
Definition: embedder.h:1610
FlutterOpenGLFramebuffer framebuffer
Definition: embedder.h:1616
uint32_t name
The name of the framebuffer.
Definition: embedder.h:396
VoidCallback destruction_callback
Definition: embedder.h:403
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition: embedder.h:399
ProcResolver gl_proc_resolver
Definition: embedder.h:554
BoolCallback make_current
Definition: embedder.h:516
BoolPresentInfoCallback present_with_info
Definition: embedder.h:578
UIntCallback fbo_callback
Definition: embedder.h:530
TextureFrameCallback gl_external_texture_frame_callback
Definition: embedder.h:559
FlutterFrameBufferWithDamageCallback populate_existing_damage
Definition: embedder.h:592
TransformationCallback surface_transformation
Definition: embedder.h:553
BoolCallback make_resource_current
Definition: embedder.h:537
UIntFrameInfoCallback fbo_with_frame_info_callback
Definition: embedder.h:567
BoolCallback clear_current
Definition: embedder.h:517
const char * channel
Definition: embedder.h:1165
size_t struct_size
The size of this struct. Must be sizeof(FlutterPointerEvent).
Definition: embedder.h:1036
size_t struct_size
The size of this struct. Must be sizeof(FlutterPresentInfo).
Definition: embedder.h:499
A structure to represent a rectangle.
Definition: embedder.h:437
double bottom
Definition: embedder.h:441
double top
Definition: embedder.h:439
double left
Definition: embedder.h:438
double right
Definition: embedder.h:440
FlutterVulkanRendererConfig vulkan
Definition: embedder.h:832
FlutterMetalRendererConfig metal
Definition: embedder.h:831
FlutterSoftwareRendererConfig software
Definition: embedder.h:830
FlutterOpenGLRendererConfig open_gl
Definition: embedder.h:829
FlutterRendererType type
Definition: embedder.h:827
FlutterSemanticsNode * nodes
Definition: embedder.h:1496
size_t nodes_count
The number of semantics node updates.
Definition: embedder.h:1494
size_t custom_actions_count
The number of semantics custom action updates.
Definition: embedder.h:1498
FlutterSemanticsCustomAction * custom_actions
Array of semantics custom actions. Has length custom_actions_count.
Definition: embedder.h:1500
double height
Definition: embedder.h:425
double width
Definition: embedder.h:424
VoidCallback destruction_callback
Definition: embedder.h:1652
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition: embedder.h:1643
FlutterSoftwarePixelFormat pixel_format
Definition: embedder.h:1655
VoidCallback destruction_callback
Definition: embedder.h:1634
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition: embedder.h:1625
SoftwareSurfacePresentCallback surface_present_callback
Definition: embedder.h:823
double transY
vertical translation
Definition: embedder.h:289
double pers2
perspective scale factor
Definition: embedder.h:295
double skewX
horizontal skew factor
Definition: embedder.h:281
double pers0
input x-axis perspective factor
Definition: embedder.h:291
double scaleX
horizontal scale factor
Definition: embedder.h:279
double skewY
vertical skew factor
Definition: embedder.h:285
double scaleY
vertical scale factor
Definition: embedder.h:287
double pers1
input y-axis perspective factor
Definition: embedder.h:293
double transX
horizontal translation
Definition: embedder.h:283
uint32_t width
Definition: embedder.h:432
size_t struct_size
The size of this struct. Must be sizeof(FlutterVulkanImage).
Definition: embedder.h:724
FlutterVulkanQueueHandle queue
Definition: embedder.h:773
FlutterVulkanDeviceHandle device
Definition: embedder.h:764
FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback
Definition: embedder.h:802
size_t enabled_instance_extension_count
Definition: embedder.h:776
uint32_t queue_family_index
The queue family index of the VkQueue supplied in the next field.
Definition: embedder.h:766
FlutterVulkanImageCallback get_next_image_callback
Definition: embedder.h:806
const char ** enabled_instance_extensions
Definition: embedder.h:783
const char ** enabled_device_extensions
Definition: embedder.h:794
size_t enabled_device_extension_count
Definition: embedder.h:786
FlutterVulkanInstanceHandle instance
Definition: embedder.h:759
FlutterVulkanPresentCallback present_image_callback
Definition: embedder.h:812
FlutterVulkanPhysicalDeviceHandle physical_device
VkPhysicalDevice handle.
Definition: embedder.h:761
GrGLuint fID
Definition: GrGLTypes.h:182
GrGLenum fFormat
Definition: GrGLTypes.h:183
GrGLenum fTarget
Definition: GrGLTypes.h:181
VkImage fImage
Definition: GrVkTypes.h:26
void operator()(Dart_LoadedElf *elf)
Definition: embedder.cc:1409
Definition: SkRect.h:32
static constexpr SkIRect MakeEmpty()