Flutter Engine
fl_engine.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 #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
6 
7 #include <gmodule.h>
8 
9 #include <cstring>
10 
11 #include "flutter/shell/platform/embedder/embedder.h"
12 #include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
13 #include "flutter/shell/platform/linux/fl_dart_project_private.h"
14 #include "flutter/shell/platform/linux/fl_engine_private.h"
15 #include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h"
16 #include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
17 #include "flutter/shell/platform/linux/fl_renderer.h"
18 #include "flutter/shell/platform/linux/fl_renderer_headless.h"
19 #include "flutter/shell/platform/linux/fl_settings_plugin.h"
20 #include "flutter/shell/platform/linux/fl_texture_gl_private.h"
21 #include "flutter/shell/platform/linux/fl_texture_registrar_private.h"
22 #include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"
23 
24 // Unique number associated with platform tasks.
25 static constexpr size_t kPlatformTaskRunnerIdentifier = 1;
26 
27 struct _FlEngine {
28  GObject parent_instance;
29 
30  // Thread the GLib main loop is running on.
31  GThread* thread;
32 
33  FlDartProject* project;
34  FlRenderer* renderer;
35  FlBinaryMessenger* binary_messenger;
36  FlSettingsPlugin* settings_plugin;
37  FlTextureRegistrar* texture_registrar;
38  FlTaskRunner* task_runner;
42 
43  // Function to call when a platform message is received.
47 
48  // Function to call when a semantic node is received.
52 
53  // Function to call right before the engine is restarted.
57 };
58 
59 G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error)
60 
62  FlPluginRegistryInterface* iface);
63 
65  FlEngine,
66  fl_engine,
67  G_TYPE_OBJECT,
68  G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
70 
71 // Parse a locale into its components.
72 static void parse_locale(const gchar* locale,
73  gchar** language,
74  gchar** territory,
75  gchar** codeset,
76  gchar** modifier) {
77  gchar* l = g_strdup(locale);
78 
79  // Locales are in the form "language[_territory][.codeset][@modifier]"
80  gchar* match = strrchr(l, '@');
81  if (match != nullptr) {
82  *modifier = g_strdup(match + 1);
83  *match = '\0';
84  } else {
85  *modifier = nullptr;
86  }
87 
88  match = strrchr(l, '.');
89  if (match != nullptr) {
90  *codeset = g_strdup(match + 1);
91  *match = '\0';
92  } else {
93  *codeset = nullptr;
94  }
95 
96  match = strrchr(l, '_');
97  if (match != nullptr) {
98  *territory = g_strdup(match + 1);
99  *match = '\0';
100  } else {
101  *territory = nullptr;
102  }
103 
104  *language = l;
105 }
106 
107 // Passes locale information to the Flutter engine.
108 static void setup_locales(FlEngine* self) {
109  const gchar* const* languages = g_get_language_names();
110  g_autoptr(GPtrArray) locales_array = g_ptr_array_new_with_free_func(g_free);
111  // Helper array to take ownership of the strings passed to Flutter.
112  g_autoptr(GPtrArray) locale_strings = g_ptr_array_new_with_free_func(g_free);
113  for (int i = 0; languages[i] != nullptr; i++) {
114  gchar *language, *territory, *codeset, *modifier;
115  parse_locale(languages[i], &language, &territory, &codeset, &modifier);
116  if (language != nullptr) {
117  g_ptr_array_add(locale_strings, language);
118  }
119  if (territory != nullptr) {
120  g_ptr_array_add(locale_strings, territory);
121  }
122  if (codeset != nullptr) {
123  g_ptr_array_add(locale_strings, codeset);
124  }
125  if (modifier != nullptr) {
126  g_ptr_array_add(locale_strings, modifier);
127  }
128 
129  FlutterLocale* locale =
130  static_cast<FlutterLocale*>(g_malloc0(sizeof(FlutterLocale)));
131  g_ptr_array_add(locales_array, locale);
132  locale->struct_size = sizeof(FlutterLocale);
133  locale->language_code = language;
134  locale->country_code = territory;
135  locale->script_code = codeset;
136  locale->variant_code = modifier;
137  }
138  FlutterLocale** locales =
139  reinterpret_cast<FlutterLocale**>(locales_array->pdata);
140  FlutterEngineResult result = self->embedder_api.UpdateLocales(
141  self->engine, const_cast<const FlutterLocale**>(locales),
142  locales_array->len);
143  if (result != kSuccess) {
144  g_warning("Failed to set up Flutter locales");
145  }
146 }
147 
148 // Called when engine needs a backing store for a specific #FlutterLayer.
150  const FlutterBackingStoreConfig* config,
151  FlutterBackingStore* backing_store_out,
152  void* user_data) {
153  g_return_val_if_fail(FL_IS_RENDERER(user_data), false);
154  return fl_renderer_create_backing_store(FL_RENDERER(user_data), config,
155  backing_store_out);
156 }
157 
158 // Called when the backing store is to be released.
161  void* user_data) {
162  g_return_val_if_fail(FL_IS_RENDERER(user_data), false);
163  return fl_renderer_collect_backing_store(FL_RENDERER(user_data), renderer);
164 }
165 
166 // Called when embedder should composite contents of each layer onto the screen.
168  size_t layers_count,
169  void* user_data) {
170  g_return_val_if_fail(FL_IS_RENDERER(user_data), false);
171  return fl_renderer_present_layers(FL_RENDERER(user_data), layers,
172  layers_count);
173 }
174 
175 // Flutter engine rendering callbacks.
176 
177 static void* fl_engine_gl_proc_resolver(void* user_data, const char* name) {
178  FlEngine* self = static_cast<FlEngine*>(user_data);
179  return fl_renderer_get_proc_address(self->renderer, name);
180 }
181 
183  FlEngine* self = static_cast<FlEngine*>(user_data);
184  g_autoptr(GError) error = nullptr;
185  gboolean result = fl_renderer_make_current(self->renderer, &error);
186  if (!result) {
187  g_warning("%s", error->message);
188  }
189  return result;
190 }
191 
193  FlEngine* self = static_cast<FlEngine*>(user_data);
194  g_autoptr(GError) error = nullptr;
195  gboolean result = fl_renderer_clear_current(self->renderer, &error);
196  if (!result) {
197  g_warning("%s", error->message);
198  }
199  return result;
200 }
201 
202 static uint32_t fl_engine_gl_get_fbo(void* user_data) {
203  FlEngine* self = static_cast<FlEngine*>(user_data);
204  return fl_renderer_get_fbo(self->renderer);
205 }
206 
207 static bool fl_engine_gl_present(void* user_data) {
208  // No action required, as this is handled in
209  // compositor_present_layers_callback.
210  return true;
211 }
212 
214  FlEngine* self = static_cast<FlEngine*>(user_data);
215  g_autoptr(GError) error = nullptr;
216  gboolean result = fl_renderer_make_resource_current(self->renderer, &error);
217  if (!result) {
218  g_warning("%s", error->message);
219  }
220  return result;
221 }
222 
223 // Called by the engine to retrieve an external texture.
225  void* user_data,
226  int64_t texture_id,
227  size_t width,
228  size_t height,
229  FlutterOpenGLTexture* opengl_texture) {
230  FlEngine* self = static_cast<FlEngine*>(user_data);
231  if (!self->texture_registrar) {
232  return false;
233  }
234 
235  FlTexture* texture =
236  fl_texture_registrar_lookup_texture(self->texture_registrar, texture_id);
237  if (texture == nullptr) {
238  g_warning("Unable to find texture %" G_GINT64_FORMAT, texture_id);
239  return false;
240  }
241 
242  gboolean result;
243  g_autoptr(GError) error = nullptr;
244  if (FL_IS_TEXTURE_GL(texture)) {
245  result = fl_texture_gl_populate(FL_TEXTURE_GL(texture), width, height,
246  opengl_texture, &error);
247  } else if (FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
248  result =
249  fl_pixel_buffer_texture_populate(FL_PIXEL_BUFFER_TEXTURE(texture),
250  width, height, opengl_texture, &error);
251  } else {
252  g_warning("Unsupported texture type %" G_GINT64_FORMAT, texture_id);
253  return false;
254  }
255 
256  if (!result) {
257  g_warning("%s", error->message);
258  return false;
259  }
260 
261  return true;
262 }
263 
264 // Called by the engine to determine if it is on the GTK thread.
266  FlEngine* self = static_cast<FlEngine*>(user_data);
267  return self->thread == g_thread_self();
268 }
269 
270 // Called when the engine has a task to perform in the GTK thread.
272  uint64_t target_time_nanos,
273  void* user_data) {
274  FlEngine* self = static_cast<FlEngine*>(user_data);
275 
276  fl_task_runner_post_task(self->task_runner, task, target_time_nanos);
277 }
278 
279 // Called when a platform message is received from the engine.
281  void* user_data) {
282  FlEngine* self = FL_ENGINE(user_data);
283 
284  gboolean handled = FALSE;
285  if (self->platform_message_handler != nullptr) {
286  g_autoptr(GBytes) data =
287  g_bytes_new(message->message, message->message_size);
288  handled = self->platform_message_handler(
289  self, message->channel, data, message->response_handle,
290  self->platform_message_handler_data);
291  }
292 
293  if (!handled) {
295  nullptr, nullptr);
296  }
297 }
298 
299 // Called when a semantic node update is received from the engine.
301  void* user_data) {
302  FlEngine* self = FL_ENGINE(user_data);
303 
304  if (self->update_semantics_node_handler != nullptr) {
305  self->update_semantics_node_handler(
306  self, node, self->update_semantics_node_handler_data);
307  }
308 }
309 
310 // Called right before the engine is restarted.
311 //
312 // This method should reset states to as if the engine has just been started,
313 // which usually indicates the user has requested a hot restart (Shift-R in the
314 // Flutter CLI.)
316  FlEngine* self = FL_ENGINE(user_data);
317 
318  if (self->on_pre_engine_restart_handler != nullptr) {
319  self->on_pre_engine_restart_handler(
320  self, self->on_pre_engine_restart_handler_data);
321  }
322 }
323 
324 // Called when a response to a sent platform message is received from the
325 // engine.
326 static void fl_engine_platform_message_response_cb(const uint8_t* data,
327  size_t data_length,
328  void* user_data) {
329  g_autoptr(GTask) task = G_TASK(user_data);
330  g_task_return_pointer(task, g_bytes_new(data, data_length),
331  reinterpret_cast<GDestroyNotify>(g_bytes_unref));
332 }
333 
334 // Implements FlPluginRegistry::get_registrar_for_plugin.
335 static FlPluginRegistrar* fl_engine_get_registrar_for_plugin(
336  FlPluginRegistry* registry,
337  const gchar* name) {
338  FlEngine* self = FL_ENGINE(registry);
339 
340  return fl_plugin_registrar_new(nullptr, self->binary_messenger,
341  self->texture_registrar);
342 }
343 
345  FlPluginRegistryInterface* iface) {
346  iface->get_registrar_for_plugin = fl_engine_get_registrar_for_plugin;
347 }
348 
349 static void fl_engine_dispose(GObject* object) {
350  FlEngine* self = FL_ENGINE(object);
351 
352  if (self->engine != nullptr) {
353  self->embedder_api.Shutdown(self->engine);
354  self->engine = nullptr;
355  }
356 
357  if (self->aot_data != nullptr) {
358  self->embedder_api.CollectAOTData(self->aot_data);
359  self->aot_data = nullptr;
360  }
361 
362  g_clear_object(&self->project);
363  g_clear_object(&self->renderer);
364  g_clear_object(&self->texture_registrar);
365  g_clear_object(&self->binary_messenger);
366  g_clear_object(&self->settings_plugin);
367  g_clear_object(&self->task_runner);
368 
369  if (self->platform_message_handler_destroy_notify) {
370  self->platform_message_handler_destroy_notify(
371  self->platform_message_handler_data);
372  }
373  self->platform_message_handler_data = nullptr;
374  self->platform_message_handler_destroy_notify = nullptr;
375 
376  if (self->update_semantics_node_handler_destroy_notify) {
377  self->update_semantics_node_handler_destroy_notify(
378  self->update_semantics_node_handler_data);
379  }
380  self->update_semantics_node_handler_data = nullptr;
381  self->update_semantics_node_handler_destroy_notify = nullptr;
382 
383  if (self->on_pre_engine_restart_handler_destroy_notify) {
384  self->on_pre_engine_restart_handler_destroy_notify(
385  self->on_pre_engine_restart_handler_data);
386  }
387  self->on_pre_engine_restart_handler_data = nullptr;
388  self->on_pre_engine_restart_handler_destroy_notify = nullptr;
389 
390  G_OBJECT_CLASS(fl_engine_parent_class)->dispose(object);
391 }
392 
393 static void fl_engine_class_init(FlEngineClass* klass) {
394  G_OBJECT_CLASS(klass)->dispose = fl_engine_dispose;
395 }
396 
397 static void fl_engine_init(FlEngine* self) {
398  self->thread = g_thread_self();
399 
400  self->embedder_api.struct_size = sizeof(FlutterEngineProcTable);
401  FlutterEngineGetProcAddresses(&self->embedder_api);
402 
403  self->texture_registrar = fl_texture_registrar_new(self);
404  self->binary_messenger = fl_binary_messenger_new(self);
405 }
406 
407 FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer) {
408  g_return_val_if_fail(FL_IS_DART_PROJECT(project), nullptr);
409  g_return_val_if_fail(FL_IS_RENDERER(renderer), nullptr);
410 
411  FlEngine* self = FL_ENGINE(g_object_new(fl_engine_get_type(), nullptr));
412  self->project = FL_DART_PROJECT(g_object_ref(project));
413  self->renderer = FL_RENDERER(g_object_ref(renderer));
414  return self;
415 }
416 
417 G_MODULE_EXPORT FlEngine* fl_engine_new_headless(FlDartProject* project) {
418  g_autoptr(FlRendererHeadless) renderer = fl_renderer_headless_new();
419  return fl_engine_new(project, FL_RENDERER(renderer));
420 }
421 
422 gboolean fl_engine_start(FlEngine* self, GError** error) {
423  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
424 
425  self->task_runner = fl_task_runner_new(self);
426 
427  FlutterRendererConfig config = {};
428  config.type = kOpenGL;
438 
439  FlutterTaskRunnerDescription platform_task_runner = {};
440  platform_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription);
441  platform_task_runner.user_data = self;
442  platform_task_runner.runs_task_on_current_thread_callback =
444  platform_task_runner.post_task_callback = fl_engine_post_task;
445  platform_task_runner.identifier = kPlatformTaskRunnerIdentifier;
446 
447  FlutterCustomTaskRunners custom_task_runners = {};
448  custom_task_runners.struct_size = sizeof(FlutterCustomTaskRunners);
449  custom_task_runners.platform_task_runner = &platform_task_runner;
450  custom_task_runners.render_task_runner = &platform_task_runner;
451 
452  g_autoptr(GPtrArray) command_line_args =
453  fl_dart_project_get_switches(self->project);
454  // FlutterProjectArgs expects a full argv, so when processing it for flags
455  // the first item is treated as the executable and ignored. Add a dummy value
456  // so that all switches are used.
457  g_ptr_array_insert(command_line_args, 0, g_strdup("flutter"));
458 
459  gchar** dart_entrypoint_args =
461 
463  args.struct_size = sizeof(FlutterProjectArgs);
464  args.assets_path = fl_dart_project_get_assets_path(self->project);
465  args.icu_data_path = fl_dart_project_get_icu_data_path(self->project);
466  args.command_line_argc = command_line_args->len;
467  args.command_line_argv =
468  reinterpret_cast<const char* const*>(command_line_args->pdata);
471  args.custom_task_runners = &custom_task_runners;
472  args.shutdown_dart_vm_when_done = true;
474  args.dart_entrypoint_argc =
475  dart_entrypoint_args != nullptr ? g_strv_length(dart_entrypoint_args) : 0;
476  args.dart_entrypoint_argv =
477  reinterpret_cast<const char* const*>(dart_entrypoint_args);
478 
479  FlutterCompositor compositor = {};
480  compositor.struct_size = sizeof(FlutterCompositor);
481  compositor.user_data = self->renderer;
482  compositor.create_backing_store_callback =
484  compositor.collect_backing_store_callback =
487  args.compositor = &compositor;
488 
489  if (self->embedder_api.RunsAOTCompiledDartCode()) {
490  FlutterEngineAOTDataSource source = {};
492  source.elf_path = fl_dart_project_get_aot_library_path(self->project);
493  if (self->embedder_api.CreateAOTData(&source, &self->aot_data) !=
494  kSuccess) {
495  g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
496  "Failed to create AOT data");
497  return FALSE;
498  }
499  args.aot_data = self->aot_data;
500  }
501 
502  FlutterEngineResult result = self->embedder_api.Initialize(
503  FLUTTER_ENGINE_VERSION, &config, &args, self, &self->engine);
504  if (result != kSuccess) {
505  g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
506  "Failed to initialize Flutter engine");
507  return FALSE;
508  }
509 
510  result = self->embedder_api.RunInitialized(self->engine);
511  if (result != kSuccess) {
512  g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
513  "Failed to run Flutter engine");
514  return FALSE;
515  }
516 
517  setup_locales(self);
518 
519  self->settings_plugin = fl_settings_plugin_new(self->binary_messenger);
520  fl_settings_plugin_start(self->settings_plugin);
521 
522  result = self->embedder_api.UpdateSemanticsEnabled(self->engine, TRUE);
523  if (result != kSuccess) {
524  g_warning("Failed to enable accessibility features on Flutter engine");
525  }
526 
527  return TRUE;
528 }
529 
531  return &(self->embedder_api);
532 }
533 
535  FlEngine* self,
537  gpointer user_data,
538  GDestroyNotify destroy_notify) {
539  g_return_if_fail(FL_IS_ENGINE(self));
540  g_return_if_fail(handler != nullptr);
541 
542  if (self->platform_message_handler_destroy_notify) {
543  self->platform_message_handler_destroy_notify(
544  self->platform_message_handler_data);
545  }
546 
547  self->platform_message_handler = handler;
548  self->platform_message_handler_data = user_data;
549  self->platform_message_handler_destroy_notify = destroy_notify;
550 }
551 
553  FlEngine* self,
555  gpointer user_data,
556  GDestroyNotify destroy_notify) {
557  g_return_if_fail(FL_IS_ENGINE(self));
558 
559  if (self->update_semantics_node_handler_destroy_notify) {
560  self->update_semantics_node_handler_destroy_notify(
561  self->update_semantics_node_handler_data);
562  }
563 
564  self->update_semantics_node_handler = handler;
565  self->update_semantics_node_handler_data = user_data;
566  self->update_semantics_node_handler_destroy_notify = destroy_notify;
567 }
568 
570  FlEngine* self,
572  gpointer user_data,
573  GDestroyNotify destroy_notify) {
574  g_return_if_fail(FL_IS_ENGINE(self));
575 
576  if (self->on_pre_engine_restart_handler_destroy_notify) {
577  self->on_pre_engine_restart_handler_destroy_notify(
578  self->on_pre_engine_restart_handler_data);
579  }
580 
581  self->on_pre_engine_restart_handler = handler;
582  self->on_pre_engine_restart_handler_data = user_data;
583  self->on_pre_engine_restart_handler_destroy_notify = destroy_notify;
584 }
585 
587  FlEngine* self,
589  GBytes* response,
590  GError** error) {
591  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
592  g_return_val_if_fail(handle != nullptr, FALSE);
593 
594  if (self->engine == nullptr) {
595  g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
596  "No engine to send response to");
597  return FALSE;
598  }
599 
600  gsize data_length = 0;
601  const uint8_t* data = nullptr;
602  if (response != nullptr) {
603  data =
604  static_cast<const uint8_t*>(g_bytes_get_data(response, &data_length));
605  }
606  FlutterEngineResult result = self->embedder_api.SendPlatformMessageResponse(
607  self->engine, handle, data, data_length);
608 
609  if (result != kSuccess) {
610  g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
611  "Failed to send platform message response");
612  return FALSE;
613  }
614 
615  return TRUE;
616 }
617 
619  const gchar* channel,
620  GBytes* message,
621  GCancellable* cancellable,
622  GAsyncReadyCallback callback,
623  gpointer user_data) {
624  g_return_if_fail(FL_IS_ENGINE(self));
625 
626  GTask* task = nullptr;
627  FlutterPlatformMessageResponseHandle* response_handle = nullptr;
628  if (callback != nullptr) {
629  task = g_task_new(self, cancellable, callback, user_data);
630 
631  if (self->engine == nullptr) {
632  g_task_return_new_error(task, fl_engine_error_quark(),
633  FL_ENGINE_ERROR_FAILED, "No engine to send to");
634  return;
635  }
636 
638  self->embedder_api.PlatformMessageCreateResponseHandle(
639  self->engine, fl_engine_platform_message_response_cb, task,
640  &response_handle);
641  if (result != kSuccess) {
642  g_task_return_new_error(task, fl_engine_error_quark(),
644  "Failed to create response handle");
645  g_object_unref(task);
646  return;
647  }
648  } else if (self->engine == nullptr) {
649  return;
650  }
651 
652  FlutterPlatformMessage fl_message = {};
653  fl_message.struct_size = sizeof(fl_message);
654  fl_message.channel = channel;
655  fl_message.message =
656  message != nullptr
657  ? static_cast<const uint8_t*>(g_bytes_get_data(message, nullptr))
658  : nullptr;
659  fl_message.message_size = message != nullptr ? g_bytes_get_size(message) : 0;
660  fl_message.response_handle = response_handle;
662  self->embedder_api.SendPlatformMessage(self->engine, &fl_message);
663 
664  if (result != kSuccess && task != nullptr) {
665  g_task_return_new_error(task, fl_engine_error_quark(),
667  "Failed to send platform messages");
668  g_object_unref(task);
669  }
670 
671  if (response_handle != nullptr) {
672  self->embedder_api.PlatformMessageReleaseResponseHandle(self->engine,
673  response_handle);
674  }
675 }
676 
678  GAsyncResult* result,
679  GError** error) {
680  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
681  g_return_val_if_fail(g_task_is_valid(result, self), FALSE);
682 
683  return static_cast<GBytes*>(g_task_propagate_pointer(G_TASK(result), error));
684 }
685 
687  size_t width,
688  size_t height,
689  double pixel_ratio) {
690  g_return_if_fail(FL_IS_ENGINE(self));
691 
692  if (self->engine == nullptr) {
693  return;
694  }
695 
696  FlutterWindowMetricsEvent event = {};
697  event.struct_size = sizeof(FlutterWindowMetricsEvent);
698  event.width = width;
699  event.height = height;
700  event.pixel_ratio = pixel_ratio;
701  self->embedder_api.SendWindowMetricsEvent(self->engine, &event);
702 }
703 
705  FlutterPointerPhase phase,
706  size_t timestamp,
707  double x,
708  double y,
709  double scroll_delta_x,
710  double scroll_delta_y,
711  int64_t buttons) {
712  g_return_if_fail(FL_IS_ENGINE(self));
713 
714  if (self->engine == nullptr) {
715  return;
716  }
717 
718  FlutterPointerEvent fl_event = {};
719  fl_event.struct_size = sizeof(fl_event);
720  fl_event.phase = phase;
721  fl_event.timestamp = timestamp;
722  fl_event.x = x;
723  fl_event.y = y;
724  if (scroll_delta_x != 0 || scroll_delta_y != 0) {
726  }
727  fl_event.scroll_delta_x = scroll_delta_x;
728  fl_event.scroll_delta_y = scroll_delta_y;
730  fl_event.buttons = buttons;
731  self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
732 }
733 
734 void fl_engine_send_key_event(FlEngine* self,
735  const FlutterKeyEvent* event,
737  void* user_data) {
738  g_return_if_fail(FL_IS_ENGINE(self));
739 
740  if (self->engine == nullptr) {
741  return;
742  }
743 
744  self->embedder_api.SendKeyEvent(self->engine, event, callback, user_data);
745 }
746 
748  uint64_t id,
750  GBytes* data) {
751  g_return_if_fail(FL_IS_ENGINE(self));
752 
753  if (self->engine == nullptr) {
754  return;
755  }
756 
757  const uint8_t* action_data = nullptr;
758  size_t action_data_length = 0;
759  if (data != nullptr) {
760  action_data = static_cast<const uint8_t*>(
761  g_bytes_get_data(data, &action_data_length));
762  }
763 
764  self->embedder_api.DispatchSemanticsAction(self->engine, id, action,
765  action_data, action_data_length);
766 }
767 
769  int64_t texture_id) {
770  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
771  return self->embedder_api.MarkExternalTextureFrameAvailable(
772  self->engine, texture_id) == kSuccess;
773 }
774 
775 gboolean fl_engine_register_external_texture(FlEngine* self,
776  int64_t texture_id) {
777  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
778  return self->embedder_api.RegisterExternalTexture(self->engine, texture_id) ==
779  kSuccess;
780 }
781 
783  int64_t texture_id) {
784  g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
785  return self->embedder_api.UnregisterExternalTexture(self->engine,
786  texture_id) == kSuccess;
787 }
788 
789 G_MODULE_EXPORT FlBinaryMessenger* fl_engine_get_binary_messenger(
790  FlEngine* self) {
791  g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
792  return self->binary_messenger;
793 }
794 
795 FlTaskRunner* fl_engine_get_task_runner(FlEngine* self) {
796  g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
797  return self->task_runner;
798 }
799 
800 void fl_engine_execute_task(FlEngine* self, FlutterTask* task) {
801  g_return_if_fail(FL_IS_ENGINE(self));
802  self->embedder_api.RunTask(self->engine, task);
803 }
804 
805 G_MODULE_EXPORT FlTextureRegistrar* fl_engine_get_texture_registrar(
806  FlEngine* self) {
807  g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
808  return self->texture_registrar;
809 }
size_t struct_size
This size of this struct. Must be sizeof(FlutterLocale).
Definition: embedder.h:1152
static void fl_engine_post_task(FlutterTask task, uint64_t target_time_nanos, void *user_data)
Definition: fl_engine.cc:271
G_BEGIN_DECLS FlValue * args
G_MODULE_EXPORT const gchar * fl_dart_project_get_icu_data_path(FlDartProject *self)
const FlutterCompositor * compositor
Definition: embedder.h:1528
FlDartProject * project
Definition: fl_engine.cc:33
void fl_engine_dispatch_semantics_action(FlEngine *self, uint64_t id, FlutterSemanticsAction action, GBytes *data)
Definition: fl_engine.cc:747
gboolean fl_renderer_make_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:95
const char * channel
Definition: embedder.h:758
double scroll_delta_y
The y offset of the scroll in physical pixels.
Definition: embedder.h:666
gboolean fl_renderer_clear_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:115
static bool compositor_create_backing_store_callback(const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out, void *user_data)
Definition: fl_engine.cc:149
gchar * match
Definition: fl_engine.cc:80
static bool compositor_collect_backing_store_callback(const FlutterBackingStore *renderer, void *user_data)
Definition: fl_engine.cc:159
const uint8_t uint32_t uint32_t GError ** error
FlPluginRegistrar * fl_plugin_registrar_new(FlView *view, FlBinaryMessenger *messenger, FlTextureRegistrar *texture_registrar)
gboolean(* FlEnginePlatformMessageHandler)(FlEngine *engine, const gchar *channel, GBytes *message, const FlutterPlatformMessageResponseHandle *response_handle, gpointer user_data)
FlBinaryMessenger * binary_messenger
Definition: fl_engine.cc:35
FlTexture * fl_texture_registrar_lookup_texture(FlTextureRegistrar *self, int64_t texture_id)
const FlutterTaskRunnerDescription * render_task_runner
Definition: embedder.h:948
FlSettingsPlugin * settings_plugin
Definition: fl_engine.cc:36
gboolean fl_texture_gl_populate(FlTextureGL *self, uint32_t width, uint32_t height, FlutterOpenGLTexture *opengl_texture, GError **error)
const char * icu_data_path
Definition: embedder.h:1378
double y
The y coordinate of the pointer event in physical pixels.
Definition: embedder.h:658
const FlutterPlatformMessageResponseHandle * response_handle
Definition: embedder.h:767
size_t struct_size
The size of this struct. Must be sizeof(FlutterTaskRunnerDescription).
Definition: embedder.h:913
const FlutterCustomTaskRunners * custom_task_runners
Definition: embedder.h:1493
FlEnginePlatformMessageHandler platform_message_handler
Definition: fl_engine.cc:44
FlRendererHeadless * fl_renderer_headless_new()
G_MODULE_EXPORT gchar ** fl_dart_project_get_dart_entrypoint_arguments(FlDartProject *self)
G_MODULE_EXPORT const gchar * fl_dart_project_get_aot_library_path(FlDartProject *self)
FlutterPointerPhase
The phase of the pointer event.
Definition: embedder.h:587
FlutterEngineProcTable embedder_api
Definition: fl_engine.cc:41
void fl_engine_set_platform_message_handler(FlEngine *self, FlEnginePlatformMessageHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_engine.cc:534
gboolean fl_renderer_make_resource_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:105
FlTaskRunner * fl_task_runner_new(FlEngine *engine)
Function-pointer-based versions of the APIs above.
Definition: embedder.h:2372
OnPreEngineRestartCallback on_pre_engine_restart_callback
Definition: embedder.h:1591
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:530
void * user_data
double scroll_delta_x
The x offset of the scroll in physical pixels.
Definition: embedder.h:664
const char * variant_code
Definition: embedder.h:1171
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
GPtrArray * fl_dart_project_get_switches(FlDartProject *self)
int64_t texture_id
GAsyncResult * result
static bool fl_engine_gl_make_resource_current(void *user_data)
Definition: fl_engine.cc:213
gboolean fl_pixel_buffer_texture_populate(FlPixelBufferTexture *texture, uint32_t width, uint32_t height, FlutterOpenGLTexture *opengl_texture, GError **error)
void fl_task_runner_post_task(FlTaskRunner *self, FlutterTask task, uint64_t target_time_nanos)
FlutterPlatformMessageCallback platform_message_callback
Definition: embedder.h:1402
void fl_engine_send_key_event(FlEngine *self, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Definition: fl_engine.cc:734
static void setup_locales(FlEngine *self)
Definition: fl_engine.cc:108
G_DEFINE_TYPE_WITH_CODE(FlEngine, fl_engine, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(), fl_engine_plugin_registry_iface_init)) static void parse_locale(const gchar *locale
static void fl_engine_platform_message_cb(const FlutterPlatformMessage *message, void *user_data)
Definition: fl_engine.cc:280
FlKeyEvent FlKeyResponderAsyncCallback callback
FlEngineUpdateSemanticsNodeHandler update_semantics_node_handler
Definition: fl_engine.cc:49
const char *const * command_line_argv
Definition: embedder.h:1396
FlutterSemanticsAction
Definition: embedder.h:101
static bool fl_engine_gl_clear_current(void *user_data)
Definition: fl_engine.cc:192
void * fl_renderer_get_proc_address(FlRenderer *self, const char *name)
Definition: fl_renderer.cc:91
FlKeyEvent * event
const char * script_code
Definition: embedder.h:1166
const char * country_code
Definition: embedder.h:1161
bool shutdown_dart_vm_when_done
Definition: embedder.h:1512
const char *const * dart_entrypoint_argv
Definition: embedder.h:1566
gboolean fl_engine_mark_texture_frame_available(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:768
gchar gchar gchar gchar ** modifier
Definition: fl_engine.cc:76
GDestroyNotify on_pre_engine_restart_handler_destroy_notify
Definition: fl_engine.cc:56
FlutterEngineAOTData aot_data
Definition: fl_engine.cc:39
static bool fl_engine_gl_present(void *user_data)
Definition: fl_engine.cc:207
void fl_engine_send_platform_message(FlEngine *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:618
#define FLUTTER_ENGINE_VERSION
Definition: embedder.h:63
static void fl_engine_plugin_registry_iface_init(FlPluginRegistryInterface *iface)
Definition: fl_engine.cc:344
FlutterRendererType type
Definition: embedder.h:555
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition: switches.h:41
GDestroyNotify update_semantics_node_handler_destroy_notify
Definition: fl_engine.cc:51
GThread * thread
Definition: fl_engine.cc:31
FlTextureRegistrar * texture_registrar
Definition: fl_engine.cc:37
void fl_engine_set_on_pre_engine_restart_handler(FlEngine *self, FlEngineOnPreEngineRestartHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_engine.cc:569
const FlutterSemanticsNode * node
Definition: fl_view.cc:83
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:422
const uint8_t * message
Definition: embedder.h:759
FlEngineOnPreEngineRestartHandler on_pre_engine_restart_handler
Definition: fl_engine.cc:54
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback
Definition: embedder.h:1446
size_t struct_size
The size of this struct. Must be sizeof(FlutterPointerEvent).
Definition: embedder.h:649
gchar ** language
Definition: fl_engine.cc:73
static bool fl_engine_gl_external_texture_frame_callback(void *user_data, int64_t texture_id, size_t width, size_t height, FlutterOpenGLTexture *opengl_texture)
Definition: fl_engine.cc:224
size_t struct_size
The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig).
Definition: embedder.h:388
FlRenderer * renderer
Definition: fl_engine.cc:34
gpointer platform_message_handler_data
Definition: fl_engine.cc:45
static void fl_engine_update_semantics_node_cb(const FlutterSemanticsNode *node, void *user_data)
Definition: fl_engine.cc:300
gboolean fl_renderer_collect_backing_store(FlRenderer *self, const FlutterBackingStore *backing_store)
Definition: fl_renderer.cc:133
G_MODULE_EXPORT FlEngine * fl_engine_new_headless(FlDartProject *project)
Definition: fl_engine.cc:417
SemanticsAction action
static void fl_engine_class_init(FlEngineClass *klass)
Definition: fl_engine.cc:393
gboolean fl_renderer_present_layers(FlRenderer *self, const FlutterLayer **layers, size_t layers_count)
Definition: fl_renderer.cc:157
BoolCallback make_resource_current
Definition: embedder.h:407
BoolCallback clear_current
Definition: embedder.h:390
TextureFrameCallback gl_external_texture_frame_callback
Definition: embedder.h:429
static constexpr size_t kPlatformTaskRunnerIdentifier
Definition: fl_engine.cc:25
void fl_engine_send_window_metrics_event(FlEngine *self, size_t width, size_t height, double pixel_ratio)
Definition: fl_engine.cc:686
gpointer on_pre_engine_restart_handler_data
Definition: fl_engine.cc:55
void fl_engine_execute_task(FlEngine *self, FlutterTask *task)
Definition: fl_engine.cc:800
int32_t width
void fl_settings_plugin_start(FlSettingsPlugin *self)
size_t struct_size
The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
Definition: embedder.h:565
FlutterEngineResult FlutterEngineGetProcAddresses(FlutterEngineProcTable *table)
Gets the table of engine function pointers.
Definition: embedder.cc:2363
void fl_engine_send_mouse_pointer_event(FlEngine *self, FlutterPointerPhase phase, size_t timestamp, double x, double y, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_engine.cc:704
FLUTTER_API_SYMBOL(FlutterEngine) engine
double x
The x coordinate of the pointer event in physical pixels.
Definition: embedder.h:656
static bool fl_engine_gl_make_current(void *user_data)
Definition: fl_engine.cc:182
gboolean fl_renderer_create_backing_store(FlRenderer *self, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
Definition: fl_renderer.cc:125
static void fl_engine_init(FlEngine *self)
Definition: fl_engine.cc:397
int32_t height
FlutterBackingStoreCollectCallback collect_backing_store_callback
Definition: embedder.h:1142
static void fl_engine_on_pre_engine_restart_cb(void *user_data)
Definition: fl_engine.cc:315
const char * assets_path
Definition: embedder.h:1354
BoolCallback make_current
Definition: embedder.h:389
FlutterOpenGLRendererConfig open_gl
Definition: embedder.h:557
gpointer update_semantics_node_handler_data
Definition: fl_engine.cc:50
FlutterEngineResult
Definition: embedder.h:65
size_t struct_size
The size of this struct. Must be sizeof(FlutterProjectArgs).
Definition: embedder.h:1350
FlSettingsPlugin * fl_settings_plugin_new(FlBinaryMessenger *messenger)
FlutterLayersPresentCallback present_layers_callback
Definition: embedder.h:1145
FlEngine * fl_engine_new(FlDartProject *project, FlRenderer *renderer)
Definition: fl_engine.cc:407
FlTextureRegistrar * fl_texture_registrar_new(FlEngine *engine)
int64_t buttons
The buttons currently pressed, if any.
Definition: embedder.h:674
UIntCallback fbo_callback
Definition: embedder.h:400
const FlutterTaskRunnerDescription * platform_task_runner
Definition: embedder.h:943
static bool fl_engine_runs_task_on_current_thread(void *user_data)
Definition: fl_engine.cc:265
guint32 fl_renderer_get_fbo(FlRenderer *self)
Definition: fl_renderer.cc:120
FlutterTaskRunnerPostTaskCallback post_task_callback
Definition: embedder.h:930
G_MODULE_EXPORT FlBinaryMessenger * fl_engine_get_binary_messenger(FlEngine *self)
Definition: fl_engine.cc:789
size_t struct_size
This size of this struct. Must be sizeof(FlutterCompositor).
Definition: embedder.h:1126
FlutterEngineAOTDataSourceType type
Definition: embedder.h:1326
FlutterPointerSignalKind signal_kind
Definition: embedder.h:662
FlTaskRunner * task_runner
Definition: fl_engine.cc:38
GDestroyNotify platform_message_handler_destroy_notify
Definition: fl_engine.cc:46
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:795
void(* FlutterKeyEventCallback)(bool, void *)
Definition: embedder.h:748
FlutterEngineAOTData aot_data
Definition: embedder.h:1543
void fl_engine_set_update_semantics_node_handler(FlEngine *self, FlEngineUpdateSemanticsNodeHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_engine.cc:552
static uint32_t fl_engine_gl_get_fbo(void *user_data)
Definition: fl_engine.cc:202
static void fl_engine_platform_message_response_cb(const uint8_t *data, size_t data_length, void *user_data)
Definition: fl_engine.cc:326
gboolean fl_engine_send_platform_message_response(FlEngine *self, const FlutterPlatformMessageResponseHandle *handle, GBytes *response, GError **error)
Definition: fl_engine.cc:586
FlTexture * texture
FlutterPointerDeviceKind device_kind
Definition: embedder.h:672
return FALSE
ProcResolver gl_proc_resolver
Definition: embedder.h:424
size_t struct_size
The size of this struct. Must be sizeof(FlutterCustomTaskRunners).
Definition: embedder.h:938
gchar gchar gchar ** codeset
Definition: fl_engine.cc:73
G_MODULE_EXPORT FlTextureRegistrar * fl_engine_get_texture_registrar(FlEngine *self)
Definition: fl_engine.cc:805
size_t struct_size
The size of this struct. Must be sizeof(FlutterPlatformMessage).
Definition: embedder.h:757
FlBinaryMessenger * fl_binary_messenger_new(FlEngine *engine)
GBytes * fl_engine_send_platform_message_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:677
static void fl_engine_dispose(GObject *object)
Definition: fl_engine.cc:349
gchar gchar ** territory
Definition: fl_engine.cc:73
G_MODULE_EXPORT const gchar * fl_dart_project_get_assets_path(FlDartProject *self)
const char * language_code
Definition: embedder.h:1156
FlutterPointerPhase phase
Definition: embedder.h:650
G_DEFINE_QUARK(fl_binary_messenger_codec_error_quark, fl_binary_messenger_codec_error) G_DECLARE_FINAL_TYPE(FlBinaryMessengerImpl
gboolean fl_engine_register_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:775
G_MODULE_EXPORT GType fl_plugin_registry_get_type()
BoolCallback runs_task_on_current_thread_callback
Definition: embedder.h:919
GQuark fl_engine_error_quark(void) G_GNUC_CONST
int command_line_argc
The command line argument count used to initialize the project.
Definition: embedder.h:1380
const char * elf_path
Absolute path to an ELF library file.
Definition: embedder.h:1329
void(* FlEngineUpdateSemanticsNodeHandler)(FlEngine *engine, const FlutterSemanticsNode *node, gpointer user_data)
static bool compositor_present_layers_callback(const FlutterLayer **layers, size_t layers_count, void *user_data)
Definition: fl_engine.cc:167
static void * fl_engine_gl_proc_resolver(void *user_data, const char *name)
Definition: fl_engine.cc:177
gboolean fl_engine_unregister_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:782
static FlPluginRegistrar * fl_engine_get_registrar_for_plugin(FlPluginRegistry *registry, const gchar *name)
Definition: fl_engine.cc:335
void(* FlEngineOnPreEngineRestartHandler)(FlEngine *engine, gpointer user_data)
GObject parent_instance
Definition: fl_engine.cc:28
FlutterBackingStoreCreateCallback create_backing_store_callback
Definition: embedder.h:1139