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