Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
16#include "flutter/fml/closure.h"
20#include "flutter/fml/thread.h"
21#include "third_party/dart/runtime/bin/elf_loader.h"
22#include "third_party/dart/runtime/include/dart_native_api.h"
23#include "third_party/skia/include/core/SkSurface.h"
24#include "third_party/skia/include/gpu/GpuTypes.h"
25#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
26#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
27
28#if !defined(FLUTTER_NO_EXPORT)
29#if FML_OS_WIN
30#define FLUTTER_EXPORT __declspec(dllexport)
31#else // FML_OS_WIN
32#define FLUTTER_EXPORT __attribute__((visibility("default")))
33#endif // FML_OS_WIN
34#endif // !FLUTTER_NO_EXPORT
35
36extern "C" {
37#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
38// Used for debugging dart:* sources.
39extern const uint8_t kPlatformStrongDill[];
40extern const intptr_t kPlatformStrongDillSize;
41#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
42}
43
48#include "flutter/fml/file.h"
51#include "flutter/fml/paths.h"
67#include "rapidjson/rapidjson.h"
68#include "rapidjson/writer.h"
69
70// Note: the IMPELLER_SUPPORTS_RENDERING may be defined even when the
71// embedder/BUILD.gn variable impeller_supports_rendering is disabled.
72#ifdef SHELL_ENABLE_GL
74#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
75#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h"
76#ifdef IMPELLER_SUPPORTS_RENDERING
80#include "impeller/core/texture.h" // nogncheck
83#include "impeller/renderer/context.h" // nogncheck
84#include "impeller/renderer/render_target.h" // nogncheck
85#endif // IMPELLER_SUPPORTS_RENDERING
86#endif // SHELL_ENABLE_GL
87
88#ifdef SHELL_ENABLE_METAL
90#include "third_party/skia/include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
91#include "third_party/skia/include/gpu/ganesh/mtl/GrMtlTypes.h"
92#include "third_party/skia/include/ports/SkCFObject.h"
93#ifdef IMPELLER_SUPPORTS_RENDERING
96#include "impeller/core/texture.h" // nogncheck
98#include "impeller/renderer/render_target.h" // nogncheck
99#endif // IMPELLER_SUPPORTS_RENDERING
100#endif // SHELL_ENABLE_METAL
101
102#ifdef SHELL_ENABLE_VULKAN
103#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
104#include "third_party/skia/include/gpu/ganesh/vk/GrVkTypes.h"
105#endif // SHELL_ENABLE_VULKAN
106
109
111
112// A message channel to send platform-independent FlutterKeyData to the
113// framework.
114//
115// This should be kept in sync with the following variables:
116//
117// - lib/ui/platform_dispatcher.dart, _kFlutterKeyDataChannel
118// - shell/platform/darwin/ios/framework/Source/FlutterEngine.mm,
119// FlutterKeyDataChannel
120// - io/flutter/embedding/android/KeyData.java,
121// CHANNEL
122//
123// Not to be confused with "flutter/keyevent", which is used to send raw
124// key event data in a platform-dependent format.
125//
126// ## Format
127//
128// Send: KeyDataPacket.data().
129//
130// Expected reply: Whether the event is handled. Exactly 1 byte long, with value
131// 1 for handled, and 0 for not. Malformed value is considered false.
132const char* kFlutterKeyDataChannel = "flutter/keydata";
133
135 const char* reason,
136 const char* code_name,
137 const char* function,
138 const char* file,
139 int line) {
140#if FML_OS_WIN
141 constexpr char kSeparator = '\\';
142#else
143 constexpr char kSeparator = '/';
144#endif
145 const auto file_base =
146 (::strrchr(file, kSeparator) ? strrchr(file, kSeparator) + 1 : file);
147 char error[256] = {};
148 snprintf(error, (sizeof(error) / sizeof(char)),
149 "%s (%d): '%s' returned '%s'. %s", file_base, line, function,
150 code_name, reason);
151 std::cerr << error << std::endl;
152 return code;
153}
154
155#define LOG_EMBEDDER_ERROR(code, reason) \
156 LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)
157
159 if (config->type != kOpenGL) {
160 return false;
161 }
162
163 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
164
165 if (!SAFE_EXISTS(open_gl_config, make_current) ||
166 !SAFE_EXISTS(open_gl_config, clear_current) ||
167 !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback,
168 fbo_with_frame_info_callback) ||
169 !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) {
170 return false;
171 }
172
173 return true;
174}
175
177 if (config->type != kSoftware) {
178 return false;
179 }
180
181 const FlutterSoftwareRendererConfig* software_config = &config->software;
182
183 if (SAFE_ACCESS(software_config, surface_present_callback, nullptr) ==
184 nullptr) {
185 return false;
186 }
187
188 return true;
189}
190
192 if (config->type != kMetal) {
193 return false;
194 }
195
196 const FlutterMetalRendererConfig* metal_config = &config->metal;
197
198 bool device = SAFE_ACCESS(metal_config, device, nullptr);
199 bool command_queue =
200 SAFE_ACCESS(metal_config, present_command_queue, nullptr);
201
202 bool present = SAFE_ACCESS(metal_config, present_drawable_callback, nullptr);
203 bool get_texture =
204 SAFE_ACCESS(metal_config, get_next_drawable_callback, nullptr);
205
206 return device && command_queue && present && get_texture;
207}
208
210 if (config->type != kVulkan) {
211 return false;
212 }
213
214 const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan;
215
216 if (!SAFE_EXISTS(vulkan_config, instance) ||
217 !SAFE_EXISTS(vulkan_config, physical_device) ||
218 !SAFE_EXISTS(vulkan_config, device) ||
219 !SAFE_EXISTS(vulkan_config, queue) ||
220 !SAFE_EXISTS(vulkan_config, get_instance_proc_address_callback) ||
221 !SAFE_EXISTS(vulkan_config, get_next_image_callback) ||
222 !SAFE_EXISTS(vulkan_config, present_image_callback)) {
223 return false;
224 }
225
226 return true;
227}
228
229static bool IsRendererValid(const FlutterRendererConfig* config) {
230 if (config == nullptr) {
231 return false;
232 }
233
234 switch (config->type) {
235 case kOpenGL:
236 return IsOpenGLRendererConfigValid(config);
237 case kSoftware:
238 return IsSoftwareRendererConfigValid(config);
239 case kMetal:
240 return IsMetalRendererConfigValid(config);
241 case kVulkan:
242 return IsVulkanRendererConfigValid(config);
243 default:
244 return false;
245 }
246
247 return false;
248}
249
250#if FML_OS_LINUX || FML_OS_WIN
251static void* DefaultGLProcResolver(const char* name) {
252 static fml::RefPtr<fml::NativeLibrary> proc_library =
253#if FML_OS_LINUX
255#elif FML_OS_WIN // FML_OS_LINUX
256 fml::NativeLibrary::Create("opengl32.dll");
257#endif // FML_OS_WIN
258 return static_cast<void*>(
259 const_cast<uint8_t*>(proc_library->ResolveSymbol(name)));
260}
261#endif // FML_OS_LINUX || FML_OS_WIN
262
263#ifdef SHELL_ENABLE_GL
264// Auxiliary function used to translate rectangles of type SkIRect to
265// FlutterRect.
266static FlutterRect DlIRectToFlutterRect(const flutter::DlIRect& dl_rect) {
267 FlutterRect flutter_rect = {static_cast<double>(dl_rect.GetLeft()),
268 static_cast<double>(dl_rect.GetTop()),
269 static_cast<double>(dl_rect.GetRight()),
270 static_cast<double>(dl_rect.GetBottom())};
271 return flutter_rect;
272}
273
274// Auxiliary function used to translate rectangles of type FlutterRect to
275// SkIRect.
276static const flutter::DlIRect FlutterRectToDlIRect(FlutterRect flutter_rect) {
277 return flutter::DlIRect::MakeLTRB(static_cast<int32_t>(flutter_rect.left),
278 static_cast<int32_t>(flutter_rect.top),
279 static_cast<int32_t>(flutter_rect.right),
280 static_cast<int32_t>(flutter_rect.bottom));
281}
282
283// We need GL_BGRA8_EXT for creating SkSurfaces from FlutterOpenGLSurfaces
284// below.
285#ifndef GL_BGRA8_EXT
286#define GL_BGRA8_EXT 0x93A1
287#endif
288
289static std::optional<SkColorType> FlutterFormatToSkColorType(uint32_t format) {
290 switch (format) {
291 case GL_BGRA8_EXT:
292 return kBGRA_8888_SkColorType;
293 case GL_RGBA8:
294 return kRGBA_8888_SkColorType;
295 default:
296 FML_LOG(ERROR) << "Cannot convert format " << format
297 << " to SkColorType.";
298 return std::nullopt;
299 }
300}
301
302#endif
303
306 const FlutterRendererConfig* config,
307 void* user_data,
309 platform_dispatch_table,
310 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
311 external_view_embedder,
312 bool enable_impeller) {
313#ifdef SHELL_ENABLE_GL
314 if (config->type != kOpenGL) {
315 return nullptr;
316 }
317
318 auto gl_make_current = [ptr = config->open_gl.make_current,
319 user_data]() -> bool { return ptr(user_data); };
320
321 auto gl_clear_current = [ptr = config->open_gl.clear_current,
322 user_data]() -> bool { return ptr(user_data); };
323
324 auto gl_present =
325 [present = config->open_gl.present,
326 present_with_info = config->open_gl.present_with_info,
327 user_data](flutter::GLPresentInfo gl_present_info) -> bool {
328 if (present) {
329 return present(user_data);
330 } else {
331 // Format the frame and buffer damages accordingly. Note that, since the
332 // current compute damage algorithm only returns one rectangle for damage
333 // we are assuming the number of rectangles provided in frame and buffer
334 // damage are always 1. Once the function that computes damage implements
335 // support for multiple damage rectangles, GLPresentInfo should also
336 // contain the number of damage rectangles.
337
338 std::optional<FlutterRect> frame_damage_rect;
339 if (gl_present_info.frame_damage) {
340 frame_damage_rect =
341 DlIRectToFlutterRect(*(gl_present_info.frame_damage));
342 }
343 std::optional<FlutterRect> buffer_damage_rect;
344 if (gl_present_info.buffer_damage) {
345 buffer_damage_rect =
346 DlIRectToFlutterRect(*(gl_present_info.buffer_damage));
347 }
348
349 FlutterDamage frame_damage{
350 .struct_size = sizeof(FlutterDamage),
351 .num_rects = frame_damage_rect ? size_t{1} : size_t{0},
352 .damage = frame_damage_rect ? &frame_damage_rect.value() : nullptr,
353 };
354 FlutterDamage buffer_damage{
355 .struct_size = sizeof(FlutterDamage),
356 .num_rects = buffer_damage_rect ? size_t{1} : size_t{0},
357 .damage = buffer_damage_rect ? &buffer_damage_rect.value() : nullptr,
358 };
359
360 // Construct the present information concerning the frame being rendered.
361 FlutterPresentInfo present_info = {
363 .fbo_id = gl_present_info.fbo_id,
364 .frame_damage = frame_damage,
365 .buffer_damage = buffer_damage,
366 };
367
368 return present_with_info(user_data, &present_info);
369 }
370 };
371
372 auto gl_fbo_callback =
373 [fbo_callback = config->open_gl.fbo_callback,
374 fbo_with_frame_info_callback =
376 user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
377 if (fbo_callback) {
378 return fbo_callback(user_data);
379 } else {
380 FlutterFrameInfo frame_info = {};
381 frame_info.struct_size = sizeof(FlutterFrameInfo);
382 frame_info.size = {gl_frame_info.width, gl_frame_info.height};
383 return fbo_with_frame_info_callback(user_data, &frame_info);
384 }
385 };
386
387 auto gl_populate_existing_damage =
388 [populate_existing_damage = config->open_gl.populate_existing_damage,
389 user_data](intptr_t id) -> flutter::GLFBOInfo {
390 // If no populate_existing_damage was provided, disable partial
391 // repaint.
392 if (!populate_existing_damage) {
393 return flutter::GLFBOInfo{
394 .fbo_id = static_cast<uint32_t>(id),
395 .existing_damage = std::nullopt,
396 };
397 }
398
399 // Given the FBO's ID, get its existing damage.
400 FlutterDamage existing_damage;
401 populate_existing_damage(user_data, id, &existing_damage);
402
403 std::optional<flutter::DlIRect> existing_damage_rect = std::nullopt;
404
405 // Verify that at least one damage rectangle was provided.
406 if (existing_damage.num_rects <= 0 || existing_damage.damage == nullptr) {
407 FML_LOG(INFO) << "No damage was provided. Forcing full repaint.";
408 } else {
409 existing_damage_rect = flutter::DlIRect();
410 for (size_t i = 0; i < existing_damage.num_rects; i++) {
411 existing_damage_rect = existing_damage_rect->Union(
412 FlutterRectToDlIRect(existing_damage.damage[i]));
413 }
414 }
415
416 // Pass the information about this FBO to the rendering backend.
417 return flutter::GLFBOInfo{
418 .fbo_id = static_cast<uint32_t>(id),
419 .existing_damage = existing_damage_rect,
420 };
421 };
422
423 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
424 std::function<bool()> gl_make_resource_current_callback = nullptr;
425 if (SAFE_ACCESS(open_gl_config, make_resource_current, nullptr) != nullptr) {
426 gl_make_resource_current_callback =
427 [ptr = config->open_gl.make_resource_current, user_data]() {
428 return ptr(user_data);
429 };
430 }
431
432 std::function<flutter::DlMatrix(void)> gl_surface_transformation_callback =
433 nullptr;
434 if (SAFE_ACCESS(open_gl_config, surface_transformation, nullptr) != nullptr) {
435 gl_surface_transformation_callback =
436 [ptr = config->open_gl.surface_transformation, user_data]() {
437 FlutterTransformation transformation = ptr(user_data);
438 // clang-format off
439 return flutter::DlMatrix(
440 transformation.scaleX, transformation.skewY, 0.0f, transformation.pers0,
441 transformation.skewX, transformation.scaleY, 0.0f, transformation.pers1,
442 0.0f, 0.0f, 1.0f, 0.0f,
443 transformation.transX, transformation.transY, 0.0f, transformation.pers2
444 );
445 // clang-format on
446 };
447
448 // If there is an external view embedder, ask it to apply the surface
449 // transformation to its surfaces as well.
450 if (external_view_embedder) {
451 external_view_embedder->SetSurfaceTransformationCallback(
452 gl_surface_transformation_callback);
453 }
454 }
455
456 flutter::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr;
457 if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) {
458 gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver,
459 user_data](const char* gl_proc_name) {
460 return ptr(user_data, gl_proc_name);
461 };
462 } else {
463#if FML_OS_LINUX || FML_OS_WIN
464 gl_proc_resolver = DefaultGLProcResolver;
465#endif // FML_OS_LINUX || FML_OS_WIN
466 }
467
468 bool fbo_reset_after_present =
469 SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false);
470
472 gl_make_current, // gl_make_current_callback
473 gl_clear_current, // gl_clear_current_callback
474 gl_present, // gl_present_callback
475 gl_fbo_callback, // gl_fbo_callback
476 gl_make_resource_current_callback, // gl_make_resource_current_callback
477 gl_surface_transformation_callback, // gl_surface_transformation_callback
478 gl_proc_resolver, // gl_proc_resolver
479 gl_populate_existing_damage, // gl_populate_existing_damage
480 };
481
482 return fml::MakeCopyable(
483 [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table,
484 enable_impeller,
485 external_view_embedder =
486 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
487 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
488 std::move(external_view_embedder);
489 if (enable_impeller) {
490 return std::make_unique<flutter::PlatformViewEmbedder>(
491 shell, // delegate
492 shell.GetTaskRunners(), // task runners
493 std::make_unique<flutter::EmbedderSurfaceGLImpeller>(
494 gl_dispatch_table, fbo_reset_after_present,
495 view_embedder), // embedder_surface
496 platform_dispatch_table, // embedder platform dispatch table
497 view_embedder // external view embedder
498 );
499 }
500 return std::make_unique<flutter::PlatformViewEmbedder>(
501 shell, // delegate
502 shell.GetTaskRunners(), // task runners
503 std::make_unique<flutter::EmbedderSurfaceGLSkia>(
504 gl_dispatch_table, fbo_reset_after_present,
505 view_embedder), // embedder_surface
506 platform_dispatch_table, // embedder platform dispatch table
507 view_embedder // external view embedder
508 );
509 });
510#else // SHELL_ENABLE_GL
511 FML_LOG(ERROR) << "This Flutter Engine does not support OpenGL rendering.";
512 return nullptr;
513#endif // SHELL_ENABLE_GL
514}
515
518 const FlutterRendererConfig* config,
519 void* user_data,
521 platform_dispatch_table,
522 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
523 external_view_embedder,
524 bool enable_impeller) {
525 if (config->type != kMetal) {
526 return nullptr;
527 }
528
529#ifdef SHELL_ENABLE_METAL
530 std::function<bool(flutter::GPUMTLTextureInfo texture)> metal_present =
531 [ptr = config->metal.present_drawable_callback,
533 FlutterMetalTexture embedder_texture;
534 embedder_texture.struct_size = sizeof(FlutterMetalTexture);
535 embedder_texture.texture = texture.texture;
536 embedder_texture.texture_id = texture.texture_id;
537 embedder_texture.user_data = texture.destruction_context;
538 embedder_texture.destruction_callback = texture.destruction_callback;
539 return ptr(user_data, &embedder_texture);
540 };
541 auto metal_get_texture =
543 const flutter::DlISize& frame_size) -> flutter::GPUMTLTextureInfo {
544 FlutterFrameInfo frame_info = {};
545 frame_info.struct_size = sizeof(FlutterFrameInfo);
546 frame_info.size = {static_cast<uint32_t>(frame_size.width),
547 static_cast<uint32_t>(frame_size.height)};
548 flutter::GPUMTLTextureInfo texture_info;
549
550 FlutterMetalTexture metal_texture = ptr(user_data, &frame_info);
551 texture_info.texture_id = metal_texture.texture_id;
552 texture_info.texture = metal_texture.texture;
553 texture_info.destruction_callback = metal_texture.destruction_callback;
554 texture_info.destruction_context = metal_texture.user_data;
555 return texture_info;
556 };
557
558 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
559 std::move(external_view_embedder);
560
561 std::unique_ptr<flutter::EmbedderSurface> embedder_surface;
562
563 if (enable_impeller) {
565 metal_dispatch_table = {
566 .present = metal_present,
567 .get_texture = metal_get_texture,
568 };
569 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalImpeller>(
570 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
573 metal_dispatch_table, view_embedder);
574 } else {
575#if !SLIMPELLER
577 {
578 .present = metal_present,
579 .get_texture = metal_get_texture,
580 };
581 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalSkia>(
582 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
585 metal_dispatch_table, view_embedder);
586#else // !SLIMPELLER
587 FML_LOG(FATAL) << "Impeller opt-out unavailable.";
588#endif // !SLIMPELLER
589 }
590
591 // The static leak checker gets confused by the use of fml::MakeCopyable.
592 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
593 return fml::MakeCopyable(
594 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
595 external_view_embedder = view_embedder](flutter::Shell& shell) mutable {
596 return std::make_unique<flutter::PlatformViewEmbedder>(
597 shell, // delegate
598 shell.GetTaskRunners(), // task runners
599 std::move(embedder_surface), // embedder surface
600 platform_dispatch_table, // platform dispatch table
601 std::move(external_view_embedder) // external view embedder
602 );
603 });
604#else // SHELL_ENABLE_METAL
605 FML_LOG(ERROR) << "This Flutter Engine does not support Metal rendering.";
606 return nullptr;
607#endif // SHELL_ENABLE_METAL
608}
609
612 const FlutterRendererConfig* config,
613 void* user_data,
615 platform_dispatch_table,
616 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
617 external_view_embedder,
618 bool enable_impeller) {
619 if (config->type != kVulkan) {
620 return nullptr;
621 }
622
623#ifdef SHELL_ENABLE_VULKAN
624 std::function<void*(VkInstance, const char*)>
625 vulkan_get_instance_proc_address =
627 VkInstance instance, const char* proc_name) -> void* {
628 return ptr(user_data, instance, proc_name);
629 };
630
631 auto vulkan_get_next_image =
632 [ptr = config->vulkan.get_next_image_callback,
633 user_data](const flutter::DlISize& frame_size) -> FlutterVulkanImage {
634 FlutterFrameInfo frame_info = {
635 .struct_size = sizeof(FlutterFrameInfo),
636 .size = {static_cast<uint32_t>(frame_size.width),
637 static_cast<uint32_t>(frame_size.height)},
638 };
639
640 return ptr(user_data, &frame_info);
641 };
642
643 auto vulkan_present_image_callback =
644 [ptr = config->vulkan.present_image_callback, user_data](
645 VkImage image, VkFormat format) -> bool {
646 FlutterVulkanImage image_desc = {
648 .image = reinterpret_cast<uint64_t>(image),
649 .format = static_cast<uint32_t>(format),
650 };
651 return ptr(user_data, &image_desc);
652 };
653
654 auto vk_instance = static_cast<VkInstance>(config->vulkan.instance);
655 auto proc_addr =
656 vulkan_get_instance_proc_address(vk_instance, "vkGetInstanceProcAddr");
657
658 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
659 std::move(external_view_embedder);
660
661#if IMPELLER_SUPPORTS_RENDERING
662 if (enable_impeller) {
664 vulkan_dispatch_table = {
666 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
667 .get_next_image = vulkan_get_next_image,
668 .present_image = vulkan_present_image_callback,
669 };
670
671 std::unique_ptr<flutter::EmbedderSurfaceVulkanImpeller> embedder_surface =
672 std::make_unique<flutter::EmbedderSurfaceVulkanImpeller>(
673 config->vulkan.version, vk_instance,
678 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
679 static_cast<VkDevice>(config->vulkan.device),
681 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
682 view_embedder);
683
684 return fml::MakeCopyable(
685 [embedder_surface = std::move(embedder_surface),
686 platform_dispatch_table,
687 external_view_embedder =
688 std::move(view_embedder)](flutter::Shell& shell) mutable {
689 return std::make_unique<flutter::PlatformViewEmbedder>(
690 shell, // delegate
691 shell.GetTaskRunners(), // task runners
692 std::move(embedder_surface), // embedder surface
693 platform_dispatch_table, // platform dispatch table
694 std::move(external_view_embedder) // external view embedder
695 );
696 });
697 } else {
699 {
701 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
702 .get_next_image = vulkan_get_next_image,
703 .present_image = vulkan_present_image_callback,
704 };
705
706 std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
707 std::make_unique<flutter::EmbedderSurfaceVulkan>(
708 config->vulkan.version, vk_instance,
713 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
714 static_cast<VkDevice>(config->vulkan.device),
716 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
717 view_embedder);
718
719 return fml::MakeCopyable(
720 [embedder_surface = std::move(embedder_surface),
721 platform_dispatch_table,
722 external_view_embedder =
723 std::move(view_embedder)](flutter::Shell& shell) mutable {
724 return std::make_unique<flutter::PlatformViewEmbedder>(
725 shell, // delegate
726 shell.GetTaskRunners(), // task runners
727 std::move(embedder_surface), // embedder surface
728 platform_dispatch_table, // platform dispatch table
729 std::move(external_view_embedder) // external view embedder
730 );
731 });
732 }
733#else
736 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
737 .get_next_image = vulkan_get_next_image,
738 .present_image = vulkan_present_image_callback,
739 };
740
741 std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
742 std::make_unique<flutter::EmbedderSurfaceVulkan>(
743 config->vulkan.version, vk_instance,
748 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
749 static_cast<VkDevice>(config->vulkan.device),
751 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
752 view_embedder);
753
754 return fml::MakeCopyable(
755 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
756 external_view_embedder =
757 std::move(view_embedder)](flutter::Shell& shell) mutable {
758 return std::make_unique<flutter::PlatformViewEmbedder>(
759 shell, // delegate
760 shell.GetTaskRunners(), // task runners
761 std::move(embedder_surface), // embedder surface
762 platform_dispatch_table, // platform dispatch table
763 std::move(external_view_embedder) // external view embedder
764 );
765 });
766#endif // // IMPELLER_SUPPORTS_RENDERING
767#else // SHELL_ENABLE_VULKAN
768 FML_LOG(ERROR) << "This Flutter Engine does not support Vulkan rendering.";
769 return nullptr;
770#endif // SHELL_ENABLE_VULKAN
771}
772
775 const FlutterRendererConfig* config,
776 void* user_data,
778 platform_dispatch_table,
779 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
780 external_view_embedder) {
781 if (config->type != kSoftware) {
782 return nullptr;
783 }
784
785 auto software_present_backing_store =
787 const void* allocation, size_t row_bytes, size_t height) -> bool {
788 return ptr(user_data, allocation, row_bytes, height);
789 };
790
792 software_dispatch_table = {
793 software_present_backing_store, // required
794 };
795
796 return fml::MakeCopyable(
797 [software_dispatch_table, platform_dispatch_table,
798 external_view_embedder =
799 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
800 return std::make_unique<flutter::PlatformViewEmbedder>(
801 shell, // delegate
802 shell.GetTaskRunners(), // task runners
803 software_dispatch_table, // software dispatch table
804 platform_dispatch_table, // platform dispatch table
805 std::move(external_view_embedder) // external view embedder
806 );
807 });
808}
809
812 const FlutterRendererConfig* config,
813 void* user_data,
815 platform_dispatch_table,
816 std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
817 external_view_embedder,
818 bool enable_impeller) {
819 if (config == nullptr) {
820 return nullptr;
821 }
822
823 switch (config->type) {
824 case kOpenGL:
826 config, user_data, platform_dispatch_table,
827 std::move(external_view_embedder), enable_impeller);
828 case kSoftware:
830 config, user_data, platform_dispatch_table,
831 std::move(external_view_embedder));
832 case kMetal:
834 config, user_data, platform_dispatch_table,
835 std::move(external_view_embedder), enable_impeller);
836 case kVulkan:
838 config, user_data, platform_dispatch_table,
839 std::move(external_view_embedder), enable_impeller);
840 default:
841 return nullptr;
842 }
843 return nullptr;
844}
845
846static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
847 GrDirectContext* context,
848 const FlutterBackingStoreConfig& config,
850#ifdef SHELL_ENABLE_GL
851 GrGLTextureInfo texture_info;
852 texture_info.fTarget = texture->target;
853 texture_info.fID = texture->name;
854 texture_info.fFormat = texture->format;
855
856 GrBackendTexture backend_texture =
857 GrBackendTextures::MakeGL(config.size.width, config.size.height,
858 skgpu::Mipmapped::kNo, texture_info);
859
860 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
861
862 std::optional<SkColorType> color_type =
863 FlutterFormatToSkColorType(texture->format);
864 if (!color_type) {
865 return nullptr;
866 }
867
868 auto surface = SkSurfaces::WrapBackendTexture(
869 context, // context
870 backend_texture, // back-end texture
871 kBottomLeft_GrSurfaceOrigin, // surface origin
872 1, // sample count
873 color_type.value(), // color type
874 SkColorSpace::MakeSRGB(), // color space
875 &surface_properties, // surface properties
876 static_cast<SkSurfaces::TextureReleaseProc>(
877 texture->destruction_callback), // release proc
878 texture->user_data // release context
879 );
880
881 if (!surface) {
882 FML_LOG(ERROR) << "Could not wrap embedder supplied render texture.";
883 return nullptr;
884 }
885
886 return surface;
887#else
888 return nullptr;
889#endif
890}
891
892static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
893 GrDirectContext* context,
894 const FlutterBackingStoreConfig& config,
895 const FlutterOpenGLFramebuffer* framebuffer) {
896#ifdef SHELL_ENABLE_GL
897 GrGLFramebufferInfo framebuffer_info = {};
898 framebuffer_info.fFormat = framebuffer->target;
899 framebuffer_info.fFBOID = framebuffer->name;
900
901 auto backend_render_target =
902 GrBackendRenderTargets::MakeGL(config.size.width, // width
903 config.size.height, // height
904 1, // sample count
905 0, // stencil bits
906 framebuffer_info // framebuffer info
907 );
908
909 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
910
911 std::optional<SkColorType> color_type =
912 FlutterFormatToSkColorType(framebuffer->target);
913 if (!color_type) {
914 return nullptr;
915 }
916
917 auto surface = SkSurfaces::WrapBackendRenderTarget(
918 context, // context
919 backend_render_target, // backend render target
920 kBottomLeft_GrSurfaceOrigin, // surface origin
921 color_type.value(), // color type
922 SkColorSpace::MakeSRGB(), // color space
923 &surface_properties, // surface properties
924 static_cast<SkSurfaces::RenderTargetReleaseProc>(
925 framebuffer->destruction_callback), // release proc
926 framebuffer->user_data // release context
927 );
928
929 if (!surface) {
930 FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
931 return nullptr;
932 }
933 return surface;
934#else
935 return nullptr;
936#endif
937}
938
939static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
940 GrDirectContext* context,
941 const FlutterBackingStoreConfig& config,
942 const FlutterOpenGLSurface* surface) {
943#ifdef SHELL_ENABLE_GL
944 GrGLFramebufferInfo framebuffer_info = {};
945 framebuffer_info.fFormat = SAFE_ACCESS(surface, format, GL_BGRA8_EXT);
946 framebuffer_info.fFBOID = 0;
947
948 auto backend_render_target =
949 GrBackendRenderTargets::MakeGL(config.size.width, // width
950 config.size.height, // height
951 1, // sample count
952 0, // stencil bits
953 framebuffer_info // framebuffer info
954 );
955
956 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
957
958 std::optional<SkColorType> color_type =
959 FlutterFormatToSkColorType(surface->format);
960 if (!color_type) {
961 return nullptr;
962 }
963
964 auto sk_surface = SkSurfaces::WrapBackendRenderTarget(
965 context, // context
966 backend_render_target, // backend render target
967 kBottomLeft_GrSurfaceOrigin, // surface origin
968 color_type.value(), // color type
969 SkColorSpace::MakeSRGB(), // color space
970 &surface_properties, // surface properties
971 static_cast<SkSurfaces::RenderTargetReleaseProc>(
972 surface->destruction_callback), // release proc
973 surface->user_data // release context
974 );
975
976 if (!sk_surface) {
977 FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
978 return nullptr;
979 }
980 return sk_surface;
981#else
982 return nullptr;
983#endif
984}
985
986static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
987 GrDirectContext* context,
988 const FlutterBackingStoreConfig& config,
989 const FlutterSoftwareBackingStore* software) {
990 const auto image_info =
991 SkImageInfo::MakeN32Premul(config.size.width, config.size.height);
992
993 struct Captures {
994 VoidCallback destruction_callback;
995 void* user_data;
996 };
997 auto captures = std::make_unique<Captures>();
998 captures->destruction_callback = software->destruction_callback;
999 captures->user_data = software->user_data;
1000 auto release_proc = [](void* pixels, void* context) {
1001 auto captures = reinterpret_cast<Captures*>(context);
1002 if (captures->destruction_callback) {
1003 captures->destruction_callback(captures->user_data);
1004 }
1005 delete captures;
1006 };
1007
1008 auto surface =
1009 SkSurfaces::WrapPixels(image_info, // image info
1010 const_cast<void*>(software->allocation), // pixels
1011 software->row_bytes, // row bytes
1012 release_proc, // release proc
1013 captures.get() // get context
1014 );
1015
1016 if (!surface) {
1017 FML_LOG(ERROR)
1018 << "Could not wrap embedder supplied software render buffer.";
1019 if (software->destruction_callback) {
1020 software->destruction_callback(software->user_data);
1021 }
1022 return nullptr;
1023 }
1024 if (surface) {
1025 captures.release(); // Skia has assumed ownership of the struct.
1026 }
1027 return surface;
1028}
1029
1030static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
1031 GrDirectContext* context,
1032 const FlutterBackingStoreConfig& config,
1033 const FlutterSoftwareBackingStore2* software) {
1034 const auto color_info = getSkColorInfo(software->pixel_format);
1035 if (!color_info) {
1036 return nullptr;
1037 }
1038
1039 const auto image_info = SkImageInfo::Make(
1040 SkISize::Make(config.size.width, config.size.height), *color_info);
1041
1042 struct Captures {
1043 VoidCallback destruction_callback;
1044 void* user_data;
1045 };
1046 auto captures = std::make_unique<Captures>();
1047 captures->destruction_callback = software->destruction_callback;
1048 captures->user_data = software->user_data;
1049 auto release_proc = [](void* pixels, void* context) {
1050 auto captures = reinterpret_cast<Captures*>(context);
1051 if (captures->destruction_callback) {
1052 captures->destruction_callback(captures->user_data);
1053 }
1054 };
1055
1056 auto surface =
1057 SkSurfaces::WrapPixels(image_info, // image info
1058 const_cast<void*>(software->allocation), // pixels
1059 software->row_bytes, // row bytes
1060 release_proc, // release proc
1061 captures.release() // release context
1062 );
1063
1064 if (!surface) {
1065 FML_LOG(ERROR)
1066 << "Could not wrap embedder supplied software render buffer.";
1067 if (software->destruction_callback) {
1068 software->destruction_callback(software->user_data);
1069 }
1070 return nullptr;
1071 }
1072 return surface;
1073}
1074
1075static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
1076 GrDirectContext* context,
1077 const FlutterBackingStoreConfig& config,
1078 const FlutterMetalBackingStore* metal) {
1079#if defined(SHELL_ENABLE_METAL) && !SLIMPELLER
1080 GrMtlTextureInfo texture_info;
1081 if (!metal->texture.texture) {
1082 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
1083 return nullptr;
1084 }
1085 sk_cfp<FlutterMetalTextureHandle> mtl_texture;
1086 mtl_texture.retain(metal->texture.texture);
1087 texture_info.fTexture = mtl_texture;
1088 GrBackendTexture backend_texture =
1089 GrBackendTextures::MakeMtl(config.size.width, //
1090 config.size.height, //
1091 skgpu::Mipmapped::kNo, //
1092 texture_info //
1093 );
1094
1095 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
1096
1097 auto surface = SkSurfaces::WrapBackendTexture(
1098 context, // context
1099 backend_texture, // back-end texture
1100 kTopLeft_GrSurfaceOrigin, // surface origin
1101 1, // sample count
1102 kBGRA_8888_SkColorType, // color type
1103 nullptr, // color space
1104 &surface_properties, // surface properties
1105 static_cast<SkSurfaces::TextureReleaseProc>(
1106 metal->texture.destruction_callback), // release proc
1107 metal->texture.user_data // release context
1108 );
1109
1110 if (!surface) {
1111 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
1112 return nullptr;
1113 }
1114
1115 return surface;
1116#else
1117 return nullptr;
1118#endif
1119}
1120
1121#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
1122static std::optional<impeller::PixelFormat> FlutterFormatToImpellerPixelFormat(
1123 uint32_t format) {
1124 switch (format) {
1125 case GL_BGRA8_EXT:
1127 case GL_RGBA8:
1129 default:
1130 FML_LOG(ERROR) << "Cannot convert format " << format
1131 << " to impeller::PixelFormat.";
1132 return std::nullopt;
1133 }
1134}
1135
1136#endif // defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
1137
1138static std::unique_ptr<flutter::EmbedderRenderTarget>
1140 FlutterBackingStore backing_store,
1141 const fml::closure& on_release,
1142 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1143 const FlutterBackingStoreConfig& config,
1144 const FlutterOpenGLFramebuffer* framebuffer) {
1145#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
1146 auto format = FlutterFormatToImpellerPixelFormat(framebuffer->target);
1147 if (!format.has_value()) {
1148 return nullptr;
1149 }
1150
1151 const auto& gl_context =
1152 impeller::ContextGLES::Cast(*aiks_context->GetContext());
1153 const bool implicit_msaa = aiks_context->GetContext()
1154 ->GetCapabilities()
1155 ->SupportsImplicitResolvingMSAA();
1156 const auto size = impeller::ISize(config.size.width, config.size.height);
1157
1158 impeller::TextureDescriptor color0_tex;
1159 if (implicit_msaa) {
1162 } else {
1165 }
1166 color0_tex.format = format.value();
1167 color0_tex.size = size;
1168 color0_tex.usage = static_cast<impeller::TextureUsageMask>(
1171
1174 gl_context.GetReactor(), color0_tex, framebuffer->name);
1177 if (implicit_msaa) {
1179 color0.resolve_texture = color0.texture;
1180 } else {
1182 }
1183
1184 impeller::TextureDescriptor depth_stencil_texture_desc;
1185 depth_stencil_texture_desc.format = impeller::PixelFormat::kD24UnormS8Uint;
1186 depth_stencil_texture_desc.size = size;
1187 depth_stencil_texture_desc.usage = static_cast<impeller::TextureUsageMask>(
1189 if (implicit_msaa) {
1190 depth_stencil_texture_desc.type =
1192 depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount4;
1193 } else {
1194 depth_stencil_texture_desc.type = impeller::TextureType::kTexture2D;
1195 depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount1;
1196 }
1197
1198 auto depth_stencil_tex = impeller::TextureGLES::CreatePlaceholder(
1199 gl_context.GetReactor(), depth_stencil_texture_desc);
1200
1202 depth0.clear_depth = 0;
1203 depth0.texture = depth_stencil_tex;
1206
1208 stencil0.clear_stencil = 0;
1209 stencil0.texture = depth_stencil_tex;
1212
1213 impeller::RenderTarget render_target_desc;
1214
1215 render_target_desc.SetColorAttachment(color0, 0u);
1216 render_target_desc.SetDepthAttachment(depth0);
1217 render_target_desc.SetStencilAttachment(stencil0);
1218
1219 fml::closure framebuffer_destruct =
1220 [callback = framebuffer->destruction_callback,
1221 user_data = framebuffer->user_data]() { callback(user_data); };
1222
1223 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1224 backing_store, aiks_context,
1225 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1226 on_release, framebuffer_destruct);
1227#else
1228 return nullptr;
1229#endif
1230}
1231
1232static std::unique_ptr<flutter::EmbedderRenderTarget>
1234 FlutterBackingStore backing_store,
1235 const fml::closure& on_release,
1236 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1237 const FlutterBackingStoreConfig& config,
1238 const FlutterMetalBackingStore* metal) {
1239#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING)
1240 if (!metal->texture.texture) {
1241 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
1242 return nullptr;
1243 }
1244
1245 const auto size = impeller::ISize(config.size.width, config.size.height);
1246
1247 impeller::TextureDescriptor resolve_tex_desc;
1248 resolve_tex_desc.size = size;
1251 resolve_tex_desc.usage = impeller::TextureUsage::kRenderTarget |
1253
1254 auto resolve_tex = impeller::WrapTextureMTL(
1255 resolve_tex_desc, metal->texture.texture,
1257 user_data = metal->texture.user_data]() { callback(user_data); });
1258 if (!resolve_tex) {
1259 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
1260 return nullptr;
1261 }
1262
1263 aiks_context->GetContext()->UpdateOffscreenLayerPixelFormat(
1264 resolve_tex->GetTextureDescriptor().format);
1265
1266 resolve_tex->SetLabel("ImpellerBackingStoreResolve");
1267
1268 impeller::TextureDescriptor msaa_tex_desc;
1272 msaa_tex_desc.format = resolve_tex->GetTextureDescriptor().format;
1273 msaa_tex_desc.size = size;
1275
1276 auto msaa_tex =
1277 aiks_context->GetContext()->GetResourceAllocator()->CreateTexture(
1278 msaa_tex_desc);
1279 if (!msaa_tex) {
1280 FML_LOG(ERROR) << "Could not allocate MSAA color texture.";
1281 return nullptr;
1282 }
1283 msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA");
1284
1286 color0.texture = msaa_tex;
1290 color0.resolve_texture = resolve_tex;
1291
1292 impeller::RenderTarget render_target_desc;
1293 render_target_desc.SetColorAttachment(color0, 0u);
1294
1295 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1296 backing_store, aiks_context,
1297 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1298 on_release, fml::closure());
1299#else
1300 return nullptr;
1301#endif
1302}
1303
1304static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
1305 GrDirectContext* context,
1306 const FlutterBackingStoreConfig& config,
1308#ifdef SHELL_ENABLE_VULKAN
1309 if (!vulkan->image) {
1310 FML_LOG(ERROR) << "Embedder supplied null Vulkan image.";
1311 return nullptr;
1312 }
1313 GrVkImageInfo image_info = {
1314 .fImage = reinterpret_cast<VkImage>(vulkan->image->image),
1315 .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
1316 .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1317 .fFormat = static_cast<VkFormat>(vulkan->image->format),
1318 .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
1319 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1320 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1321 VK_IMAGE_USAGE_SAMPLED_BIT,
1322 .fSampleCount = 1,
1323 .fLevelCount = 1,
1324 };
1325 auto backend_texture = GrBackendTextures::MakeVk(
1326 config.size.width, config.size.height, image_info);
1327
1328 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
1329
1330 auto surface = SkSurfaces::WrapBackendTexture(
1331 context, // context
1332 backend_texture, // back-end texture
1333 kTopLeft_GrSurfaceOrigin, // surface origin
1334 1, // sample count
1336 static_cast<VkFormat>(vulkan->image->format)), // color type
1337 SkColorSpace::MakeSRGB(), // color space
1338 &surface_properties, // surface properties
1339 static_cast<SkSurfaces::TextureReleaseProc>(
1340 vulkan->destruction_callback), // release proc
1341 vulkan->user_data // release context
1342 );
1343
1344 if (!surface) {
1345 FML_LOG(ERROR) << "Could not wrap embedder supplied Vulkan render texture.";
1346 return nullptr;
1347 }
1348
1349 return surface;
1350#else
1351 return nullptr;
1352#endif
1353}
1354
1355static std::unique_ptr<flutter::EmbedderRenderTarget>
1357 FlutterBackingStore backing_store,
1358 sk_sp<SkSurface> skia_surface,
1359 fml::closure on_release,
1362 on_clear_current) {
1363 if (!skia_surface) {
1364 return nullptr;
1365 }
1366 return std::make_unique<flutter::EmbedderRenderTargetSkia>(
1367 backing_store, std::move(skia_surface), std::move(on_release),
1368 std::move(on_make_current), std::move(on_clear_current));
1369}
1370
1371static std::unique_ptr<flutter::EmbedderRenderTarget>
1373 sk_sp<SkSurface> skia_surface,
1374 fml::closure on_release) {
1375 return MakeRenderTargetFromSkSurface(backing_store, std::move(skia_surface),
1376 std::move(on_release), nullptr, nullptr);
1377}
1378
1379static std::unique_ptr<flutter::EmbedderRenderTarget>
1381 const FlutterCompositor* compositor,
1382 const FlutterBackingStoreConfig& config,
1383 GrDirectContext* context,
1384 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1385 bool enable_impeller) {
1386 FlutterBackingStore backing_store = {};
1387 backing_store.struct_size = sizeof(backing_store);
1388
1389 // Safe access checks on the compositor struct have been performed in
1390 // InferExternalViewEmbedderFromArgs and are not necessary here.
1391 auto c_create_callback = compositor->create_backing_store_callback;
1392 auto c_collect_callback = compositor->collect_backing_store_callback;
1393
1394 {
1395 TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
1396 if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
1397 FML_LOG(ERROR) << "Could not create the embedder backing store.";
1398 return nullptr;
1399 }
1400 }
1401
1402 if (backing_store.struct_size != sizeof(backing_store)) {
1403 FML_LOG(ERROR) << "Embedder modified the backing store struct size.";
1404 return nullptr;
1405 }
1406
1407 // In case we return early without creating an embedder render target, the
1408 // embedder has still given us ownership of its baton which we must return
1409 // back to it. If this method is successful, the closure is released when the
1410 // render target is eventually released.
1411 fml::ScopedCleanupClosure collect_callback(
1412 [c_collect_callback, backing_store, user_data = compositor->user_data]() {
1413 TRACE_EVENT0("flutter", "FlutterCompositorCollectBackingStore");
1414 c_collect_callback(&backing_store, user_data);
1415 });
1416
1417 // No safe access checks on the renderer are necessary since we allocated
1418 // the struct.
1419
1420 std::unique_ptr<flutter::EmbedderRenderTarget> render_target;
1421
1422 switch (backing_store.type) {
1424 switch (backing_store.open_gl.type) {
1426 auto skia_surface = MakeSkSurfaceFromBackingStore(
1427 context, config, &backing_store.open_gl.texture);
1428 render_target = MakeRenderTargetFromSkSurface(
1429 backing_store, std::move(skia_surface),
1430 collect_callback.Release());
1431 break;
1432 }
1434 if (enable_impeller) {
1436 backing_store, collect_callback.Release(), aiks_context, config,
1437 &backing_store.open_gl.framebuffer);
1438 break;
1439 } else {
1440 auto skia_surface = MakeSkSurfaceFromBackingStore(
1441 context, config, &backing_store.open_gl.framebuffer);
1442 render_target = MakeRenderTargetFromSkSurface(
1443 backing_store, std::move(skia_surface),
1444 collect_callback.Release());
1445 break;
1446 }
1447 }
1448
1450 auto on_make_current =
1452 context = backing_store.open_gl.surface.user_data]()
1454 bool invalidate_api_state = false;
1455 bool ok = callback(context, &invalidate_api_state);
1456 return {ok, invalidate_api_state};
1457 };
1458
1459 auto on_clear_current =
1461 context = backing_store.open_gl.surface.user_data]()
1463 bool invalidate_api_state = false;
1464 bool ok = callback(context, &invalidate_api_state);
1465 return {ok, invalidate_api_state};
1466 };
1467
1468 if (enable_impeller) {
1469 // TODO(https://github.com/flutter/flutter/issues/151670): Implement
1470 // GL Surface backing stores for Impeller.
1471 FML_LOG(ERROR) << "Unimplemented";
1472 break;
1473 } else {
1474 auto skia_surface = MakeSkSurfaceFromBackingStore(
1475 context, config, &backing_store.open_gl.surface);
1476
1477 render_target = MakeRenderTargetFromSkSurface(
1478 backing_store, std::move(skia_surface),
1479 collect_callback.Release(), on_make_current, on_clear_current);
1480 break;
1481 }
1482 }
1483 }
1484 break;
1485 }
1486
1488 auto skia_surface = MakeSkSurfaceFromBackingStore(
1489 context, config, &backing_store.software);
1490 render_target = MakeRenderTargetFromSkSurface(
1491 backing_store, std::move(skia_surface), collect_callback.Release());
1492 break;
1493 }
1495 auto skia_surface = MakeSkSurfaceFromBackingStore(
1496 context, config, &backing_store.software2);
1497 render_target = MakeRenderTargetFromSkSurface(
1498 backing_store, std::move(skia_surface), collect_callback.Release());
1499 break;
1500 }
1502 if (enable_impeller) {
1504 backing_store, collect_callback.Release(), aiks_context, config,
1505 &backing_store.metal);
1506 } else {
1507 auto skia_surface = MakeSkSurfaceFromBackingStore(context, config,
1508 &backing_store.metal);
1509 render_target = MakeRenderTargetFromSkSurface(
1510 backing_store, std::move(skia_surface), collect_callback.Release());
1511 }
1512 break;
1513 }
1515 if (enable_impeller) {
1516 FML_LOG(ERROR) << "Unimplemented";
1517 break;
1518 } else {
1519 auto skia_surface = MakeSkSurfaceFromBackingStore(
1520 context, config, &backing_store.vulkan);
1521 render_target = MakeRenderTargetFromSkSurface(
1522 backing_store, std::move(skia_surface), collect_callback.Release());
1523 break;
1524 }
1525 }
1526 };
1527
1528 if (!render_target) {
1529 FML_LOG(ERROR) << "Could not create a surface from an embedder provided "
1530 "render target.";
1531 }
1532 return render_target;
1533}
1534
1535/// Creates an EmbedderExternalViewEmbedder.
1536///
1537/// When a non-OK status is returned, engine startup should be halted.
1540 bool enable_impeller) {
1541 if (compositor == nullptr) {
1542 return std::unique_ptr<flutter::EmbedderExternalViewEmbedder>{nullptr};
1543 }
1544
1545 auto c_create_callback =
1546 SAFE_ACCESS(compositor, create_backing_store_callback, nullptr);
1547 auto c_collect_callback =
1548 SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
1549 auto c_present_callback =
1550 SAFE_ACCESS(compositor, present_layers_callback, nullptr);
1551 auto c_present_view_callback =
1552 SAFE_ACCESS(compositor, present_view_callback, nullptr);
1553 bool avoid_backing_store_cache =
1554 SAFE_ACCESS(compositor, avoid_backing_store_cache, false);
1555
1556 // Make sure the required callbacks are present
1557 if (!c_create_callback || !c_collect_callback) {
1559 "Required compositor callbacks absent.");
1560 }
1561 // Either the present view or the present layers callback must be provided.
1562 if ((!c_present_view_callback && !c_present_callback) ||
1563 (c_present_view_callback && c_present_callback)) {
1565 "Either present_layers_callback or "
1566 "present_view_callback must be provided but not both.");
1567 }
1568
1569 FlutterCompositor captured_compositor = *compositor;
1570
1572 create_render_target_callback =
1573 [captured_compositor, enable_impeller](
1574 GrDirectContext* context,
1575 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1576 const auto& config) {
1577 return CreateEmbedderRenderTarget(&captured_compositor, config,
1578 context, aiks_context,
1579 enable_impeller);
1580 };
1581
1583 if (c_present_callback) {
1584 present_callback = [c_present_callback, user_data = compositor->user_data](
1585 FlutterViewId view_id, const auto& layers) {
1586 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1587 return c_present_callback(const_cast<const FlutterLayer**>(layers.data()),
1588 layers.size(), user_data);
1589 };
1590 } else {
1591 FML_DCHECK(c_present_view_callback != nullptr);
1592 present_callback = [c_present_view_callback,
1593 user_data = compositor->user_data](
1594 FlutterViewId view_id, const auto& layers) {
1595 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1596
1597 FlutterPresentViewInfo info = {
1599 .view_id = view_id,
1600 .layers = const_cast<const FlutterLayer**>(layers.data()),
1602 .user_data = user_data,
1603 };
1604
1605 return c_present_view_callback(&info);
1606 };
1607 }
1608
1609 return std::make_unique<flutter::EmbedderExternalViewEmbedder>(
1610 avoid_backing_store_cache, create_render_target_callback,
1611 present_callback);
1612}
1613
1614// Translates embedder metrics to engine metrics, or returns a string on error.
1615static std::variant<flutter::ViewportMetrics, std::string>
1617 const FlutterWindowMetricsEvent* flutter_metrics) {
1618 if (flutter_metrics == nullptr) {
1619 return "Invalid metrics handle.";
1620 }
1621
1623
1624 metrics.physical_width = SAFE_ACCESS(flutter_metrics, width, 0.0);
1625 metrics.physical_height = SAFE_ACCESS(flutter_metrics, height, 0.0);
1626
1627 if (SAFE_ACCESS(flutter_metrics, has_constraints, false)) {
1629 flutter_metrics, min_width_constraint, metrics.physical_width);
1631 flutter_metrics, max_width_constraint, metrics.physical_width);
1633 flutter_metrics, min_height_constraint, metrics.physical_height);
1635 flutter_metrics, max_height_constraint, metrics.physical_height);
1636 } else {
1641 }
1642
1643 if (metrics.physical_width < metrics.physical_min_width_constraint ||
1647 return "Window metrics are invalid. Width and height must be within the "
1648 "specified constraints.";
1649 }
1650
1651 metrics.device_pixel_ratio = SAFE_ACCESS(flutter_metrics, pixel_ratio, 1.0);
1652 metrics.physical_view_inset_top =
1653 SAFE_ACCESS(flutter_metrics, physical_view_inset_top, 0.0);
1655 SAFE_ACCESS(flutter_metrics, physical_view_inset_right, 0.0);
1657 SAFE_ACCESS(flutter_metrics, physical_view_inset_bottom, 0.0);
1658 metrics.physical_view_inset_left =
1659 SAFE_ACCESS(flutter_metrics, physical_view_inset_left, 0.0);
1660 metrics.display_id = SAFE_ACCESS(flutter_metrics, display_id, 0);
1661
1662 if (metrics.device_pixel_ratio <= 0.0) {
1663 return "Device pixel ratio was invalid. It must be greater than zero.";
1664 }
1665
1666 if (metrics.physical_view_inset_top < 0 ||
1667 metrics.physical_view_inset_right < 0 ||
1668 metrics.physical_view_inset_bottom < 0 ||
1669 metrics.physical_view_inset_left < 0) {
1670 return "Physical view insets are invalid. They must be non-negative.";
1671 }
1672
1673 if (metrics.physical_view_inset_top > metrics.physical_height ||
1674 metrics.physical_view_inset_right > metrics.physical_width ||
1675 metrics.physical_view_inset_bottom > metrics.physical_height ||
1676 metrics.physical_view_inset_left > metrics.physical_width) {
1677 return "Physical view insets are invalid. They cannot be greater than "
1678 "physical height or width.";
1679 }
1680
1681 return metrics;
1682}
1683
1685 std::unique_ptr<flutter::PlatformMessage> message;
1686};
1687
1689 void operator()(Dart_LoadedElf* elf) {
1690 if (elf) {
1691 ::Dart_UnloadELF(elf);
1692 }
1693 }
1694};
1695
1696using UniqueLoadedElf = std::unique_ptr<Dart_LoadedElf, LoadedElfDeleter>;
1697
1700 const uint8_t* vm_snapshot_data = nullptr;
1701 const uint8_t* vm_snapshot_instrs = nullptr;
1702 const uint8_t* vm_isolate_data = nullptr;
1703 const uint8_t* vm_isolate_instrs = nullptr;
1704};
1705
1707 const FlutterEngineAOTDataSource* source,
1708 FlutterEngineAOTData* data_out) {
1711 "AOT data can only be created in AOT mode.");
1712 } else if (!source) {
1713 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null source specified.");
1714 } else if (!data_out) {
1715 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null data_out specified.");
1716 }
1717
1718 switch (source->type) {
1720 if (!source->elf_path || !fml::IsFile(source->elf_path)) {
1722 "Invalid ELF path specified.");
1723 }
1724
1725 auto aot_data = std::make_unique<_FlutterEngineAOTData>();
1726 const char* error = nullptr;
1727
1728#if OS_FUCHSIA
1729 // TODO(gw280): https://github.com/flutter/flutter/issues/50285
1730 // Dart doesn't implement Dart_LoadELF on Fuchsia
1731 Dart_LoadedElf* loaded_elf = nullptr;
1732#else
1733 Dart_LoadedElf* loaded_elf = Dart_LoadELF(
1734 source->elf_path, // file path
1735 0, // file offset
1736 &error, // error (out)
1737 &aot_data->vm_snapshot_data, // vm snapshot data (out)
1738 &aot_data->vm_snapshot_instrs, // vm snapshot instr (out)
1739 &aot_data->vm_isolate_data, // vm isolate data (out)
1740 &aot_data->vm_isolate_instrs // vm isolate instr (out)
1741 );
1742#endif
1743
1744 if (loaded_elf == nullptr) {
1746 }
1747
1748 aot_data->loaded_elf.reset(loaded_elf);
1749
1750 *data_out = aot_data.release();
1751 return kSuccess;
1752 }
1753 }
1754
1755 return LOG_EMBEDDER_ERROR(
1757 "Invalid FlutterEngineAOTDataSourceType type specified.");
1758}
1759
1761 if (!data) {
1762 // Deleting a null object should be a no-op.
1763 return kSuccess;
1764 }
1765
1766 // Created in a unique pointer in `FlutterEngineCreateAOTData`.
1767 delete data;
1768 return kSuccess;
1769}
1770
1771// Constructs appropriate mapping callbacks if JIT snapshot locations have been
1772// explictly specified.
1774 flutter::Settings& settings) {
1775 auto make_mapping_callback = [](const char* path, bool executable) {
1776 return [path, executable]() {
1777 if (executable) {
1779 } else {
1781 }
1782 };
1783 };
1784
1785 // Users are allowed to specify only certain snapshots if they so desire.
1786 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1787 settings.vm_snapshot_data = make_mapping_callback(
1788 reinterpret_cast<const char*>(args->vm_snapshot_data), false);
1789 }
1790
1791 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1792 settings.vm_snapshot_instr = make_mapping_callback(
1793 reinterpret_cast<const char*>(args->vm_snapshot_instructions), true);
1794 }
1795
1796 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1797 settings.isolate_snapshot_data = make_mapping_callback(
1798 reinterpret_cast<const char*>(args->isolate_snapshot_data), false);
1799 }
1800
1801 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1802 settings.isolate_snapshot_instr = make_mapping_callback(
1803 reinterpret_cast<const char*>(args->isolate_snapshot_instructions),
1804 true);
1805 }
1806
1807#if !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
1808 settings.dart_library_sources_kernel = []() {
1809 return std::make_unique<fml::NonOwnedMapping>(kPlatformStrongDill,
1811 };
1812#endif // !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE ==
1813 // FLUTTER_RUNTIME_MODE_DEBUG)
1814}
1815
1817 const FlutterProjectArgs* args,
1818 flutter::Settings& settings) { // NOLINT(google-runtime-references)
1819 // There are no ownership concerns here as all mappings are owned by the
1820 // embedder and not the engine.
1821 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
1822 return [mapping, size]() {
1823 return std::make_unique<fml::NonOwnedMapping>(mapping, size);
1824 };
1825 };
1826
1827 if (SAFE_ACCESS(args, aot_data, nullptr) != nullptr) {
1828 settings.vm_snapshot_data =
1829 make_mapping_callback(args->aot_data->vm_snapshot_data, 0);
1830
1831 settings.vm_snapshot_instr =
1832 make_mapping_callback(args->aot_data->vm_snapshot_instrs, 0);
1833
1834 settings.isolate_snapshot_data =
1835 make_mapping_callback(args->aot_data->vm_isolate_data, 0);
1836
1837 settings.isolate_snapshot_instr =
1838 make_mapping_callback(args->aot_data->vm_isolate_instrs, 0);
1839 }
1840
1841 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1842 settings.vm_snapshot_data = make_mapping_callback(
1843 args->vm_snapshot_data, SAFE_ACCESS(args, vm_snapshot_data_size, 0));
1844 }
1845
1846 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1847 settings.vm_snapshot_instr = make_mapping_callback(
1848 args->vm_snapshot_instructions,
1849 SAFE_ACCESS(args, vm_snapshot_instructions_size, 0));
1850 }
1851
1852 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1853 settings.isolate_snapshot_data =
1854 make_mapping_callback(args->isolate_snapshot_data,
1855 SAFE_ACCESS(args, isolate_snapshot_data_size, 0));
1856 }
1857
1858 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1859 settings.isolate_snapshot_instr = make_mapping_callback(
1860 args->isolate_snapshot_instructions,
1861 SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0));
1862 }
1863}
1864
1865// Create a callback to notify the embedder of semantic updates
1866// using the legacy embedder callbacks 'update_semantics_node_callback' and
1867// 'update_semantics_custom_action_callback'.
1870 FlutterUpdateSemanticsNodeCallback update_semantics_node_callback,
1872 update_semantics_custom_action_callback,
1873 void* user_data) {
1874 return [update_semantics_node_callback,
1875 update_semantics_custom_action_callback, user_data](
1876 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1878 flutter::EmbedderSemanticsUpdate update{nodes, actions};
1879 FlutterSemanticsUpdate* update_ptr = update.get();
1880
1881 // First, queue all node and custom action updates.
1882 if (update_semantics_node_callback != nullptr) {
1883 for (size_t i = 0; i < update_ptr->nodes_count; i++) {
1884 update_semantics_node_callback(&update_ptr->nodes[i], user_data);
1885 }
1886 }
1887
1888 if (update_semantics_custom_action_callback != nullptr) {
1889 for (size_t i = 0; i < update_ptr->custom_actions_count; i++) {
1890 update_semantics_custom_action_callback(&update_ptr->custom_actions[i],
1891 user_data);
1892 }
1893 }
1894
1895 // Second, mark node and action batches completed now that all
1896 // updates are queued.
1897 if (update_semantics_node_callback != nullptr) {
1898 const FlutterSemanticsNode batch_end_sentinel = {
1899 sizeof(FlutterSemanticsNode),
1901 };
1902 update_semantics_node_callback(&batch_end_sentinel, user_data);
1903 }
1904
1905 if (update_semantics_custom_action_callback != nullptr) {
1906 const FlutterSemanticsCustomAction batch_end_sentinel = {
1909 };
1910 update_semantics_custom_action_callback(&batch_end_sentinel, user_data);
1911 }
1912 };
1913}
1914
1915// Create a callback to notify the embedder of semantic updates
1916// using the deprecated embedder callback 'update_semantics_callback'.
1919 FlutterUpdateSemanticsCallback update_semantics_callback,
1920 void* user_data) {
1921 return [update_semantics_callback, user_data](
1922 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1924 flutter::EmbedderSemanticsUpdate update{nodes, actions};
1925
1926 update_semantics_callback(update.get(), user_data);
1927 };
1928}
1929
1930// Create a callback to notify the embedder of semantic updates
1931// using the new embedder callback 'update_semantics_callback2'.
1934 FlutterUpdateSemanticsCallback2 update_semantics_callback,
1935 void* user_data) {
1936 return [update_semantics_callback, user_data](
1937 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1939 flutter::EmbedderSemanticsUpdate2 update{view_id, nodes, actions};
1940
1941 update_semantics_callback(update.get(), user_data);
1942 };
1943}
1944
1945// Creates a callback that receives semantic updates from the engine
1946// and notifies the embedder's callback(s). Returns null if the embedder
1947// did not register any callbacks.
1950 void* user_data) {
1951 // There are three variants for the embedder API's semantic update callbacks.
1952 // Create a callback that maps to the embedder's desired semantic update API.
1953 //
1954 // Handle the case where the embedder registered the callback
1955 // 'updated_semantics_callback2'
1956 if (SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr) {
1958 args->update_semantics_callback2, user_data);
1959 }
1960
1961 // Handle the case where the embedder registered the deprecated callback
1962 // 'update_semantics_callback'.
1963 if (SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr) {
1965 args->update_semantics_callback, user_data);
1966 }
1967
1968 // Handle the case where the embedder registered the deprecated callbacks
1969 // 'update_semantics_node_callback' and
1970 // 'update_semantics_custom_action_callback'.
1971 FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
1972 if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
1973 update_semantics_node_callback = args->update_semantics_node_callback;
1974 }
1975
1977 update_semantics_custom_action_callback = nullptr;
1978 if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
1979 nullptr) {
1980 update_semantics_custom_action_callback =
1981 args->update_semantics_custom_action_callback;
1982 }
1983
1984 if (update_semantics_node_callback != nullptr ||
1985 update_semantics_custom_action_callback != nullptr) {
1987 update_semantics_node_callback, update_semantics_custom_action_callback,
1988 user_data);
1989 }
1990
1991 // Handle the case where the embedder registered no callbacks.
1992 return nullptr;
1993}
1994
1996 const FlutterRendererConfig* config,
1997 const FlutterProjectArgs* args,
1998 void* user_data,
2000 engine_out) {
2001 auto result =
2002 FlutterEngineInitialize(version, config, args, user_data, engine_out);
2003
2004 if (result != kSuccess) {
2005 return result;
2006 }
2007
2008 return FlutterEngineRunInitialized(*engine_out);
2009}
2010
2012 const FlutterRendererConfig* config,
2013 const FlutterProjectArgs* args,
2014 void* user_data,
2016 engine_out) {
2017 // Step 0: Figure out arguments for shell creation.
2018 if (version != FLUTTER_ENGINE_VERSION) {
2019 return LOG_EMBEDDER_ERROR(
2021 "Flutter embedder version mismatch. There has been a breaking change. "
2022 "Please consult the changelog and update the embedder.");
2023 }
2024
2025 if (engine_out == nullptr) {
2027 "The engine out parameter was missing.");
2028 }
2029
2030 if (args == nullptr) {
2032 "The Flutter project arguments were missing.");
2033 }
2034
2035 if (SAFE_ACCESS(args, assets_path, nullptr) == nullptr) {
2036 return LOG_EMBEDDER_ERROR(
2038 "The assets path in the Flutter project arguments was missing.");
2039 }
2040
2041 if (SAFE_ACCESS(args, main_path__unused__, nullptr) != nullptr) {
2042 FML_LOG(WARNING)
2043 << "FlutterProjectArgs.main_path is deprecated and should be set null.";
2044 }
2045
2046 if (SAFE_ACCESS(args, packages_path__unused__, nullptr) != nullptr) {
2047 FML_LOG(WARNING) << "FlutterProjectArgs.packages_path is deprecated and "
2048 "should be set null.";
2049 }
2050
2051 if (!IsRendererValid(config)) {
2053 "The renderer configuration was invalid.");
2054 }
2055
2056 std::string icu_data_path;
2057 if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
2058 icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
2059 }
2060
2061#if !SLIMPELLER
2062 if (SAFE_ACCESS(args, persistent_cache_path, nullptr) != nullptr) {
2063 std::string persistent_cache_path =
2064 SAFE_ACCESS(args, persistent_cache_path, nullptr);
2066 }
2067
2068 if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) {
2070 }
2071#endif // !SLIMPELLER
2072
2073 fml::CommandLine command_line;
2074 if (SAFE_ACCESS(args, command_line_argc, 0) != 0 &&
2075 SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) {
2076 command_line = fml::CommandLineFromArgcArgv(
2077 SAFE_ACCESS(args, command_line_argc, 0),
2078 SAFE_ACCESS(args, command_line_argv, nullptr));
2079 }
2080
2081 flutter::Settings settings = flutter::SettingsFromCommandLine(command_line);
2082
2083 if (SAFE_ACCESS(args, aot_data, nullptr)) {
2084 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) ||
2085 SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) ||
2086 SAFE_ACCESS(args, isolate_snapshot_data, nullptr) ||
2087 SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr)) {
2088 return LOG_EMBEDDER_ERROR(
2090 "Multiple AOT sources specified. Embedders should provide either "
2091 "*_snapshot_* buffers or aot_data, not both.");
2092 }
2093 }
2094
2097 } else {
2099 }
2100
2101 settings.icu_data_path = icu_data_path;
2102 settings.assets_path = args->assets_path;
2103 settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false);
2104 settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1);
2105 settings.enable_wide_gamut = SAFE_ACCESS(args, enable_wide_gamut, false);
2106
2108 // Verify the assets path contains Dart 2 kernel assets.
2109 const std::string kApplicationKernelSnapshotFileName = "kernel_blob.bin";
2110 std::string application_kernel_path = fml::paths::JoinPaths(
2112 if (!fml::IsFile(application_kernel_path)) {
2113 return LOG_EMBEDDER_ERROR(
2115 "Not running in AOT mode but could not resolve the kernel binary.");
2116 }
2118 }
2119
2120 if (SAFE_ACCESS(args, root_isolate_create_callback, nullptr) != nullptr) {
2122 SAFE_ACCESS(args, root_isolate_create_callback, nullptr);
2124 [callback, user_data](const auto& isolate) { callback(user_data); };
2125 }
2126
2127 // Wire up callback for engine and print logging.
2128 if (SAFE_ACCESS(args, log_message_callback, nullptr) != nullptr) {
2130 SAFE_ACCESS(args, log_message_callback, nullptr);
2132 const std::string& tag,
2133 const std::string& message) {
2134 callback(tag.c_str(), message.c_str(), user_data);
2135 };
2136 } else {
2137 settings.log_message_callback = [](const std::string& tag,
2138 const std::string& message) {
2139 // Fall back to logging to stdout if unspecified.
2140 if (tag.empty()) {
2141 std::cout << tag << ": ";
2142 }
2143 std::cout << message << std::endl;
2144 };
2145 }
2146
2147 if (SAFE_ACCESS(args, log_tag, nullptr) != nullptr) {
2148 settings.log_tag = SAFE_ACCESS(args, log_tag, nullptr);
2149 }
2150
2151 bool has_update_semantics_2_callback =
2152 SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr;
2153 bool has_update_semantics_callback =
2154 SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr;
2155 bool has_legacy_update_semantics_callback =
2156 SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr ||
2157 SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
2158 nullptr;
2159
2160 int semantic_callback_count = (has_update_semantics_2_callback ? 1 : 0) +
2161 (has_update_semantics_callback ? 1 : 0) +
2162 (has_legacy_update_semantics_callback ? 1 : 0);
2163
2164 if (semantic_callback_count > 1) {
2165 return LOG_EMBEDDER_ERROR(
2167 "Multiple semantics update callbacks provided. "
2168 "Embedders should provide either `update_semantics_callback2`, "
2169 "`update_semantics_callback`, or both "
2170 "`update_semantics_node_callback` and "
2171 "`update_semantics_custom_action_callback`.");
2172 }
2173
2175 update_semantics_callback =
2177
2179 platform_message_response_callback = nullptr;
2180 if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
2181 platform_message_response_callback =
2182 [ptr = args->platform_message_callback,
2183 user_data](std::unique_ptr<flutter::PlatformMessage> message) {
2184 auto handle = new FlutterPlatformMessageResponseHandle();
2185 const FlutterPlatformMessage incoming_message = {
2186 sizeof(FlutterPlatformMessage), // struct_size
2187 message->channel().c_str(), // channel
2188 message->data().GetMapping(), // message
2189 message->data().GetSize(), // message_size
2190 handle, // response_handle
2191 };
2192 handle->message = std::move(message);
2193 return ptr(&incoming_message, user_data);
2194 };
2195 }
2196
2197 flutter::VsyncWaiterEmbedder::VsyncCallback vsync_callback = nullptr;
2198 if (SAFE_ACCESS(args, vsync_callback, nullptr) != nullptr) {
2199 vsync_callback = [ptr = args->vsync_callback, user_data](intptr_t baton) {
2200 return ptr(user_data, baton);
2201 };
2202 }
2203
2205 compute_platform_resolved_locale_callback = nullptr;
2206 if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
2207 nullptr) {
2208 compute_platform_resolved_locale_callback =
2209 [ptr = args->compute_platform_resolved_locale_callback](
2210 const std::vector<std::string>& supported_locales_data) {
2211 const size_t number_of_strings_per_locale = 3;
2212 size_t locale_count =
2213 supported_locales_data.size() / number_of_strings_per_locale;
2214 std::vector<FlutterLocale> supported_locales;
2215 std::vector<const FlutterLocale*> supported_locales_ptr;
2216 for (size_t i = 0; i < locale_count; ++i) {
2217 supported_locales.push_back(
2218 {.struct_size = sizeof(FlutterLocale),
2219 .language_code =
2220 supported_locales_data[i * number_of_strings_per_locale +
2221 0]
2222 .c_str(),
2223 .country_code =
2224 supported_locales_data[i * number_of_strings_per_locale +
2225 1]
2226 .c_str(),
2227 .script_code =
2228 supported_locales_data[i * number_of_strings_per_locale +
2229 2]
2230 .c_str(),
2231 .variant_code = nullptr});
2232 supported_locales_ptr.push_back(&supported_locales[i]);
2233 }
2234
2235 const FlutterLocale* result =
2236 ptr(supported_locales_ptr.data(), locale_count);
2237
2238 std::unique_ptr<std::vector<std::string>> out =
2239 std::make_unique<std::vector<std::string>>();
2240 if (result) {
2241 std::string language_code(SAFE_ACCESS(result, language_code, ""));
2242 if (language_code != "") {
2243 out->push_back(language_code);
2244 out->emplace_back(SAFE_ACCESS(result, country_code, ""));
2245 out->emplace_back(SAFE_ACCESS(result, script_code, ""));
2246 }
2247 }
2248 return out;
2249 };
2250 }
2251
2253 on_pre_engine_restart_callback = nullptr;
2254 if (SAFE_ACCESS(args, on_pre_engine_restart_callback, nullptr) != nullptr) {
2255 on_pre_engine_restart_callback = [ptr =
2256 args->on_pre_engine_restart_callback,
2257 user_data]() { return ptr(user_data); };
2258 }
2259
2261 nullptr;
2262 if (SAFE_ACCESS(args, channel_update_callback, nullptr) != nullptr) {
2263 channel_update_callback = [ptr = args->channel_update_callback, user_data](
2264 const std::string& name, bool listening) {
2265 FlutterChannelUpdate update{sizeof(FlutterChannelUpdate), name.c_str(),
2266 listening};
2267 ptr(&update, user_data);
2268 };
2269 }
2270
2272 view_focus_change_request_callback = nullptr;
2273 if (SAFE_ACCESS(args, view_focus_change_request_callback, nullptr) !=
2274 nullptr) {
2275 view_focus_change_request_callback =
2276 [ptr = args->view_focus_change_request_callback,
2278 FlutterViewFocusChangeRequest embedder_request{
2280 .view_id = request.view_id(),
2281 .state = static_cast<FlutterViewFocusState>(request.state()),
2282 .direction =
2283 static_cast<FlutterViewFocusDirection>(request.direction()),
2284 };
2285 ptr(&embedder_request, user_data);
2286 };
2287 }
2288
2289 auto external_view_embedder_result = InferExternalViewEmbedderFromArgs(
2290 SAFE_ACCESS(args, compositor, nullptr), settings.enable_impeller);
2291 if (!external_view_embedder_result.ok()) {
2292 FML_LOG(ERROR) << external_view_embedder_result.status().message();
2294 "Compositor arguments were invalid.");
2295 }
2296
2298 {
2299 update_semantics_callback, //
2300 platform_message_response_callback, //
2301 vsync_callback, //
2302 compute_platform_resolved_locale_callback, //
2303 on_pre_engine_restart_callback, //
2304 channel_update_callback, //
2305 view_focus_change_request_callback, //
2306 };
2307
2308 auto on_create_platform_view = InferPlatformViewCreationCallback(
2309 config, user_data, platform_dispatch_table,
2310 std::move(external_view_embedder_result.value()),
2311 settings.enable_impeller);
2312
2313 if (!on_create_platform_view) {
2314 return LOG_EMBEDDER_ERROR(
2316 "Could not infer platform view creation callback.");
2317 }
2318
2320 [](flutter::Shell& shell) {
2321 return std::make_unique<flutter::Rasterizer>(shell);
2322 };
2323
2324 using ExternalTextureResolver = flutter::EmbedderExternalTextureResolver;
2325 std::unique_ptr<ExternalTextureResolver> external_texture_resolver;
2326 external_texture_resolver = std::make_unique<ExternalTextureResolver>();
2327
2328#ifdef SHELL_ENABLE_GL
2330 external_texture_callback;
2331 if (config->type == kOpenGL) {
2332 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
2333 if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
2334 nullptr) != nullptr) {
2335 external_texture_callback =
2336 [ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
2337 int64_t texture_identifier, size_t width,
2338 size_t height) -> std::unique_ptr<FlutterOpenGLTexture> {
2339 std::unique_ptr<FlutterOpenGLTexture> texture =
2340 std::make_unique<FlutterOpenGLTexture>();
2341 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2342 return nullptr;
2343 }
2344 return texture;
2345 };
2346 external_texture_resolver =
2347 std::make_unique<ExternalTextureResolver>(external_texture_callback);
2348 }
2349 }
2350#endif
2351#ifdef SHELL_ENABLE_METAL
2353 external_texture_metal_callback;
2354 if (config->type == kMetal) {
2355 const FlutterMetalRendererConfig* metal_config = &config->metal;
2356 if (SAFE_ACCESS(metal_config, external_texture_frame_callback, nullptr)) {
2357 external_texture_metal_callback =
2358 [ptr = metal_config->external_texture_frame_callback, user_data](
2359 int64_t texture_identifier, size_t width,
2360 size_t height) -> std::unique_ptr<FlutterMetalExternalTexture> {
2361 std::unique_ptr<FlutterMetalExternalTexture> texture =
2362 std::make_unique<FlutterMetalExternalTexture>();
2363 texture->struct_size = sizeof(FlutterMetalExternalTexture);
2364 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2365 return nullptr;
2366 }
2367 return texture;
2368 };
2369 external_texture_resolver = std::make_unique<ExternalTextureResolver>(
2370 external_texture_metal_callback);
2371 }
2372 }
2373#endif
2374 auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr);
2375 auto thread_config_callback = [&custom_task_runners](
2376 const fml::Thread::ThreadConfig& config) {
2378 if (!custom_task_runners || !custom_task_runners->thread_priority_setter) {
2379 return;
2380 }
2382 switch (config.priority) {
2385 break;
2388 break;
2391 break;
2394 break;
2395 }
2396 custom_task_runners->thread_priority_setter(priority);
2397 };
2398 auto thread_host =
2400 custom_task_runners, thread_config_callback);
2401
2402 if (!thread_host || !thread_host->IsValid()) {
2404 "Could not set up or infer thread configuration "
2405 "to run the Flutter engine on.");
2406 }
2407
2408 auto task_runners = thread_host->GetTaskRunners();
2409
2410 if (!task_runners.IsValid()) {
2412 "Task runner configuration was invalid.");
2413 }
2414
2415 // Embedder supplied UI task runner runner does not have a message loop.
2416 bool has_ui_thread_message_loop =
2417 task_runners.GetUITaskRunner()->GetTaskQueueId().is_valid();
2418 // Message loop observers are used to flush the microtask queue.
2419 // If there is no message loop the queue is flushed from
2420 // EmbedderEngine::RunTask.
2421 settings.task_observer_add = [has_ui_thread_message_loop](
2422 intptr_t key, const fml::closure& callback) {
2423 if (has_ui_thread_message_loop) {
2425 }
2427 };
2428 settings.task_observer_remove = [has_ui_thread_message_loop](
2429 fml::TaskQueueId queue_id, intptr_t key) {
2430 if (has_ui_thread_message_loop) {
2432 }
2433 };
2434
2435 auto run_configuration =
2437
2438 if (SAFE_ACCESS(args, custom_dart_entrypoint, nullptr) != nullptr) {
2439 auto dart_entrypoint = std::string{args->custom_dart_entrypoint};
2440 if (!dart_entrypoint.empty()) {
2441 run_configuration.SetEntrypoint(std::move(dart_entrypoint));
2442 }
2443 }
2444
2445 if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
2446 if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
2448 "Could not determine Dart entrypoint arguments "
2449 "as dart_entrypoint_argc "
2450 "was set, but dart_entrypoint_argv was null.");
2451 }
2452 std::vector<std::string> arguments(args->dart_entrypoint_argc);
2453 for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
2454 arguments[i] = std::string{args->dart_entrypoint_argv[i]};
2455 }
2456 run_configuration.SetEntrypointArgs(std::move(arguments));
2457 }
2458
2459 if (SAFE_ACCESS(args, engine_id, 0) != 0) {
2460 run_configuration.SetEngineId(args->engine_id);
2461 }
2462
2463 if (!run_configuration.IsValid()) {
2464 return LOG_EMBEDDER_ERROR(
2466 "Could not infer the Flutter project to run from given arguments.");
2467 }
2468
2469 // Create the engine but don't launch the shell or run the root isolate.
2470 auto embedder_engine = std::make_unique<flutter::EmbedderEngine>(
2471 std::move(thread_host), //
2472 std::move(task_runners), //
2473 std::move(settings), //
2474 std::move(run_configuration), //
2475 on_create_platform_view, //
2476 on_create_rasterizer, //
2477 std::move(external_texture_resolver) //
2478 );
2479
2480 // Release the ownership of the embedder engine to the caller.
2481 *engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(
2482 embedder_engine.release());
2483 return kSuccess;
2484}
2485
2488 if (!engine) {
2489 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2490 }
2491
2492 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2493
2494 // The engine must not already be running. Initialize may only be called
2495 // once on an engine instance.
2496 if (embedder_engine->IsValid()) {
2497 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2498 }
2499
2500 // Step 1: Launch the shell.
2501 if (!embedder_engine->LaunchShell()) {
2503 "Could not launch the engine using supplied "
2504 "initialization arguments.");
2505 }
2506
2507 // Step 2: Tell the platform view to initialize itself.
2508 if (!embedder_engine->NotifyCreated()) {
2510 "Could not create platform view components.");
2511 }
2512
2513 // Step 3: Launch the root isolate.
2514 if (!embedder_engine->RunRootIsolate()) {
2515 return LOG_EMBEDDER_ERROR(
2517 "Could not run the root isolate of the Flutter application using the "
2518 "project arguments specified.");
2519 }
2520
2521 return kSuccess;
2522}
2523
2526 engine,
2527 const FlutterAddViewInfo* info) {
2528 if (!engine) {
2529 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2530 }
2531 if (!info || !info->view_metrics || !info->add_view_callback) {
2533 "Add view info handle was invalid.");
2534 }
2535
2538 return LOG_EMBEDDER_ERROR(
2540 "Add view info was invalid. The implicit view cannot be added.");
2541 }
2543 view_id) {
2546 "Add view info was invalid. The info and "
2547 "window metric view IDs must match.");
2548 }
2549 }
2550
2551 // TODO(loicsharma): Return an error if the engine was initialized with
2552 // callbacks that are incompatible with multiple views.
2553 // https://github.com/flutter/flutter/issues/144806
2554
2555 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2557
2558 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2559 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2560 }
2561
2562 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2563
2564 // The engine must be running to add a view.
2565 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2566 if (!embedder_engine->IsValid()) {
2567 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2568 }
2569
2571 [c_callback = info->add_view_callback,
2572 user_data = info->user_data](bool added) {
2573 FlutterAddViewResult result = {};
2574 result.struct_size = sizeof(FlutterAddViewResult);
2575 result.added = added;
2576 result.user_data = user_data;
2577 c_callback(&result);
2578 };
2579
2580 embedder_engine->GetShell().GetPlatformView()->AddView(view_id, metrics,
2581 callback);
2582 return kSuccess;
2583}
2584
2587 engine,
2588 const FlutterRemoveViewInfo* info) {
2589 if (!engine) {
2590 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2591 }
2592 if (!info || !info->remove_view_callback) {
2594 "Remove view info handle was invalid.");
2595 }
2596
2597 if (info->view_id == kFlutterImplicitViewId) {
2598 return LOG_EMBEDDER_ERROR(
2600 "Remove view info was invalid. The implicit view cannot be removed.");
2601 }
2602
2603 // TODO(loicsharma): Return an error if the engine was initialized with
2604 // callbacks that are incompatible with multiple views.
2605 // https://github.com/flutter/flutter/issues/144806
2606
2607 // The engine must be running to remove a view.
2608 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2609 if (!embedder_engine->IsValid()) {
2610 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2611 }
2612
2614 [c_callback = info->remove_view_callback,
2615 user_data = info->user_data](bool removed) {
2616 FlutterRemoveViewResult result = {};
2617 result.struct_size = sizeof(FlutterRemoveViewResult);
2618 result.removed = removed;
2619 result.user_data = user_data;
2620 c_callback(&result);
2621 };
2622
2623 embedder_engine->GetShell().GetPlatformView()->RemoveView(info->view_id,
2624 callback);
2625 return kSuccess;
2626}
2627
2630 const FlutterViewFocusEvent* event) {
2631 if (!engine) {
2632 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2633 }
2634 if (!event) {
2636 "View focus event must not be null.");
2637 }
2638 // The engine must be running to focus a view.
2639 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2640 if (!embedder_engine->IsValid()) {
2641 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2642 }
2643
2644 if (!STRUCT_HAS_MEMBER(event, direction)) {
2646 "The event struct has invalid size.");
2647 }
2648
2649 flutter::ViewFocusEvent flutter_event(
2650 event->view_id, //
2651 static_cast<flutter::ViewFocusState>(event->state),
2652 static_cast<flutter::ViewFocusDirection>(event->direction));
2653
2654 embedder_engine->GetShell().GetPlatformView()->SendViewFocusEvent(
2655 flutter_event);
2656
2657 return kSuccess;
2658}
2659
2662 engine) {
2663 if (engine == nullptr) {
2664 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2665 }
2666
2667 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2668 embedder_engine->NotifyDestroyed();
2669 embedder_engine->CollectShell();
2670 embedder_engine->CollectThreadHost();
2671 return kSuccess;
2672}
2673
2675 engine) {
2676 auto result = FlutterEngineDeinitialize(engine);
2677 if (result != kSuccess) {
2678 return result;
2679 }
2680 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2681 delete embedder_engine;
2682 return kSuccess;
2683}
2684
2687 const FlutterWindowMetricsEvent* flutter_metrics) {
2688 if (engine == nullptr || flutter_metrics == nullptr) {
2689 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2690 }
2692 SAFE_ACCESS(flutter_metrics, view_id, kFlutterImplicitViewId);
2693
2694 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2695 MakeViewportMetricsFromWindowMetrics(flutter_metrics);
2696 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2697 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2698 }
2699
2700 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2701
2702 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
2703 view_id, metrics)
2704 ? kSuccess
2706 "Viewport metrics were invalid.");
2707}
2708
2709// Returns the flutter::PointerData::Change for the given FlutterPointerPhase.
2736
2737// Returns the flutter::PointerData::DeviceKind for the given
2738// FlutterPointerDeviceKind.
2753
2754// Returns the flutter::PointerData::SignalKind for the given
2755// FlutterPointerSignaKind.
2770
2771// Returns the buttons to synthesize for a PointerData from a
2772// FlutterPointerEvent with no type or buttons set.
2775 switch (change) {
2778 // These kinds of change must have a non-zero `buttons`, otherwise
2779 // gesture recognizers will ignore these events.
2789 return 0;
2790 }
2791 return 0;
2792}
2793
2796 const FlutterPointerEvent* pointers,
2797 size_t events_count) {
2798 if (engine == nullptr) {
2799 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2800 }
2801
2802 if (pointers == nullptr || events_count == 0) {
2803 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid pointer events.");
2804 }
2805
2806 auto packet = std::make_unique<flutter::PointerDataPacket>(events_count);
2807
2808 const FlutterPointerEvent* current = pointers;
2809
2810 for (size_t i = 0; i < events_count; ++i) {
2811 flutter::PointerData pointer_data;
2812 pointer_data.Clear();
2813 // this is currely in use only on android embedding.
2814 pointer_data.embedder_id = 0;
2815 pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
2816 pointer_data.change = ToPointerDataChange(
2817 SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
2818 pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
2819 pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
2820 // Delta will be generated in pointer_data_packet_converter.cc.
2821 pointer_data.physical_delta_x = 0.0;
2822 pointer_data.physical_delta_y = 0.0;
2823 pointer_data.device = SAFE_ACCESS(current, device, 0);
2824 // Pointer identifier will be generated in
2825 // pointer_data_packet_converter.cc.
2826 pointer_data.pointer_identifier = 0;
2827 pointer_data.signal_kind = ToPointerDataSignalKind(
2828 SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
2829 pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
2830 pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
2831 FlutterPointerDeviceKind device_kind =
2832 SAFE_ACCESS(current, device_kind, kFlutterPointerDeviceKindMouse);
2833 // For backwards compatibility with embedders written before the device
2834 // kind and buttons were exposed, if the device kind is not set treat it
2835 // as a mouse, with a synthesized primary button state based on the phase.
2836 if (device_kind == 0) {
2838 pointer_data.buttons =
2840
2841 } else {
2842 pointer_data.kind = ToPointerDataKind(device_kind);
2843 if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
2844 // For touch events, set the button internally rather than requiring
2845 // it at the API level, since it's a confusing construction to expose.
2846 if (pointer_data.change == flutter::PointerData::Change::kDown ||
2849 }
2850 } else {
2851 // Buttons use the same mask values, so pass them through directly.
2852 pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
2853 }
2854 }
2855 pointer_data.pan_x = SAFE_ACCESS(current, pan_x, 0.0);
2856 pointer_data.pan_y = SAFE_ACCESS(current, pan_y, 0.0);
2857 // Delta will be generated in pointer_data_packet_converter.cc.
2858 pointer_data.pan_delta_x = 0.0;
2859 pointer_data.pan_delta_y = 0.0;
2860 pointer_data.scale = SAFE_ACCESS(current, scale, 0.0);
2861 pointer_data.rotation = SAFE_ACCESS(current, rotation, 0.0);
2862 pointer_data.view_id =
2864 packet->SetPointerData(i, pointer_data);
2865 current = reinterpret_cast<const FlutterPointerEvent*>(
2866 reinterpret_cast<const uint8_t*>(current) + current->struct_size);
2867 }
2868
2869 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2870 ->DispatchPointerDataPacket(std::move(packet))
2871 ? kSuccess
2873 "Could not dispatch pointer events to the "
2874 "running Flutter application.");
2875}
2876
2878 FlutterKeyEventType event_kind) {
2879 switch (event_kind) {
2886 }
2888}
2889
2906
2907// Send a platform message to the framework.
2908//
2909// The `data_callback` will be invoked with `user_data`, and must not be empty.
2912 const char* channel,
2913 const uint8_t* data,
2914 size_t size,
2915 FlutterDataCallback data_callback,
2916 void* user_data) {
2917 FlutterEngineResult result;
2918
2919 FlutterPlatformMessageResponseHandle* response_handle;
2921 engine, data_callback, user_data, &response_handle);
2922 if (result != kSuccess) {
2923 return result;
2924 }
2925
2927 sizeof(FlutterPlatformMessage), // struct_size
2928 channel, // channel
2929 data, // message
2930 size, // message_size
2931 response_handle, // response_handle
2932 };
2933
2935 // Whether `SendPlatformMessage` succeeds or not, the response handle must be
2936 // released.
2937 FlutterEngineResult release_result =
2939 if (result != kSuccess) {
2940 return result;
2941 }
2942
2943 return release_result;
2944}
2945
2947 engine,
2948 const FlutterKeyEvent* event,
2950 void* user_data) {
2951 if (engine == nullptr) {
2952 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2953 }
2954
2955 if (event == nullptr) {
2956 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid key event.");
2957 }
2958
2959 const char* character = SAFE_ACCESS(event, character, nullptr);
2960
2961 flutter::KeyData key_data;
2962 key_data.Clear();
2963 key_data.timestamp = static_cast<uint64_t>(SAFE_ACCESS(event, timestamp, 0));
2964 key_data.type = MapKeyEventType(
2966 key_data.physical = SAFE_ACCESS(event, physical, 0);
2967 key_data.logical = SAFE_ACCESS(event, logical, 0);
2968 key_data.synthesized = SAFE_ACCESS(event, synthesized, false);
2970 event, device_type,
2972
2973 auto packet = std::make_unique<flutter::KeyDataPacket>(key_data, character);
2974
2975 struct MessageData {
2977 void* user_data;
2978 };
2979
2980 MessageData* message_data =
2981 new MessageData{.callback = callback, .user_data = user_data};
2982
2983 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
2985 engine, kFlutterKeyDataChannel, packet->data().data(),
2986 packet->data().size(),
2987 [](const uint8_t* data, size_t size, void* user_data) {
2988 auto message_data = std::unique_ptr<MessageData>(
2989 reinterpret_cast<MessageData*>(user_data));
2990 if (message_data->callback == nullptr) {
2991 return;
2992 }
2993 bool handled = false;
2994 if (size == 1) {
2995 handled = *data != 0;
2996 }
2997 message_data->callback(handled, message_data->user_data);
2998 },
2999 message_data);
3000}
3001
3004 const FlutterPlatformMessage* flutter_message) {
3005 if (engine == nullptr) {
3006 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3007 }
3008
3009 if (flutter_message == nullptr) {
3010 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid message argument.");
3011 }
3012
3013 if (SAFE_ACCESS(flutter_message, channel, nullptr) == nullptr) {
3014 return LOG_EMBEDDER_ERROR(
3015 kInvalidArguments, "Message argument did not specify a valid channel.");
3016 }
3017
3018 size_t message_size = SAFE_ACCESS(flutter_message, message_size, 0);
3019 const uint8_t* message_data = SAFE_ACCESS(flutter_message, message, nullptr);
3020
3021 if (message_size != 0 && message_data == nullptr) {
3022 return LOG_EMBEDDER_ERROR(
3024 "Message size was non-zero but the message data was nullptr.");
3025 }
3026
3027 const FlutterPlatformMessageResponseHandle* response_handle =
3028 SAFE_ACCESS(flutter_message, response_handle, nullptr);
3029
3031 if (response_handle && response_handle->message) {
3032 response = response_handle->message->response();
3033 }
3034
3035 std::unique_ptr<flutter::PlatformMessage> message;
3036 if (message_size == 0) {
3037 message = std::make_unique<flutter::PlatformMessage>(
3038 flutter_message->channel, response);
3039 } else {
3040 message = std::make_unique<flutter::PlatformMessage>(
3041 flutter_message->channel,
3042 fml::MallocMapping::Copy(message_data, message_size), response);
3043 }
3044
3045 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3046 ->SendPlatformMessage(std::move(message))
3047 ? kSuccess
3049 "Could not send a message to the running "
3050 "Flutter application.");
3051}
3052
3055 FlutterDataCallback data_callback,
3056 void* user_data,
3057 FlutterPlatformMessageResponseHandle** response_out) {
3058 if (engine == nullptr) {
3059 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3060 }
3061
3062 if (data_callback == nullptr || response_out == nullptr) {
3063 return LOG_EMBEDDER_ERROR(
3064 kInvalidArguments, "Data callback or the response handle was invalid.");
3065 }
3066
3068 [user_data, data_callback](const uint8_t* data, size_t size) {
3069 data_callback(data, size, user_data);
3070 };
3071
3072 auto platform_task_runner = reinterpret_cast<flutter::EmbedderEngine*>(engine)
3073 ->GetTaskRunners()
3074 .GetPlatformTaskRunner();
3075
3076 auto handle = new FlutterPlatformMessageResponseHandle();
3077
3078 handle->message = std::make_unique<flutter::PlatformMessage>(
3079 "", // The channel is empty and unused as the response handle is going
3080 // to referenced directly in the |FlutterEngineSendPlatformMessage|
3081 // with the container message discarded.
3082 fml::MakeRefCounted<flutter::EmbedderPlatformMessageResponse>(
3083 std::move(platform_task_runner), response_callback));
3084 *response_out = handle;
3085 return kSuccess;
3086}
3087
3091 if (engine == nullptr) {
3092 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3093 }
3094
3095 if (response == nullptr) {
3096 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid response handle.");
3097 }
3098 delete response;
3099 return kSuccess;
3100}
3101
3102// Note: This can execute on any thread.
3106 const uint8_t* data,
3107 size_t data_length) {
3108 if (data_length != 0 && data == nullptr) {
3109 return LOG_EMBEDDER_ERROR(
3111 "Data size was non zero but the pointer to the data was null.");
3112 }
3113
3114 auto response = handle->message->response();
3115
3116 if (response) {
3117 if (data_length == 0) {
3118 response->CompleteEmpty();
3119 } else {
3120 response->Complete(std::make_unique<fml::DataMapping>(
3121 std::vector<uint8_t>({data, data + data_length})));
3122 }
3123 }
3124
3125 delete handle;
3126
3127 return kSuccess;
3128}
3129
3134
3137 int64_t texture_identifier) {
3138 if (engine == nullptr) {
3139 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3140 }
3141
3142 if (texture_identifier == 0) {
3144 "Texture identifier was invalid.");
3145 }
3146 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->RegisterTexture(
3147 texture_identifier)) {
3149 "Could not register the specified texture.");
3150 }
3151 return kSuccess;
3152}
3153
3156 int64_t texture_identifier) {
3157 if (engine == nullptr) {
3158 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3159 }
3160
3161 if (texture_identifier == 0) {
3163 "Texture identifier was invalid.");
3164 }
3165
3166 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->UnregisterTexture(
3167 texture_identifier)) {
3169 "Could not un-register the specified texture.");
3170 }
3171
3172 return kSuccess;
3173}
3174
3177 int64_t texture_identifier) {
3178 if (engine == nullptr) {
3179 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3180 }
3181 if (texture_identifier == 0) {
3182 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid texture identifier.");
3183 }
3184 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3185 ->MarkTextureFrameAvailable(texture_identifier)) {
3186 return LOG_EMBEDDER_ERROR(
3188 "Could not mark the texture frame as being available.");
3189 }
3190 return kSuccess;
3191}
3192
3195 bool enabled) {
3196 if (engine == nullptr) {
3197 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3198 }
3199 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetSemanticsEnabled(
3200 enabled)) {
3202 "Could not update semantics state.");
3203 }
3204 return kSuccess;
3205}
3206
3210 if (engine == nullptr) {
3211 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3212 }
3213 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3214 ->SetAccessibilityFeatures(flags)) {
3216 "Could not update accessibility features.");
3217 }
3218 return kSuccess;
3219}
3220
3223 uint64_t node_id,
3225 const uint8_t* data,
3226 size_t data_length) {
3230 .node_id = node_id,
3231 .action = action,
3232 .data = data,
3233 .data_length = data_length};
3235}
3236
3239 const FlutterSendSemanticsActionInfo* info) {
3240 if (engine == nullptr) {
3241 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3242 }
3243 auto engine_action = static_cast<flutter::SemanticsAction>(info->action);
3244 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3246 info->view_id, info->node_id, engine_action,
3247 fml::MallocMapping::Copy(info->data, info->data_length))) {
3249 "Could not dispatch semantics action.");
3250 }
3251 return kSuccess;
3252}
3253
3255 engine,
3256 intptr_t baton,
3257 uint64_t frame_start_time_nanos,
3258 uint64_t frame_target_time_nanos) {
3259 if (engine == nullptr) {
3260 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3261 }
3262
3263 TRACE_EVENT0("flutter", "FlutterEngineOnVsync");
3264
3265 auto start_time = fml::TimePoint::FromEpochDelta(
3266 fml::TimeDelta::FromNanoseconds(frame_start_time_nanos));
3267
3268 auto target_time = fml::TimePoint::FromEpochDelta(
3269 fml::TimeDelta::FromNanoseconds(frame_target_time_nanos));
3270
3271 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->OnVsyncEvent(
3272 baton, start_time, target_time)) {
3273 return LOG_EMBEDDER_ERROR(
3275 "Could not notify the running engine instance of a Vsync event.");
3276 }
3277
3278 return kSuccess;
3279}
3280
3283 if (engine == nullptr) {
3284 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3285 }
3286
3287 TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");
3288
3289 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3290 ->ReloadSystemFonts()) {
3292 "Could not reload system fonts.");
3293 }
3294
3295 return kSuccess;
3296}
3297
3299 fml::tracing::TraceEvent0("flutter", name, /*flow_id_count=*/0,
3300 /*flow_ids=*/nullptr);
3301}
3302
3306
3308 fml::tracing::TraceEventInstant0("flutter", name, /*flow_id_count=*/0,
3309 /*flow_ids=*/nullptr);
3310}
3311
3315 void* baton) {
3316 if (engine == nullptr) {
3317 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3318 }
3319
3320 if (callback == nullptr) {
3322 "Render thread callback was null.");
3323 }
3324
3325 auto task = [callback, baton]() { callback(baton); };
3326
3327 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3328 ->PostRenderThreadTask(task)
3329 ? kSuccess
3331 "Could not post the render thread task.");
3332}
3333
3337
3339 engine,
3340 const FlutterTask* task) {
3341 if (engine == nullptr) {
3342 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3343 }
3344
3346 reinterpret_cast<intptr_t>(task->runner))) {
3347 // This task came too late, the embedder has already been destroyed.
3348 // This is not an error, just ignore the task.
3349 return kSuccess;
3350 }
3351
3352 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->RunTask(task)
3353 ? kSuccess
3355 "Could not run the specified task.");
3356}
3357
3359 engine,
3360 const rapidjson::Document& document,
3361 const std::string& channel_name) {
3362 if (channel_name.empty()) {
3363 return false;
3364 }
3365
3366 rapidjson::StringBuffer buffer;
3367 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
3368
3369 if (!document.Accept(writer)) {
3370 return false;
3371 }
3372
3373 const char* message = buffer.GetString();
3374
3375 if (message == nullptr || buffer.GetSize() == 0) {
3376 return false;
3377 }
3378
3379 auto platform_message = std::make_unique<flutter::PlatformMessage>(
3380 channel_name.c_str(), // channel
3382 buffer.GetSize()), // message
3383 nullptr // response
3384 );
3385
3386 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3387 ->SendPlatformMessage(std::move(platform_message));
3388}
3389
3391 engine,
3392 const FlutterLocale** locales,
3393 size_t locales_count) {
3394 if (engine == nullptr) {
3395 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3396 }
3397
3398 if (locales_count == 0) {
3399 return kSuccess;
3400 }
3401
3402 if (locales == nullptr) {
3403 return LOG_EMBEDDER_ERROR(kInvalidArguments, "No locales were specified.");
3404 }
3405
3406 rapidjson::Document document;
3407 auto& allocator = document.GetAllocator();
3408
3409 document.SetObject();
3410 document.AddMember("method", "setLocale", allocator);
3411
3412 rapidjson::Value args(rapidjson::kArrayType);
3413 args.Reserve(locales_count * 4, allocator);
3414 for (size_t i = 0; i < locales_count; ++i) {
3415 const FlutterLocale* locale = locales[i];
3416 const char* language_code_str = SAFE_ACCESS(locale, language_code, nullptr);
3417 if (language_code_str == nullptr || ::strlen(language_code_str) == 0) {
3418 return LOG_EMBEDDER_ERROR(
3420 "Language code is required but not present in FlutterLocale.");
3421 }
3422
3423 const char* country_code_str = SAFE_ACCESS(locale, country_code, "");
3424 const char* script_code_str = SAFE_ACCESS(locale, script_code, "");
3425 const char* variant_code_str = SAFE_ACCESS(locale, variant_code, "");
3426
3427 rapidjson::Value language_code, country_code, script_code, variant_code;
3428
3429 language_code.SetString(language_code_str, allocator);
3430 country_code.SetString(country_code_str ? country_code_str : "", allocator);
3431 script_code.SetString(script_code_str ? script_code_str : "", allocator);
3432 variant_code.SetString(variant_code_str ? variant_code_str : "", allocator);
3433
3434 // Required.
3435 args.PushBack(language_code, allocator);
3436 args.PushBack(country_code, allocator);
3437 args.PushBack(script_code, allocator);
3438 args.PushBack(variant_code, allocator);
3439 }
3440 document.AddMember("args", args, allocator);
3441
3442 return DispatchJSONPlatformMessage(engine, document, "flutter/localization")
3443 ? kSuccess
3445 "Could not send message to update locale of "
3446 "a running Flutter application.");
3447}
3448
3452
3456 const FlutterEngineDartObject* object) {
3457 if (engine == nullptr) {
3458 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3459 }
3460
3461 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->IsValid()) {
3462 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine not running.");
3463 }
3464
3465 if (port == ILLEGAL_PORT) {
3467 "Attempted to post to an illegal port.");
3468 }
3469
3470 if (object == nullptr) {
3472 "Invalid Dart object to post.");
3473 }
3474
3475 Dart_CObject dart_object = {};
3476 fml::ScopedCleanupClosure typed_data_finalizer;
3477
3478 switch (object->type) {
3480 dart_object.type = Dart_CObject_kNull;
3481 break;
3483 dart_object.type = Dart_CObject_kBool;
3484 dart_object.value.as_bool = object->bool_value;
3485 break;
3487 dart_object.type = Dart_CObject_kInt32;
3488 dart_object.value.as_int32 = object->int32_value;
3489 break;
3491 dart_object.type = Dart_CObject_kInt64;
3492 dart_object.value.as_int64 = object->int64_value;
3493 break;
3495 dart_object.type = Dart_CObject_kDouble;
3496 dart_object.value.as_double = object->double_value;
3497 break;
3499 if (object->string_value == nullptr) {
3501 "kFlutterEngineDartObjectTypeString must be "
3502 "a null terminated string but was null.");
3503 }
3504 dart_object.type = Dart_CObject_kString;
3505 dart_object.value.as_string = const_cast<char*>(object->string_value);
3506 break;
3508 auto* buffer = SAFE_ACCESS(object->buffer_value, buffer, nullptr);
3509 if (buffer == nullptr) {
3511 "kFlutterEngineDartObjectTypeBuffer must "
3512 "specify a buffer but found nullptr.");
3513 }
3514 auto buffer_size = SAFE_ACCESS(object->buffer_value, buffer_size, 0);
3515 auto callback =
3516 SAFE_ACCESS(object->buffer_value, buffer_collect_callback, nullptr);
3517 auto user_data = SAFE_ACCESS(object->buffer_value, user_data, nullptr);
3518
3519 // The user has provided a callback, let them manage the lifecycle of
3520 // the underlying data. If not, copy it out from the provided buffer.
3521
3522 if (callback == nullptr) {
3523 dart_object.type = Dart_CObject_kTypedData;
3524 dart_object.value.as_typed_data.type = Dart_TypedData_kUint8;
3525 dart_object.value.as_typed_data.length = buffer_size;
3526 dart_object.value.as_typed_data.values = buffer;
3527 } else {
3528 struct ExternalTypedDataPeer {
3529 void* user_data = nullptr;
3530 VoidCallback trampoline = nullptr;
3531 };
3532 auto peer = new ExternalTypedDataPeer();
3533 peer->user_data = user_data;
3534 peer->trampoline = callback;
3535 // This finalizer is set so that in case of failure of the
3536 // Dart_PostCObject below, we collect the peer. The embedder is still
3537 // responsible for collecting the buffer in case of non-kSuccess
3538 // returns from this method. This finalizer must be released in case
3539 // of kSuccess returns from this method.
3540 typed_data_finalizer.SetClosure([peer]() {
3541 // This is the tiny object we use as the peer to the Dart call so
3542 // that we can attach the a trampoline to the embedder supplied
3543 // callback. In case of error, we need to collect this object lest
3544 // we introduce a tiny leak.
3545 delete peer;
3546 });
3547 dart_object.type = Dart_CObject_kExternalTypedData;
3548 dart_object.value.as_external_typed_data.type = Dart_TypedData_kUint8;
3549 dart_object.value.as_external_typed_data.length = buffer_size;
3550 dart_object.value.as_external_typed_data.data = buffer;
3551 dart_object.value.as_external_typed_data.peer = peer;
3552 dart_object.value.as_external_typed_data.callback =
3553 +[](void* unused_isolate_callback_data, void* peer) {
3554 auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
3555 typed_peer->trampoline(typed_peer->user_data);
3556 delete typed_peer;
3557 };
3558 }
3559 } break;
3560 default:
3561 return LOG_EMBEDDER_ERROR(
3563 "Invalid FlutterEngineDartObjectType type specified.");
3564 }
3565
3566 if (!Dart_PostCObject(port, &dart_object)) {
3568 "Could not post the object to the Dart VM.");
3569 }
3570
3571 // On a successful call, the VM takes ownership of and is responsible for
3572 // invoking the finalizer.
3573 typed_data_finalizer.Release();
3574 return kSuccess;
3575}
3576
3578 FLUTTER_API_SYMBOL(FlutterEngine) raw_engine) {
3579 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3580 if (engine == nullptr || !engine->IsValid()) {
3581 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
3582 }
3583
3584 engine->GetShell().NotifyLowMemoryWarning();
3585
3586 rapidjson::Document document;
3587 auto& allocator = document.GetAllocator();
3588
3589 document.SetObject();
3590 document.AddMember("type", "memoryPressure", allocator);
3591
3592 return DispatchJSONPlatformMessage(raw_engine, document, "flutter/system")
3593 ? kSuccess
3596 "Could not dispatch the low memory notification message.");
3597}
3598
3602 void* user_data) {
3603 if (engine == nullptr) {
3604 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3605 }
3606
3607 if (callback == nullptr) {
3609 "Invalid native thread callback.");
3610 }
3611
3612 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3613 ->PostTaskOnEngineManagedNativeThreads(
3616 })
3617 ? kSuccess
3619 "Internal error while attempting to post "
3620 "tasks to all threads.");
3621}
3622
3623namespace {
3624static bool ValidDisplayConfiguration(const FlutterEngineDisplay* displays,
3625 size_t display_count) {
3626 std::set<FlutterEngineDisplayId> display_ids;
3627 for (size_t i = 0; i < display_count; i++) {
3628 if (displays[i].single_display && display_count != 1) {
3629 return false;
3630 }
3631 display_ids.insert(displays[i].display_id);
3632 }
3633
3634 return display_ids.size() == display_count;
3635}
3636} // namespace
3637
3640 const FlutterEngineDisplaysUpdateType update_type,
3641 const FlutterEngineDisplay* embedder_displays,
3642 size_t display_count) {
3643 if (raw_engine == nullptr) {
3644 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3645 }
3646
3647 if (!ValidDisplayConfiguration(embedder_displays, display_count)) {
3648 return LOG_EMBEDDER_ERROR(
3650 "Invalid FlutterEngineDisplay configuration specified.");
3651 }
3652
3653 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3654
3655 switch (update_type) {
3657 std::vector<std::unique_ptr<flutter::Display>> displays;
3658 const auto* display = embedder_displays;
3659 for (size_t i = 0; i < display_count; i++) {
3660 displays.push_back(std::make_unique<flutter::Display>(
3661 SAFE_ACCESS(display, display_id, i), //
3662 SAFE_ACCESS(display, refresh_rate, 0), //
3663 SAFE_ACCESS(display, width, 0), //
3664 SAFE_ACCESS(display, height, 0), //
3665 SAFE_ACCESS(display, device_pixel_ratio, 1)));
3666 display = reinterpret_cast<const FlutterEngineDisplay*>(
3667 reinterpret_cast<const uint8_t*>(display) + display->struct_size);
3668 }
3669 engine->GetShell().OnDisplayUpdates(std::move(displays));
3670 return kSuccess;
3671 }
3672 default:
3673 return LOG_EMBEDDER_ERROR(
3675 "Invalid FlutterEngineDisplaysUpdateType type specified.");
3676 }
3677}
3678
3680 engine) {
3681 if (engine == nullptr) {
3682 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3683 }
3684
3685 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->ScheduleFrame()
3686 ? kSuccess
3688 "Could not schedule frame.");
3689}
3690
3694 void* user_data) {
3695 if (engine == nullptr) {
3696 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3697 }
3698
3699 if (callback == nullptr) {
3701 "Next frame callback was null.");
3702 }
3703
3704 flutter::EmbedderEngine* embedder_engine =
3705 reinterpret_cast<flutter::EmbedderEngine*>(engine);
3706
3707 fml::WeakPtr<flutter::PlatformView> weak_platform_view =
3708 embedder_engine->GetShell().GetPlatformView();
3709
3710 if (!weak_platform_view) {
3712 "Platform view unavailable.");
3713 }
3714
3715 weak_platform_view->SetNextFrameCallback(
3717
3718 return kSuccess;
3719}
3720
3722 FlutterEngineProcTable* table) {
3723 if (!table) {
3724 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null table specified.");
3725 }
3726#define SET_PROC(member, function) \
3727 if (STRUCT_HAS_MEMBER(table, member)) { \
3728 table->member = &function; \
3729 }
3730
3731 SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
3732 SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
3735 SET_PROC(Initialize, FlutterEngineInitialize);
3736 SET_PROC(Deinitialize, FlutterEngineDeinitialize);
3737 SET_PROC(RunInitialized, FlutterEngineRunInitialized);
3738 SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent);
3739 SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent);
3740 SET_PROC(SendKeyEvent, FlutterEngineSendKeyEvent);
3741 SET_PROC(SendPlatformMessage, FlutterEngineSendPlatformMessage);
3742 SET_PROC(PlatformMessageCreateResponseHandle,
3744 SET_PROC(PlatformMessageReleaseResponseHandle,
3746 SET_PROC(SendPlatformMessageResponse,
3748 SET_PROC(RegisterExternalTexture, FlutterEngineRegisterExternalTexture);
3749 SET_PROC(UnregisterExternalTexture, FlutterEngineUnregisterExternalTexture);
3750 SET_PROC(MarkExternalTextureFrameAvailable,
3752 SET_PROC(UpdateSemanticsEnabled, FlutterEngineUpdateSemanticsEnabled);
3753 SET_PROC(UpdateAccessibilityFeatures,
3755 SET_PROC(DispatchSemanticsAction, FlutterEngineDispatchSemanticsAction);
3756 SET_PROC(SendSemanticsAction, FlutterEngineSendSemanticsAction);
3758 SET_PROC(ReloadSystemFonts, FlutterEngineReloadSystemFonts);
3759 SET_PROC(TraceEventDurationBegin, FlutterEngineTraceEventDurationBegin);
3760 SET_PROC(TraceEventDurationEnd, FlutterEngineTraceEventDurationEnd);
3761 SET_PROC(TraceEventInstant, FlutterEngineTraceEventInstant);
3762 SET_PROC(PostRenderThreadTask, FlutterEnginePostRenderThreadTask);
3765 SET_PROC(UpdateLocales, FlutterEngineUpdateLocales);
3766 SET_PROC(RunsAOTCompiledDartCode, FlutterEngineRunsAOTCompiledDartCode);
3767 SET_PROC(PostDartObject, FlutterEnginePostDartObject);
3768 SET_PROC(NotifyLowMemoryWarning, FlutterEngineNotifyLowMemoryWarning);
3769 SET_PROC(PostCallbackOnAllNativeThreads,
3771 SET_PROC(NotifyDisplayUpdate, FlutterEngineNotifyDisplayUpdate);
3772 SET_PROC(ScheduleFrame, FlutterEngineScheduleFrame);
3773 SET_PROC(SetNextFrameCallback, FlutterEngineSetNextFrameCallback);
3775 SET_PROC(RemoveView, FlutterEngineRemoveView);
3776 SET_PROC(SendViewFocusEvent, FlutterEngineSendViewFocusEvent);
3777#undef SET_PROC
3778
3779 return kSuccess;
3780}
GLenum type
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:176
bool DispatchSemanticsAction(int64_t view_id, 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
std::function< SetCurrentResult()> MakeOrClearCurrentCallback
static bool RunnerIsValid(intptr_t runner)
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(int64_t view_id, flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions)> UpdateSemanticsCallback
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(const ViewFocusChangeRequest &)> ViewFocusChangeRequestCallback
std::function< void(bool removed)> RemoveViewCallback
std::function< void(bool added)> AddViewCallback
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...
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
Definition shell.cc:916
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition shell.h:121
fml::WeakPtr< PlatformView > GetPlatformView()
Platform views may only be accessed on the platform task runner.
Definition shell.cc:935
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)
void AddTaskObserver(intptr_t key, const fml::closure &callback)
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
void RunExpiredTasksNow()
static fml::RefPtr< NativeLibrary > CreateForCurrentProcess()
static fml::RefPtr< NativeLibrary > Create(const char *path)
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
static TaskQueueId Invalid()
@ 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
constexpr 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)
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(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, GLuint fbo)
Create a texture by wrapping an external framebuffer object whose lifecycle is owned by the caller.
static std::shared_ptr< TextureGLES > CreatePlaceholder(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc)
Create a "texture" that is never expected to be bound/unbound explicitly or initialized in any way....
int32_t x
#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:3307
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:2910
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:3175
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 embedder via the Flutter...
Definition embedder.cc:3338
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:3254
const int32_t kFlutterSemanticsNodeIdBatchEnd
Definition embedder.cc:107
const int32_t kFlutterSemanticsCustomActionIdBatchEnd
Definition embedder.cc:108
static bool IsMetalRendererConfigValid(const FlutterRendererConfig *config)
Definition embedder.cc:191
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:1995
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:3135
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:3390
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:811
FlutterEngineResult FlutterEngineSendViewFocusEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterViewFocusEvent *event)
Notifies the engine that platform view focus state has changed.
Definition embedder.cc:2628
FlutterEngineResult FlutterEngineGetProcAddresses(FlutterEngineProcTable *table)
Gets the table of engine function pointers.
Definition embedder.cc:3721
static bool DispatchJSONPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const rapidjson::Document &document, const std::string &channel_name)
Definition embedder.cc:3358
FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Schedule a new frame to redraw the content.
Definition embedder.cc:3679
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:3298
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
Definition embedder.cc:2685
flutter::PointerData::SignalKind ToPointerDataSignalKind(FlutterPointerSignalKind kind)
Definition embedder.cc:2756
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:3334
static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig *config)
Definition embedder.cc:158
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:3691
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:3130
#define LOG_EMBEDDER_ERROR(code, reason)
Definition embedder.cc:155
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:3312
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, bool enable_impeller)
Definition embedder.cc:611
static flutter::KeyEventDeviceType MapKeyEventDeviceType(FlutterKeyEventDeviceType event_kind)
Definition embedder.cc:2890
static bool IsRendererValid(const FlutterRendererConfig *config)
Definition embedder.cc:229
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:1139
std::unique_ptr< Dart_LoadedElf, LoadedElfDeleter > UniqueLoadedElf
Definition embedder.cc:1696
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 in the implicit view.
Definition embedder.cc:3221
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:3453
flutter::PointerData::DeviceKind ToPointerDataKind(FlutterPointerDeviceKind device_kind)
Definition embedder.cc:2739
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:2661
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore(GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLTexture *texture)
Definition embedder.cc:846
flutter::PointerData::Change ToPointerDataChange(FlutterPointerPhase phase)
Definition embedder.cc:2710
static constexpr FlutterViewId kFlutterImplicitViewId
Definition embedder.cc:110
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:3599
FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterAddViewInfo *info)
Adds a view.
Definition embedder.cc:2525
static std::unique_ptr< flutter::EmbedderRenderTarget > MakeRenderTargetFromSkSurface(FlutterBackingStore backing_store, sk_sp< SkSurface > skia_surface, fml::closure on_release, flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback on_make_current, flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback on_clear_current)
Definition embedder.cc:1356
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:2011
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:1380
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV3(FlutterUpdateSemanticsCallback2 update_semantics_callback, void *user_data)
Definition embedder.cc:1933
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterAccessibilityFeature flags)
Sets additional accessibility features.
Definition embedder.cc:3207
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:2674
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:3053
FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data)
Collects the AOT data.
Definition embedder.cc:1760
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:3638
FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
Definition embedder.cc:3002
bool FlutterEngineRunsAOTCompiledDartCode(void)
Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading re...
Definition embedder.cc:3449
FlutterEngineResult FlutterEngineReloadSystemFonts(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Reloads the system fonts in engine.
Definition embedder.cc:3281
static flutter::KeyEventType MapKeyEventType(FlutterKeyEventType event_kind)
Definition embedder.cc:2877
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallback(const FlutterProjectArgs *args, void *user_data)
Definition embedder.cc:1949
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:774
static fml::StatusOr< std::unique_ptr< flutter::EmbedderExternalViewEmbedder > > InferExternalViewEmbedderFromArgs(const FlutterCompositor *compositor, bool enable_impeller)
Definition embedder.cc:1539
const intptr_t kPlatformStrongDillSize
#define FLUTTER_EXPORT
Definition embedder.cc:32
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV1(FlutterUpdateSemanticsNodeCallback update_semantics_node_callback, FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback, void *user_data)
Definition embedder.cc:1869
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
Definition embedder.cc:2794
FlutterEngineResult FlutterEngineRunInitialized(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize....
Definition embedder.cc:2486
static bool IsSoftwareRendererConfigValid(const FlutterRendererConfig *config)
Definition embedder.cc:176
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:305
void PopulateJITSnapshotMappingCallbacks(const FlutterProjectArgs *args, flutter::Settings &settings)
Definition embedder.cc:1773
static bool IsVulkanRendererConfigValid(const FlutterRendererConfig *config)
Definition embedder.cc:209
FlutterEngineResult FlutterEngineSendSemanticsAction(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterSendSemanticsActionInfo *info)
Dispatch a semantics action to the specified semantics node within a specific view.
Definition embedder.cc:3237
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:3577
FlutterEngineResult FlutterEngineUnregisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Unregister a previous texture registration.
Definition embedder.cc:3154
FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled)
Enable or disable accessibility semantics.
Definition embedder.cc:3193
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:2946
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:517
static FlutterEngineResult LogEmbedderError(FlutterEngineResult code, const char *reason, const char *code_name, const char *function, const char *file, int line)
Definition embedder.cc:134
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:3303
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:3103
const char * kFlutterKeyDataChannel
Definition embedder.cc:132
FLUTTER_EXPORT FlutterEngineResult FlutterEngineRemoveView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterRemoveViewInfo *info)
Removes a view.
Definition embedder.cc:2586
int64_t PointerDataButtonsForLegacyEvent(flutter::PointerData::Change change)
Definition embedder.cc:2773
void PopulateAOTSnapshotMappingCallbacks(const FlutterProjectArgs *args, flutter::Settings &settings)
Definition embedder.cc:1816
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
Definition embedder.cc:3088
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV2(FlutterUpdateSemanticsCallback update_semantics_callback, void *user_data)
Definition embedder.cc:1918
static std::variant< flutter::ViewportMetrics, std::string > MakeViewportMetricsFromWindowMetrics(const FlutterWindowMetricsEvent *flutter_metrics)
Definition embedder.cc:1616
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:1706
#define FLUTTER_API_SYMBOL(symbol)
Definition embedder.h:67
FlutterKeyEventDeviceType
Definition embedder.h:1382
@ kFlutterKeyEventDeviceTypeKeyboard
Definition embedder.h:1383
@ kFlutterKeyEventDeviceTypeDirectionalPad
Definition embedder.h:1384
@ kFlutterKeyEventDeviceTypeHdmi
Definition embedder.h:1387
@ kFlutterKeyEventDeviceTypeJoystick
Definition embedder.h:1386
@ kFlutterKeyEventDeviceTypeGamepad
Definition embedder.h:1385
void(* FlutterUpdateSemanticsCustomActionCallback)(const FlutterSemanticsCustomAction *, void *)
Definition embedder.h:1846
void(* FlutterUpdateSemanticsCallback)(const FlutterSemanticsUpdate *, void *)
Definition embedder.h:1850
FlutterViewFocusState
Represents the focus state of a given [FlutterView].
Definition embedder.h:1219
@ kFlutterEngineAOTDataSourceTypeElfPath
Definition embedder.h:2458
FlutterViewFocusDirection
Definition embedder.h:1200
struct _FlutterPlatformMessageResponseHandle FlutterPlatformMessageResponseHandle
Definition embedder.h:1461
@ kVulkan
Definition embedder.h:86
@ kOpenGL
Definition embedder.h:80
@ kMetal
Definition embedder.h:85
@ kSoftware
Definition embedder.h:81
void(* FlutterDataCallback)(const uint8_t *, size_t, void *)
Definition embedder.h:1483
FlutterPointerPhase
The phase of the pointer event.
Definition embedder.h:1267
@ kPanZoomUpdate
The pan/zoom updated.
Definition embedder.h:1303
@ kHover
The pointer moved while up.
Definition embedder.h:1299
@ kUp
Definition embedder.h:1275
@ kPanZoomStart
A pan/zoom started on this pointer.
Definition embedder.h:1301
@ kRemove
Definition embedder.h:1297
@ kCancel
Definition embedder.h:1268
@ kDown
Definition embedder.h:1282
@ kAdd
Definition embedder.h:1292
@ kMove
Definition embedder.h:1287
@ kPanZoomEnd
The pan/zoom ended.
Definition embedder.h:1305
FlutterAccessibilityFeature
Definition embedder.h:91
void(* FlutterNativeThreadCallback)(FlutterNativeThreadType type, void *user_data)
Definition embedder.h:2453
@ kFlutterEngineDartObjectTypeString
Definition embedder.h:2366
@ kFlutterEngineDartObjectTypeBool
Definition embedder.h:2362
@ kFlutterEngineDartObjectTypeDouble
Definition embedder.h:2365
@ kFlutterEngineDartObjectTypeInt32
Definition embedder.h:2363
@ kFlutterEngineDartObjectTypeBuffer
Definition embedder.h:2369
@ kFlutterEngineDartObjectTypeInt64
Definition embedder.h:2364
@ kFlutterEngineDartObjectTypeNull
Definition embedder.h:2361
void(* FlutterLogMessageCallback)(const char *, const char *, void *)
Definition embedder.h:2478
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:2434
FlutterPointerSignalKind
The type of a pointer signal.
Definition embedder.h:1329
@ kFlutterPointerSignalKindScale
Definition embedder.h:1333
@ kFlutterPointerSignalKindScrollInertiaCancel
Definition embedder.h:1332
@ kFlutterPointerSignalKindScroll
Definition embedder.h:1331
@ kFlutterPointerSignalKindNone
Definition embedder.h:1330
void(* FlutterUpdateSemanticsNodeCallback)(const FlutterSemanticsNode *, void *)
Definition embedder.h:1842
void(* VoidCallback)(void *)
Definition embedder.h:416
FlutterEngineDisplaysUpdateType
Definition embedder.h:2348
@ kFlutterEngineDisplaysUpdateTypeStartup
Definition embedder.h:2354
FlutterThreadPriority
Valid values for priority of Thread.
Definition embedder.h:376
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
Definition embedder.h:378
@ kDisplay
Suitable for threads which generate data for the display.
Definition embedder.h:382
@ kNormal
Default priority level.
Definition embedder.h:380
@ kRaster
Suitable for thread which raster data.
Definition embedder.h:384
FlutterSemanticsAction
Definition embedder.h:122
void(* FlutterKeyEventCallback)(bool, void *)
Definition embedder.h:1457
int64_t FlutterViewId
Definition embedder.h:393
FlutterKeyEventType
Definition embedder.h:1376
@ kFlutterKeyEventTypeDown
Definition embedder.h:1378
@ kFlutterKeyEventTypeUp
Definition embedder.h:1377
@ kFlutterKeyEventTypeRepeat
Definition embedder.h:1379
void(* FlutterUpdateSemanticsCallback2)(const FlutterSemanticsUpdate2 *, void *)
Definition embedder.h:1854
int64_t FlutterEngineDartPort
Definition embedder.h:2358
@ kFlutterOpenGLTargetTypeFramebuffer
Definition embedder.h:424
@ kFlutterOpenGLTargetTypeSurface
Definition embedder.h:427
@ kFlutterOpenGLTargetTypeTexture
Definition embedder.h:421
@ kFlutterBackingStoreTypeSoftware2
Definition embedder.h:2090
@ kFlutterBackingStoreTypeMetal
Specifies a Metal backing store. This is backed by a Metal texture.
Definition embedder.h:2085
@ kFlutterBackingStoreTypeVulkan
Specifies a Vulkan backing store. This is backed by a Vulkan VkImage.
Definition embedder.h:2087
@ kFlutterBackingStoreTypeSoftware
Specified an software allocation for Flutter to render into using the CPU.
Definition embedder.h:2083
@ kFlutterBackingStoreTypeOpenGL
Definition embedder.h:2081
#define FLUTTER_ENGINE_VERSION
Definition embedder.h:70
FlutterPointerDeviceKind
The device type that created a pointer event.
Definition embedder.h:1309
@ kFlutterPointerDeviceKindTouch
Definition embedder.h:1311
@ kFlutterPointerDeviceKindTrackpad
Definition embedder.h:1313
@ kFlutterPointerDeviceKindStylus
Definition embedder.h:1312
@ kFlutterPointerDeviceKindMouse
Definition embedder.h:1310
#define SAFE_EXISTS(pointer, member)
Checks if the member exists and is non-null.
#define SAFE_ACCESS(pointer, member, default_value)
#define STRUCT_HAS_MEMBER(pointer, member)
#define SAFE_EXISTS_ONE_OF(pointer, member1, member2)
Checks if exactly one of member1 or member2 exists and is non-null.
FlutterVulkanImage * image
VkPhysicalDevice physical_device
Definition main.cc:67
VkDevice device
Definition main.cc:69
FlutterEngine engine
Definition main.cc:84
VkInstance instance
Definition main.cc:64
VkQueue queue
Definition main.cc:71
VkSurfaceKHR surface
Definition main.cc:65
const char * message
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const gchar * channel
const uint8_t uint32_t uint32_t GError ** error
uint32_t uint32_t * format
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DCHECK(condition)
Definition logging.h:122
Dart_NativeFunction function
Definition fuchsia.cc:50
const char * name
Definition fuchsia.cc:49
std::shared_ptr< ImpellerAllocator > allocator
static const char * kApplicationKernelSnapshotFileName
FlTexture * texture
double y
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
impeller::Matrix DlMatrix
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
@ kPointerButtonMousePrimary
@ kPointerButtonTouchContact
KeyEventType
Definition key_data.h:22
impeller::IRect32 DlIRect
ViewFocusDirection
Definition view_focus.h:22
Settings SettingsFromCommandLine(const fml::CommandLine &command_line, bool require_merged_platform_ui_thread)
Definition switches.cc:230
KeyEventDeviceType
Definition key_data.h:34
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)
void TraceEvent0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
void TraceEventEnd(TraceArg name)
CommandLine CommandLineFromArgcArgv(int argc, const char *const *argv)
internal::CopyableLambda< T > MakeCopyable(T lambda)
bool IsFile(const std::string &path)
std::function< void()> closure
Definition closure.h:14
std::shared_ptr< Texture > WrapTextureMTL(TextureDescriptor desc, const void *mtl_texture, std::function< void()> deletion_proc=nullptr)
ISize64 ISize
Definition size.h:162
std::optional< SkColorInfo > getSkColorInfo(FlutterSoftwarePixelFormat pixfmt)
std::vector< FlutterEngineDisplay > * displays
uint32_t color_type
int32_t height
int32_t width
UniqueLoadedElf loaded_elf
Definition embedder.cc:1699
const uint8_t * vm_isolate_instrs
Definition embedder.cc:1703
const uint8_t * vm_snapshot_instrs
Definition embedder.cc:1701
const uint8_t * vm_snapshot_data
Definition embedder.cc:1700
const uint8_t * vm_isolate_data
Definition embedder.cc:1702
std::unique_ptr< flutter::PlatformMessage > message
Definition embedder.cc:1685
FlutterAddViewCallback add_view_callback
Definition embedder.h:1147
FlutterViewId view_id
The identifier for the view to add. This must be unique.
Definition embedder.h:1127
const FlutterWindowMetricsEvent * view_metrics
Definition embedder.h:1132
void * user_data
The |FlutterAddViewInfo.user_data|.
Definition embedder.h:1111
bool added
True if the add view operation succeeded.
Definition embedder.h:1108
FlutterSize size
The size of the render target the engine expects to render into.
Definition embedder.h:2123
FlutterVulkanBackingStore vulkan
Definition embedder.h:2115
FlutterMetalBackingStore metal
Definition embedder.h:2113
FlutterBackingStoreType type
Specifies the type of backing store.
Definition embedder.h:2101
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition embedder.h:2107
FlutterSoftwareBackingStore software
The description of the software backing store.
Definition embedder.h:2109
FlutterSoftwareBackingStore2 software2
The description of the software backing store.
Definition embedder.h:2111
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStore).
Definition embedder.h:2095
An update to whether a message channel has a listener set or not.
Definition embedder.h:1859
FlutterBackingStoreCreateCallback create_backing_store_callback
Definition embedder.h:2243
FlutterBackingStoreCollectCallback collect_backing_store_callback
Definition embedder.h:2248
A structure to represent a damage region.
Definition embedder.h:671
size_t num_rects
The number of rectangles within the damage region.
Definition embedder.h:675
size_t struct_size
The size of this struct. Must be sizeof(FlutterDamage).
Definition embedder.h:673
FlutterRect * damage
The actual damage region(s) in question.
Definition embedder.h:677
FlutterEngineAOTDataSourceType type
Definition embedder.h:2464
const char * elf_path
Absolute path to an ELF library file.
Definition embedder.h:2467
FlutterEngineDartObjectType type
Definition embedder.h:2417
const char * string_value
Definition embedder.h:2426
const FlutterEngineDartBuffer * buffer_value
Definition embedder.h:2427
Function-pointer-based versions of the APIs above.
Definition embedder.h:3738
size_t struct_size
The size of this struct. Must be sizeof(FlutterFrameInfo).
Definition embedder.h:688
FlutterUIntSize size
The size of the surface that will be backed by the fbo.
Definition embedder.h:690
FlutterSize size
The size of the layer (in physical pixels).
Definition embedder.h:2177
FlutterMetalTexture texture
Definition embedder.h:2004
FlutterMetalTextureFrameCallback external_texture_frame_callback
Definition embedder.h:915
FlutterMetalCommandQueueHandle present_command_queue
Alias for id<MTLCommandQueue>.
Definition embedder.h:900
FlutterMetalDeviceHandle device
Alias for id<MTLDevice>.
Definition embedder.h:898
FlutterMetalPresentCallback present_drawable_callback
Definition embedder.h:910
FlutterMetalTextureCallback get_next_drawable_callback
Definition embedder.h:905
FlutterMetalTextureHandle texture
Definition embedder.h:872
size_t struct_size
The size of this struct. Must be sizeof(FlutterMetalTexture).
Definition embedder.h:862
VoidCallback destruction_callback
Definition embedder.h:879
FlutterOpenGLSurface surface
Definition embedder.h:1953
FlutterOpenGLTexture texture
A texture for Flutter to render into.
Definition embedder.h:1947
FlutterOpenGLTargetType type
Definition embedder.h:1944
FlutterOpenGLFramebuffer framebuffer
Definition embedder.h:1950
uint32_t name
The name of the framebuffer.
Definition embedder.h:551
VoidCallback destruction_callback
Definition embedder.h:558
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition embedder.h:554
ProcResolver gl_proc_resolver
Definition embedder.h:765
BoolPresentInfoCallback present_with_info
Definition embedder.h:789
TextureFrameCallback gl_external_texture_frame_callback
Definition embedder.h:770
FlutterFrameBufferWithDamageCallback populate_existing_damage
Definition embedder.h:803
TransformationCallback surface_transformation
Definition embedder.h:764
BoolCallback make_resource_current
Definition embedder.h:748
UIntFrameInfoCallback fbo_with_frame_info_callback
Definition embedder.h:778
FlutterOpenGLSurfaceCallback clear_current_callback
Definition embedder.h:601
FlutterOpenGLSurfaceCallback make_current_callback
Definition embedder.h:584
const char * channel
Definition embedder.h:1467
size_t struct_size
The size of this struct. Must be sizeof(FlutterPointerEvent).
Definition embedder.h:1338
size_t struct_size
The size of this struct. Must be sizeof(FlutterPresentInfo).
Definition embedder.h:710
A structure to represent a rectangle.
Definition embedder.h:648
double bottom
Definition embedder.h:652
double top
Definition embedder.h:650
double left
Definition embedder.h:649
double right
Definition embedder.h:651
FlutterRemoveViewCallback remove_view_callback
Definition embedder.h:1195
FlutterViewId view_id
Definition embedder.h:1178
void * user_data
The |FlutterRemoveViewInfo.user_data|.
Definition embedder.h:1159
bool removed
True if the remove view operation succeeded.
Definition embedder.h:1156
FlutterVulkanRendererConfig vulkan
Definition embedder.h:1043
FlutterMetalRendererConfig metal
Definition embedder.h:1042
FlutterSoftwareRendererConfig software
Definition embedder.h:1041
FlutterOpenGLRendererConfig open_gl
Definition embedder.h:1040
FlutterRendererType type
Definition embedder.h:1038
FlutterSemanticsNode * nodes
Definition embedder.h:1818
size_t nodes_count
The number of semantics node updates.
Definition embedder.h:1816
size_t custom_actions_count
The number of semantics custom action updates.
Definition embedder.h:1820
FlutterSemanticsCustomAction * custom_actions
Array of semantics custom actions. Has length custom_actions_count.
Definition embedder.h:1822
FlutterViewId view_id
The ID of the view that includes the node.
Definition embedder.h:2808
FlutterSemanticsAction action
The semantics action.
Definition embedder.h:2814
size_t data_length
The data length.
Definition embedder.h:2820
uint64_t node_id
The semantics node identifier.
Definition embedder.h:2811
const uint8_t * data
Data associated with the action.
Definition embedder.h:2817
double height
Definition embedder.h:636
double width
Definition embedder.h:635
VoidCallback destruction_callback
Definition embedder.h:1990
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition embedder.h:1981
FlutterSoftwarePixelFormat pixel_format
Definition embedder.h:1994
VoidCallback destruction_callback
Definition embedder.h:1971
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition embedder.h:1962
SoftwareSurfacePresentCallback surface_present_callback
Definition embedder.h:1034
FlutterTaskRunner runner
Definition embedder.h:1879
double transY
vertical translation
Definition embedder.h:407
double pers2
perspective scale factor
Definition embedder.h:413
double skewX
horizontal skew factor
Definition embedder.h:399
double pers0
input x-axis perspective factor
Definition embedder.h:409
double scaleX
horizontal scale factor
Definition embedder.h:397
double skewY
vertical skew factor
Definition embedder.h:403
double scaleY
vertical scale factor
Definition embedder.h:405
double pers1
input y-axis perspective factor
Definition embedder.h:411
double transX
horizontal translation
Definition embedder.h:401
uint32_t width
Definition embedder.h:643
FlutterViewFocusState state
The focus state of the view.
Definition embedder.h:1240
FlutterViewFocusDirection direction
The direction in which the focus transitioned across [FlutterView]s.
Definition embedder.h:1243
FlutterViewId view_id
The identifier of the view that received the focus event.
Definition embedder.h:1237
size_t struct_size
The size of this struct. Must be sizeof(FlutterVulkanImage).
Definition embedder.h:935
uint32_t format
The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
Definition embedder.h:940
FlutterVulkanQueueHandle queue
Definition embedder.h:984
FlutterVulkanDeviceHandle device
Definition embedder.h:975
FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback
Definition embedder.h:1013
size_t enabled_instance_extension_count
Definition embedder.h:987
uint32_t queue_family_index
The queue family index of the VkQueue supplied in the next field.
Definition embedder.h:977
FlutterVulkanImageCallback get_next_image_callback
Definition embedder.h:1017
const char ** enabled_instance_extensions
Definition embedder.h:994
const char ** enabled_device_extensions
Definition embedder.h:1005
FlutterVulkanInstanceHandle instance
Definition embedder.h:970
FlutterVulkanPresentCallback present_image_callback
Definition embedder.h:1023
FlutterVulkanPhysicalDeviceHandle physical_device
VkPhysicalDevice handle.
Definition embedder.h:972
void operator()(Dart_LoadedElf *elf)
Definition embedder.cc:1689
std::function< bool(GPUMTLTextureInfo texture)> present
GPUMTLDestructionCallback destruction_callback
uint64_t synthesized
Definition key_data.h:70
KeyEventDeviceType device_type
Definition key_data.h:71
uint64_t logical
Definition key_data.h:66
uint64_t physical
Definition key_data.h:65
KeyEventType type
Definition key_data.h:64
uint64_t timestamp
Definition key_data.h:63
std::string application_kernel_asset
Definition settings.h:140
LogMessageCallback log_message_callback
Definition settings.h:316
MappingCallback isolate_snapshot_instr
Definition settings.h:123
std::function< void(const DartIsolate &)> root_isolate_create_callback
Definition settings.h:285
std::string assets_path
Definition settings.h:333
TaskObserverRemove task_observer_remove
Definition settings.h:282
MappingCallback isolate_snapshot_data
Definition settings.h:121
MappingCallback vm_snapshot_data
Definition settings.h:116
TaskObserverAdd task_observer_add
Definition settings.h:281
std::string log_tag
Definition settings.h:320
std::string icu_data_path
Definition settings.h:327
MappingCallback vm_snapshot_instr
Definition settings.h:118
MappingCallback dart_library_sources_kernel
Definition settings.h:129
int64_t old_gen_heap_size
Definition settings.h:352
The ThreadConfig is the thread info include thread name, thread priority.
Definition thread.h:35
std::shared_ptr< Texture > resolve_texture
Definition formats.h:662
LoadAction load_action
Definition formats.h:663
std::shared_ptr< Texture > texture
Definition formats.h:661
StoreAction store_action
Definition formats.h:664
static constexpr Color DarkSlateGray()
Definition color.h:418
constexpr auto GetBottom() const
Definition rect.h:357
constexpr auto GetTop() const
Definition rect.h:353
constexpr auto GetLeft() const
Definition rect.h:351
constexpr auto GetRight() const
Definition rect.h:355
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
std::shared_ptr< const fml::Mapping > data
const uintptr_t id
#define TRACE_EVENT0(category_group, name)
#define GetCurrentTime()