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