Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
embedder.cc File Reference
#include <cstring>
#include <iostream>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "flutter/fml/build_config.h"
#include "flutter/fml/closure.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/status_or.h"
#include "flutter/fml/thread.h"
#include "third_party/dart/runtime/bin/elf_loader.h"
#include "third_party/dart/runtime/include/dart_native_api.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GpuTypes.h"
#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/common/graphics/persistent_cache.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/file.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_engine.h"
#include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h"
#include "flutter/shell/platform/embedder/embedder_platform_message_response.h"
#include "flutter/shell/platform/embedder/embedder_render_target.h"
#include "flutter/shell/platform/embedder/embedder_render_target_skia.h"
#include "flutter/shell/platform/embedder/embedder_semantics_update.h"
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
#include "flutter/shell/platform/embedder/embedder_task_runner.h"
#include "flutter/shell/platform/embedder/embedder_thread_host.h"
#include "flutter/shell/platform/embedder/pixel_formats.h"
#include "flutter/shell/platform/embedder/platform_view_embedder.h"
#include "rapidjson/rapidjson.h"
#include "rapidjson/writer.h"

Go to the source code of this file.

Classes

struct  _FlutterPlatformMessageResponseHandle
 
struct  LoadedElfDeleter
 
struct  _FlutterEngineAOTData
 

Macros

#define FML_USED_ON_EMBEDDER
 
#define RAPIDJSON_HAS_STDSTRING   1
 
#define FLUTTER_EXPORT   __attribute__((visibility("default")))
 
#define LOG_EMBEDDER_ERROR(code, reason)    LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)
 
#define SET_PROC(member, function)
 

Typedefs

using UniqueLoadedElf = std::unique_ptr< Dart_LoadedElf, LoadedElfDeleter >
 

Functions

static FlutterEngineResult LogEmbedderError (FlutterEngineResult code, const char *reason, const char *code_name, const char *function, const char *file, int line)
 
static bool IsOpenGLRendererConfigValid (const FlutterRendererConfig *config)
 
static bool IsSoftwareRendererConfigValid (const FlutterRendererConfig *config)
 
static bool IsMetalRendererConfigValid (const FlutterRendererConfig *config)
 
static bool IsVulkanRendererConfigValid (const FlutterRendererConfig *config)
 
static bool IsRendererValid (const FlutterRendererConfig *config)
 
static flutter::Shell::CreateCallback< flutter::PlatformViewInferOpenGLPlatformViewCreationCallback (const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
 
static flutter::Shell::CreateCallback< flutter::PlatformViewInferMetalPlatformViewCreationCallback (const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
 
static flutter::Shell::CreateCallback< flutter::PlatformViewInferVulkanPlatformViewCreationCallback (const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
 
static flutter::Shell::CreateCallback< flutter::PlatformViewInferSoftwarePlatformViewCreationCallback (const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
 
static flutter::Shell::CreateCallback< flutter::PlatformViewInferPlatformViewCreationCallback (const FlutterRendererConfig *config, void *user_data, const flutter::PlatformViewEmbedder::PlatformDispatchTable &platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder, bool enable_impeller)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLTexture *texture)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLFramebuffer *framebuffer)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLSurface *surface)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterSoftwareBackingStore *software)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterSoftwareBackingStore2 *software)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterMetalBackingStore *metal)
 
static std::unique_ptr< flutter::EmbedderRenderTargetMakeRenderTargetFromBackingStoreImpeller (FlutterBackingStore backing_store, const fml::closure &on_release, const std::shared_ptr< impeller::AiksContext > &aiks_context, const FlutterBackingStoreConfig &config, const FlutterOpenGLFramebuffer *framebuffer)
 
static std::unique_ptr< flutter::EmbedderRenderTargetMakeRenderTargetFromBackingStoreImpeller (FlutterBackingStore backing_store, const fml::closure &on_release, const std::shared_ptr< impeller::AiksContext > &aiks_context, const FlutterBackingStoreConfig &config, const FlutterMetalBackingStore *metal)
 
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore (GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterVulkanBackingStore *vulkan)
 
static std::unique_ptr< flutter::EmbedderRenderTargetMakeRenderTargetFromSkSurface (FlutterBackingStore backing_store, sk_sp< SkSurface > skia_surface, fml::closure on_release, flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback on_make_current, flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback on_clear_current)
 
static std::unique_ptr< flutter::EmbedderRenderTargetMakeRenderTargetFromSkSurface (FlutterBackingStore backing_store, sk_sp< SkSurface > skia_surface, fml::closure on_release)
 
static std::unique_ptr< flutter::EmbedderRenderTargetCreateEmbedderRenderTarget (const FlutterCompositor *compositor, const FlutterBackingStoreConfig &config, GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, bool enable_impeller)
 
static fml::StatusOr< std::unique_ptr< flutter::EmbedderExternalViewEmbedder > > InferExternalViewEmbedderFromArgs (const FlutterCompositor *compositor, bool enable_impeller)
 
static std::variant< flutter::ViewportMetrics, std::string > MakeViewportMetricsFromWindowMetrics (const FlutterWindowMetricsEvent *flutter_metrics)
 
FlutterEngineResult FlutterEngineCreateAOTData (const FlutterEngineAOTDataSource *source, FlutterEngineAOTData *data_out)
 Creates the necessary data structures to launch a Flutter Dart application in AOT mode. The data may only be collected after all FlutterEngine instances launched using this data have been terminated.
 
FlutterEngineResult FlutterEngineCollectAOTData (FlutterEngineAOTData data)
 Collects the AOT data.
 
void PopulateJITSnapshotMappingCallbacks (const FlutterProjectArgs *args, flutter::Settings &settings)
 
void PopulateAOTSnapshotMappingCallbacks (const FlutterProjectArgs *args, flutter::Settings &settings)
 
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV1 (FlutterUpdateSemanticsNodeCallback update_semantics_node_callback, FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback, void *user_data)
 
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV2 (FlutterUpdateSemanticsCallback update_semantics_callback, void *user_data)
 
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV3 (FlutterUpdateSemanticsCallback2 update_semantics_callback, void *user_data)
 
flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallback (const FlutterProjectArgs *args, void *user_data)
 
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 for the pair of calls to FlutterEngineInitialize and FlutterEngineRunInitialized.
 
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 FlutterEngineRunInitialized call is made. Besides Flutter application code, no tasks are scheduled on embedder managed task runners either. This allows embedders providing custom task runners to the Flutter engine to obtain a handle to the Flutter engine before the engine can post tasks on these task runners.
 
FlutterEngineResult FlutterEngineRunInitialized (FLUTTER_API_SYMBOL(FlutterEngine) engine)
 Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize. An initialized instance can only be run once. During and after this call, custom task runners supplied by the embedder are expected to start servicing tasks.
 
FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddView (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterAddViewInfo *info)
 Adds a view.
 
FLUTTER_EXPORT FlutterEngineResult FlutterEngineRemoveView (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterRemoveViewInfo *info)
 Removes a view.
 
FlutterEngineResult FlutterEngineSendViewFocusEvent (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterViewFocusEvent *event)
 Notifies the engine that platform view focus state has changed.
 
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 more calls to post tasks onto custom task runners specified by the embedder are made. The Flutter engine handle still needs to be collected via a call to FlutterEngineShutdown.
 
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 embedder API after this point. Making additional calls with this handle is undefined behavior.
 
FlutterEngineResult FlutterEngineSendWindowMetricsEvent (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
 
flutter::PointerData::Change ToPointerDataChange (FlutterPointerPhase phase)
 
flutter::PointerData::DeviceKind ToPointerDataKind (FlutterPointerDeviceKind device_kind)
 
flutter::PointerData::SignalKind ToPointerDataSignalKind (FlutterPointerSignalKind kind)
 
int64_t PointerDataButtonsForLegacyEvent (flutter::PointerData::Change change)
 
FlutterEngineResult FlutterEngineSendPointerEvent (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
 
static flutter::KeyEventType MapKeyEventType (FlutterKeyEventType event_kind)
 
static flutter::KeyEventDeviceType MapKeyEventDeviceType (FlutterKeyEventDeviceType event_kind)
 
static FlutterEngineResult InternalSendPlatformMessage (FLUTTER_API_SYMBOL(FlutterEngine) engine, const char *channel, const uint8_t *data, size_t size, FlutterDataCallback data_callback, void *user_data)
 
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 synchronous fashion, although due to technical limitation, the result is always reported asynchronously. The callback is guaranteed to be called exactly once.
 
FlutterEngineResult FlutterEngineSendPlatformMessage (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
 
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 response to a message. This handle may be set on the response_handle field of any FlutterPlatformMessage sent to the engine.
 
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle (FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
 Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
 
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.
 
FlutterEngineResult __FlutterEngineFlushPendingTasksNow ()
 This API is only meant to be used by platforms that need to flush tasks on a message loop not controlled by the Flutter engine.
 
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 support external textures accept external texture registrations. After the external texture is registered, the application can mark that a frame is available by calling FlutterEngineMarkExternalTextureFrameAvailable.
 
FlutterEngineResult FlutterEngineUnregisterExternalTexture (FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
 Unregister a previous texture registration.
 
FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable (FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
 Mark that a new texture frame is available for a given texture identifier.
 
FlutterEngineResult FlutterEngineUpdateSemanticsEnabled (FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled)
 Enable or disable accessibility semantics.
 
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures (FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterAccessibilityFeature flags)
 Sets additional accessibility features.
 
FlutterEngineResult FlutterEngineDispatchSemanticsAction (FLUTTER_API_SYMBOL(FlutterEngine) engine, uint64_t node_id, FlutterSemanticsAction action, const uint8_t *data, size_t data_length)
 Dispatch a semantics action to the specified semantics node in the implicit view.
 
FlutterEngineResult FlutterEngineSendSemanticsAction (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterSendSemanticsActionInfo *info)
 Dispatch a semantics action to the specified semantics node within a specific view.
 
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 must be returned. This call must be made on the thread on which the call to FlutterEngineRun was made.
 
FlutterEngineResult FlutterEngineReloadSystemFonts (FLUTTER_API_SYMBOL(FlutterEngine) engine)
 Reloads the system fonts in engine.
 
void FlutterEngineTraceEventDurationBegin (const char *name)
 A profiling utility. Logs a trace duration begin event to the timeline. If the timeline is unavailable or disabled, this has no effect. Must be balanced with an duration end event (via FlutterEngineTraceEventDurationEnd) with the same name on the same thread. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.
 
void FlutterEngineTraceEventDurationEnd (const char *name)
 A profiling utility. Logs a trace duration end event to the timeline. If the timeline is unavailable or disabled, this has no effect. This call must be preceded by a trace duration begin call (via FlutterEngineTraceEventDurationBegin) with the same name on the same thread. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.
 
void FlutterEngineTraceEventInstant (const char *name)
 A profiling utility. Logs a trace duration instant event to the timeline. If the timeline is unavailable or disabled, this has no effect. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.
 
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 a FlutterEngineShutdown on the specific engine has not already been initiated.
 
uint64_t FlutterEngineGetCurrentTime ()
 Get the current time in nanoseconds from the clock used by the flutter engine. This is the system monotonic clock.
 
FlutterEngineResult FlutterEngineRunTask (FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterTask *task)
 Inform the engine to run the specified task. This task has been given to the embedder via the FlutterTaskRunnerDescription.post_task_callback. This call must only be made at the target time specified in that callback. Running the task before that time is undefined behavior.
 
static bool DispatchJSONPlatformMessage (FLUTTER_API_SYMBOL(FlutterEngine) engine, const rapidjson::Document &document, const std::string &channel_name)
 
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 first item in the list of locales supplied. The other entries will be used as a fallback.
 
bool FlutterEngineRunsAOTCompiledDartCode (void)
 Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading restrictions.
 
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 any isolate running in the VM. This isolate can also be the root isolate for an unrelated engine. The engine parameter is necessary only to ensure the call is not made when no engine (and hence no VM) is running.
 
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 non-critical resources in response. It is not guaranteed that the resource would have been collected by the time this call returns however. The notification is posted to engine subsystems that may be operating on other threads.
 
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 callback the next time the message loop for each managed thread is idle. Since the engine manages the entire lifecycle of multiple threads, there is no opportunity for the embedders to finely tune the priorities of threads directly, or, perform other thread specific configuration (for example, setting thread names for tracing). This callback gives embedders a chance to affect such tuning.
 
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.
 
FlutterEngineResult FlutterEngineScheduleFrame (FLUTTER_API_SYMBOL(FlutterEngine) engine)
 Schedule a new frame to redraw the content.
 
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 thread. The callback is executed only once from the raster thread; embedders must re-thread if necessary. Performing blocking calls in this callback may introduce application jank.
 
FlutterEngineResult FlutterEngineGetProcAddresses (FlutterEngineProcTable *table)
 Gets the table of engine function pointers.
 

Variables

const uint8_t kPlatformStrongDill []
 
const intptr_t kPlatformStrongDillSize
 
const int32_t kFlutterSemanticsNodeIdBatchEnd = -1
 
const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1
 
static constexpr FlutterViewId kFlutterImplicitViewId = 0
 
const char * kFlutterKeyDataChannel = "flutter/keydata"
 

Macro Definition Documentation

◆ FLUTTER_EXPORT

#define FLUTTER_EXPORT   __attribute__((visibility("default")))

Definition at line 32 of file embedder.cc.

◆ FML_USED_ON_EMBEDDER

#define FML_USED_ON_EMBEDDER

Definition at line 5 of file embedder.cc.

◆ LOG_EMBEDDER_ERROR

#define LOG_EMBEDDER_ERROR (   code,
  reason 
)     LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)

Definition at line 155 of file embedder.cc.

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

◆ RAPIDJSON_HAS_STDSTRING

#define RAPIDJSON_HAS_STDSTRING   1

Definition at line 6 of file embedder.cc.

◆ SET_PROC

#define SET_PROC (   member,
  function 
)
Value:
if (STRUCT_HAS_MEMBER(table, member)) { \
table->member = &function; \
}
Dart_NativeFunction function
Definition fuchsia.cc:50

Typedef Documentation

◆ UniqueLoadedElf

using UniqueLoadedElf = std::unique_ptr<Dart_LoadedElf, LoadedElfDeleter>

Definition at line 1696 of file embedder.cc.

Function Documentation

◆ __FlutterEngineFlushPendingTasksNow()

FlutterEngineResult __FlutterEngineFlushPendingTasksNow ( )

This API is only meant to be used by platforms that need to flush tasks on a message loop not controlled by the Flutter engine.

Returns
The result of the call.

Definition at line 3130 of file embedder.cc.

3130 {
3132 return kSuccess;
3133}

References fml::MessageLoop::GetCurrent(), kSuccess, and fml::MessageLoop::RunExpiredTasksNow().

◆ CreateEmbedderRenderTarget()

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 
)
static

Definition at line 1380 of file embedder.cc.

1385 {
1386 FlutterBackingStore backing_store = {};
1387 backing_store.struct_size = sizeof(backing_store);
1388
1389 // Safe access checks on the compositor struct have been performed in
1390 // InferExternalViewEmbedderFromArgs and are not necessary here.
1391 auto c_create_callback = compositor->create_backing_store_callback;
1392 auto c_collect_callback = compositor->collect_backing_store_callback;
1393
1394 {
1395 TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
1396 if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
1397 FML_LOG(ERROR) << "Could not create the embedder backing store.";
1398 return nullptr;
1399 }
1400 }
1401
1402 if (backing_store.struct_size != sizeof(backing_store)) {
1403 FML_LOG(ERROR) << "Embedder modified the backing store struct size.";
1404 return nullptr;
1405 }
1406
1407 // In case we return early without creating an embedder render target, the
1408 // embedder has still given us ownership of its baton which we must return
1409 // back to it. If this method is successful, the closure is released when the
1410 // render target is eventually released.
1411 fml::ScopedCleanupClosure collect_callback(
1412 [c_collect_callback, backing_store, user_data = compositor->user_data]() {
1413 TRACE_EVENT0("flutter", "FlutterCompositorCollectBackingStore");
1414 c_collect_callback(&backing_store, user_data);
1415 });
1416
1417 // No safe access checks on the renderer are necessary since we allocated
1418 // the struct.
1419
1420 std::unique_ptr<flutter::EmbedderRenderTarget> render_target;
1421
1422 switch (backing_store.type) {
1424 switch (backing_store.open_gl.type) {
1426 auto skia_surface = MakeSkSurfaceFromBackingStore(
1427 context, config, &backing_store.open_gl.texture);
1428 render_target = MakeRenderTargetFromSkSurface(
1429 backing_store, std::move(skia_surface),
1430 collect_callback.Release());
1431 break;
1432 }
1434 if (enable_impeller) {
1436 backing_store, collect_callback.Release(), aiks_context, config,
1437 &backing_store.open_gl.framebuffer);
1438 break;
1439 } else {
1440 auto skia_surface = MakeSkSurfaceFromBackingStore(
1441 context, config, &backing_store.open_gl.framebuffer);
1442 render_target = MakeRenderTargetFromSkSurface(
1443 backing_store, std::move(skia_surface),
1444 collect_callback.Release());
1445 break;
1446 }
1447 }
1448
1450 auto on_make_current =
1452 context = backing_store.open_gl.surface.user_data]()
1454 bool invalidate_api_state = false;
1455 bool ok = callback(context, &invalidate_api_state);
1456 return {ok, invalidate_api_state};
1457 };
1458
1459 auto on_clear_current =
1461 context = backing_store.open_gl.surface.user_data]()
1463 bool invalidate_api_state = false;
1464 bool ok = callback(context, &invalidate_api_state);
1465 return {ok, invalidate_api_state};
1466 };
1467
1468 if (enable_impeller) {
1469 // TODO(https://github.com/flutter/flutter/issues/151670): Implement
1470 // GL Surface backing stores for Impeller.
1471 FML_LOG(ERROR) << "Unimplemented";
1472 break;
1473 } else {
1474 auto skia_surface = MakeSkSurfaceFromBackingStore(
1475 context, config, &backing_store.open_gl.surface);
1476
1477 render_target = MakeRenderTargetFromSkSurface(
1478 backing_store, std::move(skia_surface),
1479 collect_callback.Release(), on_make_current, on_clear_current);
1480 break;
1481 }
1482 }
1483 }
1484 break;
1485 }
1486
1488 auto skia_surface = MakeSkSurfaceFromBackingStore(
1489 context, config, &backing_store.software);
1490 render_target = MakeRenderTargetFromSkSurface(
1491 backing_store, std::move(skia_surface), collect_callback.Release());
1492 break;
1493 }
1495 auto skia_surface = MakeSkSurfaceFromBackingStore(
1496 context, config, &backing_store.software2);
1497 render_target = MakeRenderTargetFromSkSurface(
1498 backing_store, std::move(skia_surface), collect_callback.Release());
1499 break;
1500 }
1502 if (enable_impeller) {
1504 backing_store, collect_callback.Release(), aiks_context, config,
1505 &backing_store.metal);
1506 } else {
1507 auto skia_surface = MakeSkSurfaceFromBackingStore(context, config,
1508 &backing_store.metal);
1509 render_target = MakeRenderTargetFromSkSurface(
1510 backing_store, std::move(skia_surface), collect_callback.Release());
1511 }
1512 break;
1513 }
1515 if (enable_impeller) {
1516 FML_LOG(ERROR) << "Unimplemented";
1517 break;
1518 } else {
1519 auto skia_surface = MakeSkSurfaceFromBackingStore(
1520 context, config, &backing_store.vulkan);
1521 render_target = MakeRenderTargetFromSkSurface(
1522 backing_store, std::move(skia_surface), collect_callback.Release());
1523 break;
1524 }
1525 }
1526 };
1527
1528 if (!render_target) {
1529 FML_LOG(ERROR) << "Could not create a surface from an embedder provided "
1530 "render target.";
1531 }
1532 return render_target;
1533}

References callback, FlutterOpenGLSurface::clear_current_callback, FlutterCompositor::collect_backing_store_callback, FlutterCompositor::create_backing_store_callback, FML_LOG, FlutterOpenGLBackingStore::framebuffer, kFlutterBackingStoreTypeMetal, kFlutterBackingStoreTypeOpenGL, kFlutterBackingStoreTypeSoftware, kFlutterBackingStoreTypeSoftware2, kFlutterBackingStoreTypeVulkan, kFlutterOpenGLTargetTypeFramebuffer, kFlutterOpenGLTargetTypeSurface, kFlutterOpenGLTargetTypeTexture, FlutterOpenGLSurface::make_current_callback, MakeRenderTargetFromBackingStoreImpeller(), MakeRenderTargetFromSkSurface(), MakeSkSurfaceFromBackingStore(), FlutterBackingStore::metal, FlutterBackingStore::open_gl, fml::ScopedCleanupClosure::Release(), FlutterBackingStore::software, FlutterBackingStore::software2, FlutterBackingStore::struct_size, FlutterOpenGLBackingStore::surface, FlutterOpenGLBackingStore::texture, TRACE_EVENT0, FlutterOpenGLBackingStore::type, FlutterBackingStore::type, user_data, FlutterOpenGLSurface::user_data, FlutterCompositor::user_data, and FlutterBackingStore::vulkan.

Referenced by InferExternalViewEmbedderFromArgs().

◆ CreateEmbedderSemanticsUpdateCallback()

flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallback ( const FlutterProjectArgs args,
void *  user_data 
)

Definition at line 1949 of file embedder.cc.

1950 {
1951 // There are three variants for the embedder API's semantic update callbacks.
1952 // Create a callback that maps to the embedder's desired semantic update API.
1953 //
1954 // Handle the case where the embedder registered the callback
1955 // 'updated_semantics_callback2'
1956 if (SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr) {
1958 args->update_semantics_callback2, user_data);
1959 }
1960
1961 // Handle the case where the embedder registered the deprecated callback
1962 // 'update_semantics_callback'.
1963 if (SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr) {
1965 args->update_semantics_callback, user_data);
1966 }
1967
1968 // Handle the case where the embedder registered the deprecated callbacks
1969 // 'update_semantics_node_callback' and
1970 // 'update_semantics_custom_action_callback'.
1971 FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
1972 if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
1973 update_semantics_node_callback = args->update_semantics_node_callback;
1974 }
1975
1977 update_semantics_custom_action_callback = nullptr;
1978 if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
1979 nullptr) {
1980 update_semantics_custom_action_callback =
1981 args->update_semantics_custom_action_callback;
1982 }
1983
1984 if (update_semantics_node_callback != nullptr ||
1985 update_semantics_custom_action_callback != nullptr) {
1987 update_semantics_node_callback, update_semantics_custom_action_callback,
1988 user_data);
1989 }
1990
1991 // Handle the case where the embedder registered no callbacks.
1992 return nullptr;
1993}

References args, CreateEmbedderSemanticsUpdateCallbackV1(), CreateEmbedderSemanticsUpdateCallbackV2(), CreateEmbedderSemanticsUpdateCallbackV3(), SAFE_ACCESS, and user_data.

Referenced by FlutterEngineInitialize().

◆ CreateEmbedderSemanticsUpdateCallbackV1()

flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV1 ( FlutterUpdateSemanticsNodeCallback  update_semantics_node_callback,
FlutterUpdateSemanticsCustomActionCallback  update_semantics_custom_action_callback,
void *  user_data 
)

Definition at line 1869 of file embedder.cc.

1873 {
1874 return [update_semantics_node_callback,
1875 update_semantics_custom_action_callback, user_data](
1876 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1878 flutter::EmbedderSemanticsUpdate update{nodes, actions};
1879 FlutterSemanticsUpdate* update_ptr = update.get();
1880
1881 // First, queue all node and custom action updates.
1882 if (update_semantics_node_callback != nullptr) {
1883 for (size_t i = 0; i < update_ptr->nodes_count; i++) {
1884 update_semantics_node_callback(&update_ptr->nodes[i], user_data);
1885 }
1886 }
1887
1888 if (update_semantics_custom_action_callback != nullptr) {
1889 for (size_t i = 0; i < update_ptr->custom_actions_count; i++) {
1890 update_semantics_custom_action_callback(&update_ptr->custom_actions[i],
1891 user_data);
1892 }
1893 }
1894
1895 // Second, mark node and action batches completed now that all
1896 // updates are queued.
1897 if (update_semantics_node_callback != nullptr) {
1898 const FlutterSemanticsNode batch_end_sentinel = {
1899 sizeof(FlutterSemanticsNode),
1901 };
1902 update_semantics_node_callback(&batch_end_sentinel, user_data);
1903 }
1904
1905 if (update_semantics_custom_action_callback != nullptr) {
1906 const FlutterSemanticsCustomAction batch_end_sentinel = {
1909 };
1910 update_semantics_custom_action_callback(&batch_end_sentinel, user_data);
1911 }
1912 };
1913}

References FlutterSemanticsUpdate::custom_actions, FlutterSemanticsUpdate::custom_actions_count, i, kFlutterSemanticsCustomActionIdBatchEnd, kFlutterSemanticsNodeIdBatchEnd, FlutterSemanticsUpdate::nodes, FlutterSemanticsUpdate::nodes_count, user_data, and view_id.

Referenced by CreateEmbedderSemanticsUpdateCallback().

◆ CreateEmbedderSemanticsUpdateCallbackV2()

flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV2 ( FlutterUpdateSemanticsCallback  update_semantics_callback,
void *  user_data 
)

Definition at line 1918 of file embedder.cc.

1920 {
1921 return [update_semantics_callback, user_data](
1922 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1924 flutter::EmbedderSemanticsUpdate update{nodes, actions};
1925
1926 update_semantics_callback(update.get(), user_data);
1927 };
1928}

References user_data, and view_id.

Referenced by CreateEmbedderSemanticsUpdateCallback().

◆ CreateEmbedderSemanticsUpdateCallbackV3()

flutter::PlatformViewEmbedder::UpdateSemanticsCallback CreateEmbedderSemanticsUpdateCallbackV3 ( FlutterUpdateSemanticsCallback2  update_semantics_callback,
void *  user_data 
)

Definition at line 1933 of file embedder.cc.

1935 {
1936 return [update_semantics_callback, user_data](
1937 int64_t view_id, const flutter::SemanticsNodeUpdates& nodes,
1939 flutter::EmbedderSemanticsUpdate2 update{view_id, nodes, actions};
1940
1941 update_semantics_callback(update.get(), user_data);
1942 };
1943}

References user_data, and view_id.

Referenced by CreateEmbedderSemanticsUpdateCallback().

◆ DispatchJSONPlatformMessage()

static bool DispatchJSONPlatformMessage ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const rapidjson::Document &  document,
const std::string &  channel_name 
)
static

Definition at line 3358 of file embedder.cc.

3361 {
3362 if (channel_name.empty()) {
3363 return false;
3364 }
3365
3366 rapidjson::StringBuffer buffer;
3367 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
3368
3369 if (!document.Accept(writer)) {
3370 return false;
3371 }
3372
3373 const char* message = buffer.GetString();
3374
3375 if (message == nullptr || buffer.GetSize() == 0) {
3376 return false;
3377 }
3378
3379 auto platform_message = std::make_unique<flutter::PlatformMessage>(
3380 channel_name.c_str(), // channel
3382 buffer.GetSize()), // message
3383 nullptr // response
3384 );
3385
3386 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3387 ->SendPlatformMessage(std::move(platform_message));
3388}

References fml::MallocMapping::Copy(), engine, and message.

Referenced by FlutterEngineNotifyLowMemoryWarning(), and FlutterEngineUpdateLocales().

◆ FlutterEngineAddView()

FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddView ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterAddViewInfo info 
)

Adds a view.

        This is an asynchronous operation. The view should not be used
        until the |info.add_view_callback| is invoked with an |added|
        value of true. The embedder should prepare resources in advance
        but be ready to clean up on failure.

        A frame is scheduled if the operation succeeds.

        The callback is invoked on a thread managed by the engine. The
        embedder should re-thread if needed.

        Attempting to add the implicit view will fail and will return
        kInvalidArguments. Attempting to add a view with an already
        existing view ID will fail, and |info.add_view_callback| will be
        invoked with an |added| value of false.
Parameters
[in]engineA running engine instance.
[in]infoThe add view arguments. This can be deallocated once |FlutterEngineAddView| returns, before |add_view_callback| is invoked.
Returns
The result of starting the asynchronous operation. If kSuccess, the |add_view_callback| will be invoked.

Definition at line 2525 of file embedder.cc.

2527 {
2528 if (!engine) {
2529 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2530 }
2531 if (!info || !info->view_metrics || !info->add_view_callback) {
2533 "Add view info handle was invalid.");
2534 }
2535
2538 return LOG_EMBEDDER_ERROR(
2540 "Add view info was invalid. The implicit view cannot be added.");
2541 }
2543 view_id) {
2546 "Add view info was invalid. The info and "
2547 "window metric view IDs must match.");
2548 }
2549 }
2550
2551 // TODO(loicsharma): Return an error if the engine was initialized with
2552 // callbacks that are incompatible with multiple views.
2553 // https://github.com/flutter/flutter/issues/144806
2554
2555 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2557
2558 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2559 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2560 }
2561
2562 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2563
2564 // The engine must be running to add a view.
2565 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2566 if (!embedder_engine->IsValid()) {
2567 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2568 }
2569
2571 [c_callback = info->add_view_callback,
2572 user_data = info->user_data](bool added) {
2573 FlutterAddViewResult result = {};
2574 result.struct_size = sizeof(FlutterAddViewResult);
2575 result.added = added;
2576 result.user_data = user_data;
2577 c_callback(&result);
2578 };
2579
2580 embedder_engine->GetShell().GetPlatformView()->AddView(view_id, metrics,
2581 callback);
2582 return kSuccess;
2583}

References FlutterAddViewInfo::add_view_callback, FlutterAddViewResult::added, callback, engine, error, kFlutterImplicitViewId, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, MakeViewportMetricsFromWindowMetrics(), SAFE_ACCESS, FlutterAddViewResult::struct_size, user_data, FlutterAddViewResult::user_data, FlutterAddViewInfo::user_data, FlutterAddViewInfo::view_id, view_id, and FlutterAddViewInfo::view_metrics.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineCollectAOTData()

FlutterEngineResult FlutterEngineCollectAOTData ( FlutterEngineAOTData  data)

Collects the AOT data.

Warning
The embedder must ensure that this call is made only after all FlutterEngine instances launched using this data have been terminated, and that all of those instances were launched with the FlutterProjectArgs::shutdown_dart_vm_when_done flag set to true.
Parameters
[in]dataThe data to collect.
Returns
Returns if the AOT data was successfully collected.

Definition at line 1760 of file embedder.cc.

1760 {
1761 if (!data) {
1762 // Deleting a null object should be a no-op.
1763 return kSuccess;
1764 }
1765
1766 // Created in a unique pointer in `FlutterEngineCreateAOTData`.
1767 delete data;
1768 return kSuccess;
1769}

References data, and kSuccess.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::AOTDataDeleter::operator()(), AOTDataDeleter::operator()(), and flutter::testing::TEST_F().

◆ FlutterEngineCreateAOTData()

FlutterEngineResult FlutterEngineCreateAOTData ( const FlutterEngineAOTDataSource source,
FlutterEngineAOTData data_out 
)

Creates the necessary data structures to launch a Flutter Dart application in AOT mode. The data may only be collected after all FlutterEngine instances launched using this data have been terminated.

Parameters
[in]sourceThe source of the AOT data.
[out]data_outThe AOT data on success. Unchanged on failure.
Returns
Returns if the AOT data could be successfully resolved.

Definition at line 1706 of file embedder.cc.

1708 {
1711 "AOT data can only be created in AOT mode.");
1712 } else if (!source) {
1713 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null source specified.");
1714 } else if (!data_out) {
1715 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null data_out specified.");
1716 }
1717
1718 switch (source->type) {
1720 if (!source->elf_path || !fml::IsFile(source->elf_path)) {
1722 "Invalid ELF path specified.");
1723 }
1724
1725 auto aot_data = std::make_unique<_FlutterEngineAOTData>();
1726 const char* error = nullptr;
1727
1728#if OS_FUCHSIA
1729 // TODO(gw280): https://github.com/flutter/flutter/issues/50285
1730 // Dart doesn't implement Dart_LoadELF on Fuchsia
1731 Dart_LoadedElf* loaded_elf = nullptr;
1732#else
1733 Dart_LoadedElf* loaded_elf = Dart_LoadELF(
1734 source->elf_path, // file path
1735 0, // file offset
1736 &error, // error (out)
1737 &aot_data->vm_snapshot_data, // vm snapshot data (out)
1738 &aot_data->vm_snapshot_instrs, // vm snapshot instr (out)
1739 &aot_data->vm_isolate_data, // vm isolate data (out)
1740 &aot_data->vm_isolate_instrs // vm isolate instr (out)
1741 );
1742#endif
1743
1744 if (loaded_elf == nullptr) {
1746 }
1747
1748 aot_data->loaded_elf.reset(loaded_elf);
1749
1750 *data_out = aot_data.release();
1751 return kSuccess;
1752 }
1753 }
1754
1755 return LOG_EMBEDDER_ERROR(
1757 "Invalid FlutterEngineAOTDataSourceType type specified.");
1758}

References FlutterEngineAOTDataSource::elf_path, error, fml::IsFile(), flutter::DartVM::IsRunningPrecompiledCode(), kFlutterEngineAOTDataSourceTypeElfPath, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and FlutterEngineAOTDataSource::type.

Referenced by FlutterEngineGetProcAddresses(), LoadAotData(), flutter::testing::EmbedderTestContext::SetupAOTDataIfNecessary(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineDeinitialize()

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 more calls to post tasks onto custom task runners specified by the embedder are made. The Flutter engine handle still needs to be collected via a call to FlutterEngineShutdown.

Parameters
[in]engineThe running engine instance to de-initialize.
Returns
The result of the call to de-initialize the Flutter engine.

Definition at line 2661 of file embedder.cc.

2662 {
2663 if (engine == nullptr) {
2664 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2665 }
2666
2667 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2668 embedder_engine->NotifyDestroyed();
2669 embedder_engine->CollectShell();
2670 embedder_engine->CollectThreadHost();
2671 return kSuccess;
2672}

References engine, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and flutter::EmbedderEngine::NotifyDestroyed().

Referenced by FlutterEngineGetProcAddresses(), FlutterEngineShutdown(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_P().

◆ FlutterEngineDispatchSemanticsAction()

FlutterEngineResult FlutterEngineDispatchSemanticsAction ( FLUTTER_API_SYMBOL(FlutterEngine engine,
uint64_t  node_id,
FlutterSemanticsAction  action,
const uint8_t *  data,
size_t  data_length 
)

Dispatch a semantics action to the specified semantics node in the implicit view.

Parameters
[in]engineA running engine instance.
[in]node_idThe semantics node identifier.
[in]actionThe semantics action.
[in]dataData associated with the action.
[in]data_lengthThe data length.
Returns
The result of the call.

Definition at line 3221 of file embedder.cc.

3226 {
3230 .node_id = node_id,
3231 .action = action,
3232 .data = data,
3233 .data_length = data_length};
3235}

References action, data, engine, FlutterEngineSendSemanticsAction(), kFlutterImplicitViewId, FlutterSendSemanticsActionInfo::struct_size, and view_id.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineGetCurrentTime()

uint64_t FlutterEngineGetCurrentTime ( )

Get the current time in nanoseconds from the clock used by the flutter engine. This is the system monotonic clock.

Returns
The current time in nanoseconds.

Definition at line 3334 of file embedder.cc.

3334 {
3336}

References fml::TimePoint::Now(), fml::TimePoint::ToEpochDelta(), and fml::TimeDelta::ToNanoseconds().

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST(), and flutter::EventLoop::TimePointFromFlutterTime().

◆ FlutterEngineGetProcAddresses()

FlutterEngineResult FlutterEngineGetProcAddresses ( FlutterEngineProcTable table)

Gets the table of engine function pointers.

Parameters
[out]tableThe table to fill with pointers. This should be zero-initialized, except for struct_size.
Returns
Returns whether the table was successfully populated.

Definition at line 3721 of file embedder.cc.

3722 {
3723 if (!table) {
3724 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null table specified.");
3725 }
3726#define SET_PROC(member, function) \
3727 if (STRUCT_HAS_MEMBER(table, member)) { \
3728 table->member = &function; \
3729 }
3730
3731 SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
3732 SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
3735 SET_PROC(Initialize, FlutterEngineInitialize);
3736 SET_PROC(Deinitialize, FlutterEngineDeinitialize);
3737 SET_PROC(RunInitialized, FlutterEngineRunInitialized);
3738 SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent);
3739 SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent);
3740 SET_PROC(SendKeyEvent, FlutterEngineSendKeyEvent);
3741 SET_PROC(SendPlatformMessage, FlutterEngineSendPlatformMessage);
3742 SET_PROC(PlatformMessageCreateResponseHandle,
3744 SET_PROC(PlatformMessageReleaseResponseHandle,
3746 SET_PROC(SendPlatformMessageResponse,
3748 SET_PROC(RegisterExternalTexture, FlutterEngineRegisterExternalTexture);
3749 SET_PROC(UnregisterExternalTexture, FlutterEngineUnregisterExternalTexture);
3750 SET_PROC(MarkExternalTextureFrameAvailable,
3752 SET_PROC(UpdateSemanticsEnabled, FlutterEngineUpdateSemanticsEnabled);
3753 SET_PROC(UpdateAccessibilityFeatures,
3755 SET_PROC(DispatchSemanticsAction, FlutterEngineDispatchSemanticsAction);
3756 SET_PROC(SendSemanticsAction, FlutterEngineSendSemanticsAction);
3758 SET_PROC(ReloadSystemFonts, FlutterEngineReloadSystemFonts);
3759 SET_PROC(TraceEventDurationBegin, FlutterEngineTraceEventDurationBegin);
3760 SET_PROC(TraceEventDurationEnd, FlutterEngineTraceEventDurationEnd);
3761 SET_PROC(TraceEventInstant, FlutterEngineTraceEventInstant);
3762 SET_PROC(PostRenderThreadTask, FlutterEnginePostRenderThreadTask);
3765 SET_PROC(UpdateLocales, FlutterEngineUpdateLocales);
3766 SET_PROC(RunsAOTCompiledDartCode, FlutterEngineRunsAOTCompiledDartCode);
3767 SET_PROC(PostDartObject, FlutterEnginePostDartObject);
3768 SET_PROC(NotifyLowMemoryWarning, FlutterEngineNotifyLowMemoryWarning);
3769 SET_PROC(PostCallbackOnAllNativeThreads,
3771 SET_PROC(NotifyDisplayUpdate, FlutterEngineNotifyDisplayUpdate);
3772 SET_PROC(ScheduleFrame, FlutterEngineScheduleFrame);
3773 SET_PROC(SetNextFrameCallback, FlutterEngineSetNextFrameCallback);
3775 SET_PROC(RemoveView, FlutterEngineRemoveView);
3776 SET_PROC(SendViewFocusEvent, FlutterEngineSendViewFocusEvent);
3777#undef SET_PROC
3778
3779 return kSuccess;
3780}

References FlutterEngineAddView(), FlutterEngineCollectAOTData(), FlutterEngineCreateAOTData(), FlutterEngineDeinitialize(), FlutterEngineDispatchSemanticsAction(), FlutterEngineGetCurrentTime(), FlutterEngineInitialize(), FlutterEngineMarkExternalTextureFrameAvailable(), FlutterEngineNotifyDisplayUpdate(), FlutterEngineNotifyLowMemoryWarning(), FlutterEngineOnVsync(), FlutterEnginePostCallbackOnAllNativeThreads(), FlutterEnginePostDartObject(), FlutterEnginePostRenderThreadTask(), FlutterEngineRegisterExternalTexture(), FlutterEngineReloadSystemFonts(), FlutterEngineRemoveView(), FlutterEngineRun(), FlutterEngineRunInitialized(), FlutterEngineRunsAOTCompiledDartCode(), FlutterEngineRunTask(), FlutterEngineScheduleFrame(), FlutterEngineSendKeyEvent(), FlutterEngineSendPlatformMessage(), FlutterEngineSendPlatformMessageResponse(), FlutterEngineSendPointerEvent(), FlutterEngineSendSemanticsAction(), FlutterEngineSendViewFocusEvent(), FlutterEngineSendWindowMetricsEvent(), FlutterEngineSetNextFrameCallback(), FlutterEngineShutdown(), FlutterEngineTraceEventDurationBegin(), FlutterEngineTraceEventDurationEnd(), FlutterEngineTraceEventInstant(), FlutterEngineUnregisterExternalTexture(), FlutterEngineUpdateAccessibilityFeatures(), FlutterEngineUpdateLocales(), FlutterEngineUpdateSemanticsEnabled(), FlutterPlatformMessageCreateResponseHandle(), FlutterPlatformMessageReleaseResponseHandle(), GetCurrentTime, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and SET_PROC.

Referenced by fl_engine_init(), flutter::FlutterWindowsEngine::FlutterWindowsEngine(), flutter::testing::TEST(), flutter::testing::TEST(), and flutter::testing::TEST().

◆ FlutterEngineInitialize()

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 FlutterEngineRunInitialized call is made. Besides Flutter application code, no tasks are scheduled on embedder managed task runners either. This allows embedders providing custom task runners to the Flutter engine to obtain a handle to the Flutter engine before the engine can post tasks on these task runners.

Parameters
[in]versionThe Flutter embedder API version. Must be FLUTTER_ENGINE_VERSION.
[in]configThe renderer configuration.
[in]argsThe Flutter project arguments.
user_dataA user data baton passed back to embedders in callbacks.
[out]engine_outThe engine handle on successful engine creation.
Returns
The result of the call to initialize the Flutter engine.

Definition at line 2011 of file embedder.cc.

2016 {
2017 // Step 0: Figure out arguments for shell creation.
2018 if (version != FLUTTER_ENGINE_VERSION) {
2019 return LOG_EMBEDDER_ERROR(
2021 "Flutter embedder version mismatch. There has been a breaking change. "
2022 "Please consult the changelog and update the embedder.");
2023 }
2024
2025 if (engine_out == nullptr) {
2027 "The engine out parameter was missing.");
2028 }
2029
2030 if (args == nullptr) {
2032 "The Flutter project arguments were missing.");
2033 }
2034
2035 if (SAFE_ACCESS(args, assets_path, nullptr) == nullptr) {
2036 return LOG_EMBEDDER_ERROR(
2038 "The assets path in the Flutter project arguments was missing.");
2039 }
2040
2041 if (SAFE_ACCESS(args, main_path__unused__, nullptr) != nullptr) {
2042 FML_LOG(WARNING)
2043 << "FlutterProjectArgs.main_path is deprecated and should be set null.";
2044 }
2045
2046 if (SAFE_ACCESS(args, packages_path__unused__, nullptr) != nullptr) {
2047 FML_LOG(WARNING) << "FlutterProjectArgs.packages_path is deprecated and "
2048 "should be set null.";
2049 }
2050
2051 if (!IsRendererValid(config)) {
2053 "The renderer configuration was invalid.");
2054 }
2055
2056 std::string icu_data_path;
2057 if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
2058 icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
2059 }
2060
2061#if !SLIMPELLER
2062 if (SAFE_ACCESS(args, persistent_cache_path, nullptr) != nullptr) {
2063 std::string persistent_cache_path =
2064 SAFE_ACCESS(args, persistent_cache_path, nullptr);
2066 }
2067
2068 if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) {
2070 }
2071#endif // !SLIMPELLER
2072
2073 fml::CommandLine command_line;
2074 if (SAFE_ACCESS(args, command_line_argc, 0) != 0 &&
2075 SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) {
2076 command_line = fml::CommandLineFromArgcArgv(
2077 SAFE_ACCESS(args, command_line_argc, 0),
2078 SAFE_ACCESS(args, command_line_argv, nullptr));
2079 }
2080
2081 flutter::Settings settings = flutter::SettingsFromCommandLine(command_line);
2082
2083 if (SAFE_ACCESS(args, aot_data, nullptr)) {
2084 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) ||
2085 SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) ||
2086 SAFE_ACCESS(args, isolate_snapshot_data, nullptr) ||
2087 SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr)) {
2088 return LOG_EMBEDDER_ERROR(
2090 "Multiple AOT sources specified. Embedders should provide either "
2091 "*_snapshot_* buffers or aot_data, not both.");
2092 }
2093 }
2094
2097 } else {
2099 }
2100
2101 settings.icu_data_path = icu_data_path;
2102 settings.assets_path = args->assets_path;
2103 settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false);
2104 settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1);
2105 settings.enable_wide_gamut = SAFE_ACCESS(args, enable_wide_gamut, false);
2106
2108 // Verify the assets path contains Dart 2 kernel assets.
2109 const std::string kApplicationKernelSnapshotFileName = "kernel_blob.bin";
2110 std::string application_kernel_path = fml::paths::JoinPaths(
2112 if (!fml::IsFile(application_kernel_path)) {
2113 return LOG_EMBEDDER_ERROR(
2115 "Not running in AOT mode but could not resolve the kernel binary.");
2116 }
2118 }
2119
2120 if (SAFE_ACCESS(args, root_isolate_create_callback, nullptr) != nullptr) {
2122 SAFE_ACCESS(args, root_isolate_create_callback, nullptr);
2124 [callback, user_data](const auto& isolate) { callback(user_data); };
2125 }
2126
2127 // Wire up callback for engine and print logging.
2128 if (SAFE_ACCESS(args, log_message_callback, nullptr) != nullptr) {
2130 SAFE_ACCESS(args, log_message_callback, nullptr);
2132 const std::string& tag,
2133 const std::string& message) {
2134 callback(tag.c_str(), message.c_str(), user_data);
2135 };
2136 } else {
2137 settings.log_message_callback = [](const std::string& tag,
2138 const std::string& message) {
2139 // Fall back to logging to stdout if unspecified.
2140 if (tag.empty()) {
2141 std::cout << tag << ": ";
2142 }
2143 std::cout << message << std::endl;
2144 };
2145 }
2146
2147 if (SAFE_ACCESS(args, log_tag, nullptr) != nullptr) {
2148 settings.log_tag = SAFE_ACCESS(args, log_tag, nullptr);
2149 }
2150
2151 bool has_update_semantics_2_callback =
2152 SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr;
2153 bool has_update_semantics_callback =
2154 SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr;
2155 bool has_legacy_update_semantics_callback =
2156 SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr ||
2157 SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
2158 nullptr;
2159
2160 int semantic_callback_count = (has_update_semantics_2_callback ? 1 : 0) +
2161 (has_update_semantics_callback ? 1 : 0) +
2162 (has_legacy_update_semantics_callback ? 1 : 0);
2163
2164 if (semantic_callback_count > 1) {
2165 return LOG_EMBEDDER_ERROR(
2167 "Multiple semantics update callbacks provided. "
2168 "Embedders should provide either `update_semantics_callback2`, "
2169 "`update_semantics_callback`, or both "
2170 "`update_semantics_node_callback` and "
2171 "`update_semantics_custom_action_callback`.");
2172 }
2173
2175 update_semantics_callback =
2177
2179 platform_message_response_callback = nullptr;
2180 if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
2181 platform_message_response_callback =
2182 [ptr = args->platform_message_callback,
2183 user_data](std::unique_ptr<flutter::PlatformMessage> message) {
2184 auto handle = new FlutterPlatformMessageResponseHandle();
2185 const FlutterPlatformMessage incoming_message = {
2186 sizeof(FlutterPlatformMessage), // struct_size
2187 message->channel().c_str(), // channel
2188 message->data().GetMapping(), // message
2189 message->data().GetSize(), // message_size
2190 handle, // response_handle
2191 };
2192 handle->message = std::move(message);
2193 return ptr(&incoming_message, user_data);
2194 };
2195 }
2196
2197 flutter::VsyncWaiterEmbedder::VsyncCallback vsync_callback = nullptr;
2198 if (SAFE_ACCESS(args, vsync_callback, nullptr) != nullptr) {
2199 vsync_callback = [ptr = args->vsync_callback, user_data](intptr_t baton) {
2200 return ptr(user_data, baton);
2201 };
2202 }
2203
2205 compute_platform_resolved_locale_callback = nullptr;
2206 if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
2207 nullptr) {
2208 compute_platform_resolved_locale_callback =
2209 [ptr = args->compute_platform_resolved_locale_callback](
2210 const std::vector<std::string>& supported_locales_data) {
2211 const size_t number_of_strings_per_locale = 3;
2212 size_t locale_count =
2213 supported_locales_data.size() / number_of_strings_per_locale;
2214 std::vector<FlutterLocale> supported_locales;
2215 std::vector<const FlutterLocale*> supported_locales_ptr;
2216 for (size_t i = 0; i < locale_count; ++i) {
2217 supported_locales.push_back(
2218 {.struct_size = sizeof(FlutterLocale),
2219 .language_code =
2220 supported_locales_data[i * number_of_strings_per_locale +
2221 0]
2222 .c_str(),
2223 .country_code =
2224 supported_locales_data[i * number_of_strings_per_locale +
2225 1]
2226 .c_str(),
2227 .script_code =
2228 supported_locales_data[i * number_of_strings_per_locale +
2229 2]
2230 .c_str(),
2231 .variant_code = nullptr});
2232 supported_locales_ptr.push_back(&supported_locales[i]);
2233 }
2234
2235 const FlutterLocale* result =
2236 ptr(supported_locales_ptr.data(), locale_count);
2237
2238 std::unique_ptr<std::vector<std::string>> out =
2239 std::make_unique<std::vector<std::string>>();
2240 if (result) {
2241 std::string language_code(SAFE_ACCESS(result, language_code, ""));
2242 if (language_code != "") {
2243 out->push_back(language_code);
2244 out->emplace_back(SAFE_ACCESS(result, country_code, ""));
2245 out->emplace_back(SAFE_ACCESS(result, script_code, ""));
2246 }
2247 }
2248 return out;
2249 };
2250 }
2251
2253 on_pre_engine_restart_callback = nullptr;
2254 if (SAFE_ACCESS(args, on_pre_engine_restart_callback, nullptr) != nullptr) {
2255 on_pre_engine_restart_callback = [ptr =
2256 args->on_pre_engine_restart_callback,
2257 user_data]() { return ptr(user_data); };
2258 }
2259
2261 nullptr;
2262 if (SAFE_ACCESS(args, channel_update_callback, nullptr) != nullptr) {
2263 channel_update_callback = [ptr = args->channel_update_callback, user_data](
2264 const std::string& name, bool listening) {
2265 FlutterChannelUpdate update{sizeof(FlutterChannelUpdate), name.c_str(),
2266 listening};
2267 ptr(&update, user_data);
2268 };
2269 }
2270
2272 view_focus_change_request_callback = nullptr;
2273 if (SAFE_ACCESS(args, view_focus_change_request_callback, nullptr) !=
2274 nullptr) {
2275 view_focus_change_request_callback =
2276 [ptr = args->view_focus_change_request_callback,
2278 FlutterViewFocusChangeRequest embedder_request{
2280 .view_id = request.view_id(),
2281 .state = static_cast<FlutterViewFocusState>(request.state()),
2282 .direction =
2283 static_cast<FlutterViewFocusDirection>(request.direction()),
2284 };
2285 ptr(&embedder_request, user_data);
2286 };
2287 }
2288
2289 auto external_view_embedder_result = InferExternalViewEmbedderFromArgs(
2290 SAFE_ACCESS(args, compositor, nullptr), settings.enable_impeller);
2291 if (!external_view_embedder_result.ok()) {
2292 FML_LOG(ERROR) << external_view_embedder_result.status().message();
2294 "Compositor arguments were invalid.");
2295 }
2296
2298 {
2299 update_semantics_callback, //
2300 platform_message_response_callback, //
2301 vsync_callback, //
2302 compute_platform_resolved_locale_callback, //
2303 on_pre_engine_restart_callback, //
2304 channel_update_callback, //
2305 view_focus_change_request_callback, //
2306 };
2307
2308 auto on_create_platform_view = InferPlatformViewCreationCallback(
2309 config, user_data, platform_dispatch_table,
2310 std::move(external_view_embedder_result.value()),
2311 settings.enable_impeller);
2312
2313 if (!on_create_platform_view) {
2314 return LOG_EMBEDDER_ERROR(
2316 "Could not infer platform view creation callback.");
2317 }
2318
2320 [](flutter::Shell& shell) {
2321 return std::make_unique<flutter::Rasterizer>(shell);
2322 };
2323
2324 using ExternalTextureResolver = flutter::EmbedderExternalTextureResolver;
2325 std::unique_ptr<ExternalTextureResolver> external_texture_resolver;
2326 external_texture_resolver = std::make_unique<ExternalTextureResolver>();
2327
2328#ifdef SHELL_ENABLE_GL
2330 external_texture_callback;
2331 if (config->type == kOpenGL) {
2332 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
2333 if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
2334 nullptr) != nullptr) {
2335 external_texture_callback =
2336 [ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
2337 int64_t texture_identifier, size_t width,
2338 size_t height) -> std::unique_ptr<FlutterOpenGLTexture> {
2339 std::unique_ptr<FlutterOpenGLTexture> texture =
2340 std::make_unique<FlutterOpenGLTexture>();
2341 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2342 return nullptr;
2343 }
2344 return texture;
2345 };
2346 external_texture_resolver =
2347 std::make_unique<ExternalTextureResolver>(external_texture_callback);
2348 }
2349 }
2350#endif
2351#ifdef SHELL_ENABLE_METAL
2353 external_texture_metal_callback;
2354 if (config->type == kMetal) {
2355 const FlutterMetalRendererConfig* metal_config = &config->metal;
2356 if (SAFE_ACCESS(metal_config, external_texture_frame_callback, nullptr)) {
2357 external_texture_metal_callback =
2358 [ptr = metal_config->external_texture_frame_callback, user_data](
2359 int64_t texture_identifier, size_t width,
2360 size_t height) -> std::unique_ptr<FlutterMetalExternalTexture> {
2361 std::unique_ptr<FlutterMetalExternalTexture> texture =
2362 std::make_unique<FlutterMetalExternalTexture>();
2363 texture->struct_size = sizeof(FlutterMetalExternalTexture);
2364 if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2365 return nullptr;
2366 }
2367 return texture;
2368 };
2369 external_texture_resolver = std::make_unique<ExternalTextureResolver>(
2370 external_texture_metal_callback);
2371 }
2372 }
2373#endif
2374 auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr);
2375 auto thread_config_callback = [&custom_task_runners](
2376 const fml::Thread::ThreadConfig& config) {
2378 if (!custom_task_runners || !custom_task_runners->thread_priority_setter) {
2379 return;
2380 }
2382 switch (config.priority) {
2385 break;
2388 break;
2391 break;
2394 break;
2395 }
2396 custom_task_runners->thread_priority_setter(priority);
2397 };
2398 auto thread_host =
2400 custom_task_runners, thread_config_callback);
2401
2402 if (!thread_host || !thread_host->IsValid()) {
2404 "Could not set up or infer thread configuration "
2405 "to run the Flutter engine on.");
2406 }
2407
2408 auto task_runners = thread_host->GetTaskRunners();
2409
2410 if (!task_runners.IsValid()) {
2412 "Task runner configuration was invalid.");
2413 }
2414
2415 // Embedder supplied UI task runner runner does not have a message loop.
2416 bool has_ui_thread_message_loop =
2417 task_runners.GetUITaskRunner()->GetTaskQueueId().is_valid();
2418 // Message loop observers are used to flush the microtask queue.
2419 // If there is no message loop the queue is flushed from
2420 // EmbedderEngine::RunTask.
2421 settings.task_observer_add = [has_ui_thread_message_loop](
2422 intptr_t key, const fml::closure& callback) {
2423 if (has_ui_thread_message_loop) {
2425 }
2427 };
2428 settings.task_observer_remove = [has_ui_thread_message_loop](
2429 fml::TaskQueueId queue_id, intptr_t key) {
2430 if (has_ui_thread_message_loop) {
2432 }
2433 };
2434
2435 auto run_configuration =
2437
2438 if (SAFE_ACCESS(args, custom_dart_entrypoint, nullptr) != nullptr) {
2439 auto dart_entrypoint = std::string{args->custom_dart_entrypoint};
2440 if (!dart_entrypoint.empty()) {
2441 run_configuration.SetEntrypoint(std::move(dart_entrypoint));
2442 }
2443 }
2444
2445 if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
2446 if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
2448 "Could not determine Dart entrypoint arguments "
2449 "as dart_entrypoint_argc "
2450 "was set, but dart_entrypoint_argv was null.");
2451 }
2452 std::vector<std::string> arguments(args->dart_entrypoint_argc);
2453 for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
2454 arguments[i] = std::string{args->dart_entrypoint_argv[i]};
2455 }
2456 run_configuration.SetEntrypointArgs(std::move(arguments));
2457 }
2458
2459 if (SAFE_ACCESS(args, engine_id, 0) != 0) {
2460 run_configuration.SetEngineId(args->engine_id);
2461 }
2462
2463 if (!run_configuration.IsValid()) {
2464 return LOG_EMBEDDER_ERROR(
2466 "Could not infer the Flutter project to run from given arguments.");
2467 }
2468
2469 // Create the engine but don't launch the shell or run the root isolate.
2470 auto embedder_engine = std::make_unique<flutter::EmbedderEngine>(
2471 std::move(thread_host), //
2472 std::move(task_runners), //
2473 std::move(settings), //
2474 std::move(run_configuration), //
2475 on_create_platform_view, //
2476 on_create_rasterizer, //
2477 std::move(external_texture_resolver) //
2478 );
2479
2480 // Release the ownership of the embedder engine to the caller.
2481 *engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(
2482 embedder_engine.release());
2483 return kSuccess;
2484}

References fml::MessageLoop::AddTaskObserver(), flutter::Settings::application_kernel_asset, args, flutter::Settings::assets_path, callback, FlutterPlatformMessage::channel, fml::CommandLineFromArgcArgv(), flutter::EmbedderThreadHost::CreateEmbedderOrEngineManagedThreadHost(), CreateEmbedderSemanticsUpdateCallback(), flutter::Settings::enable_impeller, flutter::Settings::enable_wide_gamut, FlutterMetalRendererConfig::external_texture_frame_callback, FLUTTER_API_SYMBOL, FLUTTER_ENGINE_VERSION, FML_LOG, fml::MessageLoop::GetCurrent(), flutter::PersistentCache::gIsReadOnly, FlutterOpenGLRendererConfig::gl_external_texture_frame_callback, height, i, flutter::Settings::icu_data_path, InferExternalViewEmbedderFromArgs(), flutter::RunConfiguration::InferFromSettings(), InferPlatformViewCreationCallback(), fml::TaskQueueId::Invalid(), fml::IsFile(), IsRendererValid(), flutter::DartVM::IsRunningPrecompiledCode(), fml::paths::JoinPaths(), kApplicationKernelSnapshotFileName, fml::Thread::kBackground, kBackground, fml::Thread::kDisplay, kDisplay, key, kInternalInconsistency, kInvalidArguments, kInvalidLibraryVersion, kMetal, fml::Thread::kNormal, kNormal, kOpenGL, fml::Thread::kRaster, kRaster, kSuccess, flutter::Settings::leak_vm, LOG_EMBEDDER_ERROR, flutter::Settings::log_message_callback, flutter::Settings::log_tag, message, FlutterRendererConfig::metal, name, flutter::Settings::old_gen_heap_size, FlutterRendererConfig::open_gl, PopulateAOTSnapshotMappingCallbacks(), PopulateJITSnapshotMappingCallbacks(), fml::MessageLoop::RemoveTaskObserver(), flutter::Settings::root_isolate_create_callback, SAFE_ACCESS, flutter::PersistentCache::SetCacheDirectoryPath(), fml::Thread::SetCurrentThreadName(), flutter::SettingsFromCommandLine(), FlutterViewFocusChangeRequest::struct_size, flutter::Settings::task_observer_add, flutter::Settings::task_observer_remove, texture, FlutterRendererConfig::type, user_data, view_id, and width.

Referenced by FlutterEngineGetProcAddresses(), and FlutterEngineRun().

◆ FlutterEngineMarkExternalTextureFrameAvailable()

FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable ( FLUTTER_API_SYMBOL(FlutterEngine engine,
int64_t  texture_identifier 
)

Mark that a new texture frame is available for a given texture identifier.

See also
FlutterEngineRegisterExternalTexture()
FlutterEngineUnregisterExternalTexture()
Parameters
[in]engineA running engine instance.
[in]texture_identifierThe identifier of the texture whose frame has been updated.
Returns
The result of the call.

Definition at line 3175 of file embedder.cc.

3177 {
3178 if (engine == nullptr) {
3179 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3180 }
3181 if (texture_identifier == 0) {
3182 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid texture identifier.");
3183 }
3184 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3185 ->MarkTextureFrameAvailable(texture_identifier)) {
3186 return LOG_EMBEDDER_ERROR(
3188 "Could not mark the texture frame as being available.");
3189 }
3190 return kSuccess;
3191}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineNotifyDisplayUpdate()

FlutterEngineResult FlutterEngineNotifyDisplayUpdate ( FLUTTER_API_SYMBOL(FlutterEngine engine,
FlutterEngineDisplaysUpdateType  update_type,
const FlutterEngineDisplay displays,
size_t  display_count 
)

Posts updates corresponding to display changes to a running engine instance.

Parameters
[in]update_typeThe type of update pushed to the engine.
[in]displaysThe displays affected by this update.
[in]display_countSize of the displays array, must be at least 1.
Returns
the result of the call made to the engine.

Definition at line 3638 of file embedder.cc.

3642 {
3643 if (raw_engine == nullptr) {
3644 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3645 }
3646
3647 if (!ValidDisplayConfiguration(embedder_displays, display_count)) {
3648 return LOG_EMBEDDER_ERROR(
3650 "Invalid FlutterEngineDisplay configuration specified.");
3651 }
3652
3653 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3654
3655 switch (update_type) {
3657 std::vector<std::unique_ptr<flutter::Display>> displays;
3658 const auto* display = embedder_displays;
3659 for (size_t i = 0; i < display_count; i++) {
3660 displays.push_back(std::make_unique<flutter::Display>(
3661 SAFE_ACCESS(display, display_id, i), //
3662 SAFE_ACCESS(display, refresh_rate, 0), //
3663 SAFE_ACCESS(display, width, 0), //
3664 SAFE_ACCESS(display, height, 0), //
3665 SAFE_ACCESS(display, device_pixel_ratio, 1)));
3666 display = reinterpret_cast<const FlutterEngineDisplay*>(
3667 reinterpret_cast<const uint8_t*>(display) + display->struct_size);
3668 }
3669 engine->GetShell().OnDisplayUpdates(std::move(displays));
3670 return kSuccess;
3671 }
3672 default:
3673 return LOG_EMBEDDER_ERROR(
3675 "Invalid FlutterEngineDisplaysUpdateType type specified.");
3676 }
3677}

References displays, engine, height, i, kFlutterEngineDisplaysUpdateTypeStartup, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, SAFE_ACCESS, and width.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineNotifyLowMemoryWarning()

FlutterEngineResult FlutterEngineNotifyLowMemoryWarning ( FLUTTER_API_SYMBOL(FlutterEngine engine)

Posts a low memory notification to a running engine instance. The engine will do its best to release non-critical resources in response. It is not guaranteed that the resource would have been collected by the time this call returns however. The notification is posted to engine subsystems that may be operating on other threads.

Flutter applications can respond to these notifications by setting WidgetsBindingObserver.didHaveMemoryPressure observers.

Parameters
[in]engineA running engine instance.
Returns
If the low memory notification was sent to the running engine instance.

Definition at line 3577 of file embedder.cc.

3578 {
3579 auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
3580 if (engine == nullptr || !engine->IsValid()) {
3581 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
3582 }
3583
3584 engine->GetShell().NotifyLowMemoryWarning();
3585
3586 rapidjson::Document document;
3587 auto& allocator = document.GetAllocator();
3588
3589 document.SetObject();
3590 document.AddMember("type", "memoryPressure", allocator);
3591
3592 return DispatchJSONPlatformMessage(raw_engine, document, "flutter/system")
3593 ? kSuccess
3596 "Could not dispatch the low memory notification message.");
3597}

References allocator, DispatchJSONPlatformMessage(), engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineOnVsync()

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 must be returned. This call must be made on the thread on which the call to FlutterEngineRun was made.

See also
FlutterEngineGetCurrentTime()
Attention
That frame timepoints are in nanoseconds.
The system monotonic clock is used as the timebase.
Parameters
[in]engine.A running engine instance.
[in]batonThe baton supplied by the engine.
[in]frame_start_time_nanosThe point at which the vsync event occurred or will occur. If the time point is in the future, the engine will wait till that point to begin its frame workload.
[in]frame_target_time_nanosThe point at which the embedder anticipates the next vsync to occur. This is a hint the engine uses to schedule Dart VM garbage collection in periods in which the various threads are most likely to be idle. For example, for a 60Hz display, embedders should add 16.6 * 1e6 to the frame time field.
Returns
The result of the call.

Definition at line 3254 of file embedder.cc.

3258 {
3259 if (engine == nullptr) {
3260 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3261 }
3262
3263 TRACE_EVENT0("flutter", "FlutterEngineOnVsync");
3264
3265 auto start_time = fml::TimePoint::FromEpochDelta(
3266 fml::TimeDelta::FromNanoseconds(frame_start_time_nanos));
3267
3268 auto target_time = fml::TimePoint::FromEpochDelta(
3269 fml::TimeDelta::FromNanoseconds(frame_target_time_nanos));
3270
3271 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->OnVsyncEvent(
3272 baton, start_time, target_time)) {
3273 return LOG_EMBEDDER_ERROR(
3275 "Could not notify the running engine instance of a Vsync event.");
3276 }
3277
3278 return kSuccess;
3279}

References engine, fml::TimePoint::FromEpochDelta(), fml::TimeDelta::FromNanoseconds(), kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and TRACE_EVENT0.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEnginePostCallbackOnAllNativeThreads()

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 callback the next time the message loop for each managed thread is idle. Since the engine manages the entire lifecycle of multiple threads, there is no opportunity for the embedders to finely tune the priorities of threads directly, or, perform other thread specific configuration (for example, setting thread names for tracing). This callback gives embedders a chance to affect such tuning.

Attention
This call is expensive and must be made as few times as possible. The callback must also return immediately as not doing so may risk performance issues (especially for callbacks of type kFlutterNativeThreadTypeUI and kFlutterNativeThreadTypeRender).
Some callbacks (especially the ones of type kFlutterNativeThreadTypeWorker) may be called after the FlutterEngine instance has shut down. Embedders must be careful in handling the lifecycle of objects associated with the user data baton.
In case there are multiple running Flutter engine instances, their workers are shared.
Parameters
[in]engineA running engine instance.
[in]callbackThe callback that will get called multiple times on each engine managed thread.
[in]user_dataA baton passed by the engine to the callback. This baton is not interpreted by the engine in any way.
Returns
Returns if the callback was successfully posted to all threads.

Definition at line 3599 of file embedder.cc.

3602 {
3603 if (engine == nullptr) {
3604 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3605 }
3606
3607 if (callback == nullptr) {
3609 "Invalid native thread callback.");
3610 }
3611
3612 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3613 ->PostTaskOnEngineManagedNativeThreads(
3616 })
3617 ? kSuccess
3619 "Internal error while attempting to post "
3620 "tasks to all threads.");
3621}

References callback, engine, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, type, and user_data.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEnginePostDartObject()

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 any isolate running in the VM. This isolate can also be the root isolate for an unrelated engine. The engine parameter is necessary only to ensure the call is not made when no engine (and hence no VM) is running.

Unlike the platform messages mechanism, there are no threading restrictions when using this API. Message can be posted on any thread and they will be made available to isolate on which the corresponding send port is listening.

However, it is the embedders responsibility to ensure that the call is not made during an ongoing call the FlutterEngineDeinitialize or FlutterEngineShutdown on another thread.

Parameters
[in]engineA running engine instance.
[in]portThe send port to send the object to.
[in]objectThe object to send to the isolate with the corresponding receive port.
Returns
If the message was posted to the send port.

Definition at line 3453 of file embedder.cc.

3456 {
3457 if (engine == nullptr) {
3458 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3459 }
3460
3461 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->IsValid()) {
3462 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine not running.");
3463 }
3464
3465 if (port == ILLEGAL_PORT) {
3467 "Attempted to post to an illegal port.");
3468 }
3469
3470 if (object == nullptr) {
3472 "Invalid Dart object to post.");
3473 }
3474
3475 Dart_CObject dart_object = {};
3476 fml::ScopedCleanupClosure typed_data_finalizer;
3477
3478 switch (object->type) {
3480 dart_object.type = Dart_CObject_kNull;
3481 break;
3483 dart_object.type = Dart_CObject_kBool;
3484 dart_object.value.as_bool = object->bool_value;
3485 break;
3487 dart_object.type = Dart_CObject_kInt32;
3488 dart_object.value.as_int32 = object->int32_value;
3489 break;
3491 dart_object.type = Dart_CObject_kInt64;
3492 dart_object.value.as_int64 = object->int64_value;
3493 break;
3495 dart_object.type = Dart_CObject_kDouble;
3496 dart_object.value.as_double = object->double_value;
3497 break;
3499 if (object->string_value == nullptr) {
3501 "kFlutterEngineDartObjectTypeString must be "
3502 "a null terminated string but was null.");
3503 }
3504 dart_object.type = Dart_CObject_kString;
3505 dart_object.value.as_string = const_cast<char*>(object->string_value);
3506 break;
3508 auto* buffer = SAFE_ACCESS(object->buffer_value, buffer, nullptr);
3509 if (buffer == nullptr) {
3511 "kFlutterEngineDartObjectTypeBuffer must "
3512 "specify a buffer but found nullptr.");
3513 }
3514 auto buffer_size = SAFE_ACCESS(object->buffer_value, buffer_size, 0);
3515 auto callback =
3516 SAFE_ACCESS(object->buffer_value, buffer_collect_callback, nullptr);
3517 auto user_data = SAFE_ACCESS(object->buffer_value, user_data, nullptr);
3518
3519 // The user has provided a callback, let them manage the lifecycle of
3520 // the underlying data. If not, copy it out from the provided buffer.
3521
3522 if (callback == nullptr) {
3523 dart_object.type = Dart_CObject_kTypedData;
3524 dart_object.value.as_typed_data.type = Dart_TypedData_kUint8;
3525 dart_object.value.as_typed_data.length = buffer_size;
3526 dart_object.value.as_typed_data.values = buffer;
3527 } else {
3528 struct ExternalTypedDataPeer {
3529 void* user_data = nullptr;
3530 VoidCallback trampoline = nullptr;
3531 };
3532 auto peer = new ExternalTypedDataPeer();
3533 peer->user_data = user_data;
3534 peer->trampoline = callback;
3535 // This finalizer is set so that in case of failure of the
3536 // Dart_PostCObject below, we collect the peer. The embedder is still
3537 // responsible for collecting the buffer in case of non-kSuccess
3538 // returns from this method. This finalizer must be released in case
3539 // of kSuccess returns from this method.
3540 typed_data_finalizer.SetClosure([peer]() {
3541 // This is the tiny object we use as the peer to the Dart call so
3542 // that we can attach the a trampoline to the embedder supplied
3543 // callback. In case of error, we need to collect this object lest
3544 // we introduce a tiny leak.
3545 delete peer;
3546 });
3547 dart_object.type = Dart_CObject_kExternalTypedData;
3548 dart_object.value.as_external_typed_data.type = Dart_TypedData_kUint8;
3549 dart_object.value.as_external_typed_data.length = buffer_size;
3550 dart_object.value.as_external_typed_data.data = buffer;
3551 dart_object.value.as_external_typed_data.peer = peer;
3552 dart_object.value.as_external_typed_data.callback =
3553 +[](void* unused_isolate_callback_data, void* peer) {
3554 auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
3555 typed_peer->trampoline(typed_peer->user_data);
3556 delete typed_peer;
3557 };
3558 }
3559 } break;
3560 default:
3561 return LOG_EMBEDDER_ERROR(
3563 "Invalid FlutterEngineDartObjectType type specified.");
3564 }
3565
3566 if (!Dart_PostCObject(port, &dart_object)) {
3568 "Could not post the object to the Dart VM.");
3569 }
3570
3571 // On a successful call, the VM takes ownership of and is responsible for
3572 // invoking the finalizer.
3573 typed_data_finalizer.Release();
3574 return kSuccess;
3575}

References FlutterEngineDartObject::buffer_value, callback, engine, kFlutterEngineDartObjectTypeBool, kFlutterEngineDartObjectTypeBuffer, kFlutterEngineDartObjectTypeDouble, kFlutterEngineDartObjectTypeInt32, kFlutterEngineDartObjectTypeInt64, kFlutterEngineDartObjectTypeNull, kFlutterEngineDartObjectTypeString, kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, fml::ScopedCleanupClosure::Release(), SAFE_ACCESS, fml::ScopedCleanupClosure::SetClosure(), FlutterEngineDartObject::string_value, FlutterEngineDartObject::type, and user_data.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEnginePostRenderThreadTask()

FlutterEngineResult FlutterEnginePostRenderThreadTask ( FLUTTER_API_SYMBOL(FlutterEngine engine,
VoidCallback  callback,
void *  callback_data 
)

Posts a task onto the Flutter render thread. Typically, this may be called from any thread as long as a FlutterEngineShutdown on the specific engine has not already been initiated.

Parameters
[in]engineA running engine instance.
[in]callbackThe callback to execute on the render thread.
callback_dataThe callback context.
Returns
The result of the call.

Definition at line 3312 of file embedder.cc.

3315 {
3316 if (engine == nullptr) {
3317 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3318 }
3319
3320 if (callback == nullptr) {
3322 "Render thread callback was null.");
3323 }
3324
3325 auto task = [callback, baton]() { callback(baton); };
3326
3327 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3328 ->PostRenderThreadTask(task)
3329 ? kSuccess
3331 "Could not post the render thread task.");
3332}

References callback, engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineRegisterExternalTexture()

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 support external textures accept external texture registrations. After the external texture is registered, the application can mark that a frame is available by calling FlutterEngineMarkExternalTextureFrameAvailable.

See also
FlutterEngineUnregisterExternalTexture()
FlutterEngineMarkExternalTextureFrameAvailable()
Parameters
[in]engineA running engine instance.
[in]texture_identifierThe identifier of the texture to register with the engine. The embedder may supply new frames to this texture using the same identifier.
Returns
The result of the call.

Definition at line 3135 of file embedder.cc.

3137 {
3138 if (engine == nullptr) {
3139 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3140 }
3141
3142 if (texture_identifier == 0) {
3144 "Texture identifier was invalid.");
3145 }
3146 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->RegisterTexture(
3147 texture_identifier)) {
3149 "Could not register the specified texture.");
3150 }
3151 return kSuccess;
3152}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineReloadSystemFonts()

FlutterEngineResult FlutterEngineReloadSystemFonts ( FLUTTER_API_SYMBOL(FlutterEngine engine)

Reloads the system fonts in engine.

Parameters
[in]engine.A running engine instance.
Returns
The result of the call.

Definition at line 3281 of file embedder.cc.

3282 {
3283 if (engine == nullptr) {
3284 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3285 }
3286
3287 TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");
3288
3289 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3290 ->ReloadSystemFonts()) {
3292 "Could not reload system fonts.");
3293 }
3294
3295 return kSuccess;
3296}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and TRACE_EVENT0.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineRemoveView()

FLUTTER_EXPORT FlutterEngineResult FlutterEngineRemoveView ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterRemoveViewInfo info 
)

Removes a view.

        This is an asynchronous operation. The view's resources must not
        be cleaned up until |info.remove_view_callback| is invoked with
        a |removed| value of true.

        The callback is invoked on a thread managed by the engine. The
        embedder should re-thread if needed.

        Attempting to remove the implicit view will fail and will return
        kInvalidArguments. Attempting to remove a view with a
        non-existent view ID will fail, and |info.remove_view_callback|
        will be invoked with a |removed| value of false.
Parameters
[in]engineA running engine instance.
[in]infoThe remove view arguments. This can be deallocated once |FlutterEngineRemoveView| returns, before |remove_view_callback| is invoked.
Returns
The result of starting the asynchronous operation. If kSuccess, the |remove_view_callback| will be invoked.

Definition at line 2586 of file embedder.cc.

2588 {
2589 if (!engine) {
2590 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2591 }
2592 if (!info || !info->remove_view_callback) {
2594 "Remove view info handle was invalid.");
2595 }
2596
2597 if (info->view_id == kFlutterImplicitViewId) {
2598 return LOG_EMBEDDER_ERROR(
2600 "Remove view info was invalid. The implicit view cannot be removed.");
2601 }
2602
2603 // TODO(loicsharma): Return an error if the engine was initialized with
2604 // callbacks that are incompatible with multiple views.
2605 // https://github.com/flutter/flutter/issues/144806
2606
2607 // The engine must be running to remove a view.
2608 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2609 if (!embedder_engine->IsValid()) {
2610 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2611 }
2612
2614 [c_callback = info->remove_view_callback,
2615 user_data = info->user_data](bool removed) {
2616 FlutterRemoveViewResult result = {};
2617 result.struct_size = sizeof(FlutterRemoveViewResult);
2618 result.removed = removed;
2619 result.user_data = user_data;
2620 c_callback(&result);
2621 };
2622
2623 embedder_engine->GetShell().GetPlatformView()->RemoveView(info->view_id,
2624 callback);
2625 return kSuccess;
2626}

References callback, engine, kFlutterImplicitViewId, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, FlutterRemoveViewInfo::remove_view_callback, FlutterRemoveViewResult::removed, FlutterRemoveViewResult::struct_size, user_data, FlutterRemoveViewResult::user_data, FlutterRemoveViewInfo::user_data, and FlutterRemoveViewInfo::view_id.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineRun()

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 for the pair of calls to FlutterEngineInitialize and FlutterEngineRunInitialized.

Note
This method of running a Flutter engine works well except in cases where the embedder specifies custom task runners via FlutterProjectArgs::custom_task_runners. In such cases, the engine may need the embedder to post tasks back to it before FlutterEngineRun has returned. Embedders can only post tasks to the engine if they have a handle to the engine. In such cases, embedders are advised to get the engine handle by calling FlutterEngineInitialize. Then they can call FlutterEngineRunInitialized knowing that they will be able to service custom tasks on other threads with the engine handle.
Parameters
[in]versionThe Flutter embedder API version. Must be FLUTTER_ENGINE_VERSION.
[in]configThe renderer configuration.
[in]argsThe Flutter project arguments.
user_dataA user data baton passed back to embedders in callbacks.
[out]engine_outThe engine handle on successful engine creation.
Returns
The result of the call to run the Flutter engine.

Definition at line 1995 of file embedder.cc.

2000 {
2001 auto result =
2002 FlutterEngineInitialize(version, config, args, user_data, engine_out);
2003
2004 if (result != kSuccess) {
2005 return result;
2006 }
2007
2008 return FlutterEngineRunInitialized(*engine_out);
2009}

References args, FlutterEngineInitialize(), FlutterEngineRunInitialized(), kSuccess, and user_data.

Referenced by FlutterEngineGetProcAddresses(), main(), RunFlutter(), and RunFlutterEngine().

◆ FlutterEngineRunInitialized()

FlutterEngineResult FlutterEngineRunInitialized ( FLUTTER_API_SYMBOL(FlutterEngine engine)

Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize. An initialized instance can only be run once. During and after this call, custom task runners supplied by the embedder are expected to start servicing tasks.

Parameters
[in]engineAn initialized engine instance that has not previously been run.
Returns
The result of the call to run the initialized Flutter engine instance.

Definition at line 2486 of file embedder.cc.

2487 {
2488 if (!engine) {
2489 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2490 }
2491
2492 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2493
2494 // The engine must not already be running. Initialize may only be called
2495 // once on an engine instance.
2496 if (embedder_engine->IsValid()) {
2497 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2498 }
2499
2500 // Step 1: Launch the shell.
2501 if (!embedder_engine->LaunchShell()) {
2503 "Could not launch the engine using supplied "
2504 "initialization arguments.");
2505 }
2506
2507 // Step 2: Tell the platform view to initialize itself.
2508 if (!embedder_engine->NotifyCreated()) {
2510 "Could not create platform view components.");
2511 }
2512
2513 // Step 3: Launch the root isolate.
2514 if (!embedder_engine->RunRootIsolate()) {
2515 return LOG_EMBEDDER_ERROR(
2517 "Could not run the root isolate of the Flutter application using the "
2518 "project arguments specified.");
2519 }
2520
2521 return kSuccess;
2522}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), FlutterEngineRun(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_P().

◆ FlutterEngineRunsAOTCompiledDartCode()

bool FlutterEngineRunsAOTCompiledDartCode ( void  )

Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading restrictions.

For embedder code that is configured for both AOT and JIT mode Dart execution based on the Flutter engine being linked to, this runtime check may be used to appropriately configure the FlutterProjectArgs. In JIT mode execution, the kernel snapshots must be present in the Flutter assets directory specified in the FlutterProjectArgs. For AOT execution, the fields vm_snapshot_data, vm_snapshot_instructions, isolate_snapshot_data and isolate_snapshot_instructions (along with their size fields) must be specified in FlutterProjectArgs.

Returns
True, if AOT Dart code is run. JIT otherwise.

Definition at line 3449 of file embedder.cc.

3449 {
3451}

References flutter::DartVM::IsRunningPrecompiledCode().

Referenced by FlutterEngineGetProcAddresses(), RunFlutterEngine(), and flutter::testing::TEST_F().

◆ FlutterEngineRunTask()

FlutterEngineResult FlutterEngineRunTask ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterTask task 
)

Inform the engine to run the specified task. This task has been given to the embedder via the FlutterTaskRunnerDescription.post_task_callback. This call must only be made at the target time specified in that callback. Running the task before that time is undefined behavior.

Parameters
[in]engineA running engine instance.
[in]taskthe task handle.
Returns
The result of the call.

Definition at line 3338 of file embedder.cc.

3340 {
3341 if (engine == nullptr) {
3342 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3343 }
3344
3346 reinterpret_cast<intptr_t>(task->runner))) {
3347 // This task came too late, the embedder has already been destroyed.
3348 // This is not an error, just ignore the task.
3349 return kSuccess;
3350 }
3351
3352 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->RunTask(task)
3353 ? kSuccess
3355 "Could not run the specified task.");
3356}

References engine, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, FlutterTask::runner, and flutter::EmbedderThreadHost::RunnerIsValid().

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_P().

◆ FlutterEngineScheduleFrame()

FlutterEngineResult FlutterEngineScheduleFrame ( FLUTTER_API_SYMBOL(FlutterEngine engine)

Schedule a new frame to redraw the content.

Parameters
[in]engineA running engine instance.
Returns
the result of the call made to the engine.

Definition at line 3679 of file embedder.cc.

3680 {
3681 if (engine == nullptr) {
3682 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3683 }
3684
3685 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->ScheduleFrame()
3686 ? kSuccess
3688 "Could not schedule frame.");
3689}

References engine, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineSendKeyEvent()

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 synchronous fashion, although due to technical limitation, the result is always reported asynchronously. The callback is guaranteed to be called exactly once.

Parameters
[in]engineA running engine instance.
[in]eventThe event data to be sent. This function will no longer access event after returning.
[in]callbackThe callback invoked by the engine when the Flutter application has decided whether it handles this event. Accepts nullptr.
[in]user_dataThe context associated with the callback. The exact same value will used to invoke callback. Accepts nullptr.
Returns
The result of the call.

Definition at line 2946 of file embedder.cc.

2950 {
2951 if (engine == nullptr) {
2952 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2953 }
2954
2955 if (event == nullptr) {
2956 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid key event.");
2957 }
2958
2959 const char* character = SAFE_ACCESS(event, character, nullptr);
2960
2961 flutter::KeyData key_data;
2962 key_data.Clear();
2963 key_data.timestamp = static_cast<uint64_t>(SAFE_ACCESS(event, timestamp, 0));
2964 key_data.type = MapKeyEventType(
2966 key_data.physical = SAFE_ACCESS(event, physical, 0);
2967 key_data.logical = SAFE_ACCESS(event, logical, 0);
2968 key_data.synthesized = SAFE_ACCESS(event, synthesized, false);
2970 event, device_type,
2972
2973 auto packet = std::make_unique<flutter::KeyDataPacket>(key_data, character);
2974
2975 struct MessageData {
2977 void* user_data;
2978 };
2979
2980 MessageData* message_data =
2981 new MessageData{.callback = callback, .user_data = user_data};
2982
2983 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
2985 engine, kFlutterKeyDataChannel, packet->data().data(),
2986 packet->data().size(),
2987 [](const uint8_t* data, size_t size, void* user_data) {
2988 auto message_data = std::unique_ptr<MessageData>(
2989 reinterpret_cast<MessageData*>(user_data));
2990 if (message_data->callback == nullptr) {
2991 return;
2992 }
2993 bool handled = false;
2994 if (size == 1) {
2995 handled = *data != 0;
2996 }
2997 message_data->callback(handled, message_data->user_data);
2998 },
2999 message_data);
3000}

References callback, character, flutter::KeyData::Clear(), data, flutter::KeyData::device_type, engine, InternalSendPlatformMessage(), kFlutterKeyDataChannel, kFlutterKeyEventDeviceTypeKeyboard, kFlutterKeyEventTypeUp, kInvalidArguments, LOG_EMBEDDER_ERROR, flutter::KeyData::logical, MapKeyEventDeviceType(), MapKeyEventType(), flutter::KeyData::physical, SAFE_ACCESS, flutter::KeyData::synthesized, flutter::KeyData::timestamp, type, flutter::KeyData::type, and user_data.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineSendPlatformMessage()

FlutterEngineResult FlutterEngineSendPlatformMessage ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterPlatformMessage flutter_message 
)

Definition at line 3002 of file embedder.cc.

3004 {
3005 if (engine == nullptr) {
3006 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3007 }
3008
3009 if (flutter_message == nullptr) {
3010 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid message argument.");
3011 }
3012
3013 if (SAFE_ACCESS(flutter_message, channel, nullptr) == nullptr) {
3014 return LOG_EMBEDDER_ERROR(
3015 kInvalidArguments, "Message argument did not specify a valid channel.");
3016 }
3017
3018 size_t message_size = SAFE_ACCESS(flutter_message, message_size, 0);
3019 const uint8_t* message_data = SAFE_ACCESS(flutter_message, message, nullptr);
3020
3021 if (message_size != 0 && message_data == nullptr) {
3022 return LOG_EMBEDDER_ERROR(
3024 "Message size was non-zero but the message data was nullptr.");
3025 }
3026
3027 const FlutterPlatformMessageResponseHandle* response_handle =
3028 SAFE_ACCESS(flutter_message, response_handle, nullptr);
3029
3031 if (response_handle && response_handle->message) {
3032 response = response_handle->message->response();
3033 }
3034
3035 std::unique_ptr<flutter::PlatformMessage> message;
3036 if (message_size == 0) {
3037 message = std::make_unique<flutter::PlatformMessage>(
3038 flutter_message->channel, response);
3039 } else {
3040 message = std::make_unique<flutter::PlatformMessage>(
3041 flutter_message->channel,
3042 fml::MallocMapping::Copy(message_data, message_size), response);
3043 }
3044
3045 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
3046 ->SendPlatformMessage(std::move(message))
3047 ? kSuccess
3049 "Could not send a message to the running "
3050 "Flutter application.");
3051}

References FlutterPlatformMessage::channel, channel, fml::MallocMapping::Copy(), engine, kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, _FlutterPlatformMessageResponseHandle::message, message, and SAFE_ACCESS.

Referenced by FlutterDesktopMessengerSendWithReply(), FlutterEngineGetProcAddresses(), InternalSendPlatformMessage(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineSendPlatformMessageResponse()

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.

Parameters
[in]engineThe running engine instance.
[in]handleThe platform message response handle.
[in]dataThe data to associate with the platform message response.
[in]data_lengthThe length of the platform message response data.
Returns
The result of the call.

Definition at line 3103 of file embedder.cc.

3107 {
3108 if (data_length != 0 && data == nullptr) {
3109 return LOG_EMBEDDER_ERROR(
3111 "Data size was non zero but the pointer to the data was null.");
3112 }
3113
3114 auto response = handle->message->response();
3115
3116 if (response) {
3117 if (data_length == 0) {
3118 response->CompleteEmpty();
3119 } else {
3120 response->Complete(std::make_unique<fml::DataMapping>(
3121 std::vector<uint8_t>({data, data + data_length})));
3122 }
3123 }
3124
3125 delete handle;
3126
3127 return kSuccess;
3128}

References data, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and _FlutterPlatformMessageResponseHandle::message.

Referenced by FlutterDesktopMessengerSendResponse(), FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineSendPointerEvent()

FlutterEngineResult FlutterEngineSendPointerEvent ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterPointerEvent pointers,
size_t  events_count 
)

Definition at line 2794 of file embedder.cc.

2797 {
2798 if (engine == nullptr) {
2799 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2800 }
2801
2802 if (pointers == nullptr || events_count == 0) {
2803 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid pointer events.");
2804 }
2805
2806 auto packet = std::make_unique<flutter::PointerDataPacket>(events_count);
2807
2808 const FlutterPointerEvent* current = pointers;
2809
2810 for (size_t i = 0; i < events_count; ++i) {
2811 flutter::PointerData pointer_data;
2812 pointer_data.Clear();
2813 // this is currely in use only on android embedding.
2814 pointer_data.embedder_id = 0;
2815 pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
2816 pointer_data.change = ToPointerDataChange(
2817 SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
2818 pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
2819 pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
2820 // Delta will be generated in pointer_data_packet_converter.cc.
2821 pointer_data.physical_delta_x = 0.0;
2822 pointer_data.physical_delta_y = 0.0;
2823 pointer_data.device = SAFE_ACCESS(current, device, 0);
2824 // Pointer identifier will be generated in
2825 // pointer_data_packet_converter.cc.
2826 pointer_data.pointer_identifier = 0;
2827 pointer_data.signal_kind = ToPointerDataSignalKind(
2828 SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
2829 pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
2830 pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
2831 FlutterPointerDeviceKind device_kind =
2832 SAFE_ACCESS(current, device_kind, kFlutterPointerDeviceKindMouse);
2833 // For backwards compatibility with embedders written before the device
2834 // kind and buttons were exposed, if the device kind is not set treat it
2835 // as a mouse, with a synthesized primary button state based on the phase.
2836 if (device_kind == 0) {
2838 pointer_data.buttons =
2840
2841 } else {
2842 pointer_data.kind = ToPointerDataKind(device_kind);
2843 if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
2844 // For touch events, set the button internally rather than requiring
2845 // it at the API level, since it's a confusing construction to expose.
2846 if (pointer_data.change == flutter::PointerData::Change::kDown ||
2849 }
2850 } else {
2851 // Buttons use the same mask values, so pass them through directly.
2852 pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
2853 }
2854 }
2855 pointer_data.pan_x = SAFE_ACCESS(current, pan_x, 0.0);
2856 pointer_data.pan_y = SAFE_ACCESS(current, pan_y, 0.0);
2857 // Delta will be generated in pointer_data_packet_converter.cc.
2858 pointer_data.pan_delta_x = 0.0;
2859 pointer_data.pan_delta_y = 0.0;
2860 pointer_data.scale = SAFE_ACCESS(current, scale, 0.0);
2861 pointer_data.rotation = SAFE_ACCESS(current, rotation, 0.0);
2862 pointer_data.view_id =
2864 packet->SetPointerData(i, pointer_data);
2865 current = reinterpret_cast<const FlutterPointerEvent*>(
2866 reinterpret_cast<const uint8_t*>(current) + current->struct_size);
2867 }
2868
2869 return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2870 ->DispatchPointerDataPacket(std::move(packet))
2871 ? kSuccess
2873 "Could not dispatch pointer events to the "
2874 "running Flutter application.");
2875}

References flutter::PointerData::buttons, flutter::PointerData::change, flutter::PointerData::Clear(), device, flutter::PointerData::device, flutter::PointerData::embedder_id, engine, i, kCancel, flutter::PointerData::kDown, kFlutterImplicitViewId, kFlutterPointerDeviceKindMouse, kFlutterPointerSignalKindNone, flutter::PointerData::kind, kInternalInconsistency, kInvalidArguments, flutter::PointerData::kMouse, flutter::PointerData::kMove, flutter::kPointerButtonTouchContact, kSuccess, flutter::PointerData::kTouch, LOG_EMBEDDER_ERROR, flutter::PointerData::pan_delta_x, flutter::PointerData::pan_delta_y, flutter::PointerData::pan_x, flutter::PointerData::pan_y, flutter::PointerData::physical_delta_x, flutter::PointerData::physical_delta_y, flutter::PointerData::physical_x, flutter::PointerData::physical_y, flutter::PointerData::pointer_identifier, PointerDataButtonsForLegacyEvent(), flutter::PointerData::rotation, SAFE_ACCESS, flutter::PointerData::scale, flutter::PointerData::scroll_delta_x, flutter::PointerData::scroll_delta_y, flutter::PointerData::signal_kind, FlutterPointerEvent::struct_size, flutter::PointerData::time_stamp, ToPointerDataChange(), ToPointerDataKind(), ToPointerDataSignalKind(), flutter::PointerData::view_id, view_id, x, and y.

Referenced by FlutterEngineGetProcAddresses(), GLFWcursorPositionCallbackAtPhase(), SendPointerEventWithData(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineSendSemanticsAction()

FlutterEngineResult FlutterEngineSendSemanticsAction ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterSendSemanticsActionInfo info 
)

Dispatch a semantics action to the specified semantics node within a specific view.

Parameters
[in]engineA running engine instance.
[in]infoThe dispatch semantics on view arguments. This can be deallocated once |FlutterEngineSendSemanticsAction| returns.
Returns
The result of the call.

Definition at line 3237 of file embedder.cc.

3239 {
3240 if (engine == nullptr) {
3241 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3242 }
3243 auto engine_action = static_cast<flutter::SemanticsAction>(info->action);
3244 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3246 info->view_id, info->node_id, engine_action,
3247 fml::MallocMapping::Copy(info->data, info->data_length))) {
3249 "Could not dispatch semantics action.");
3250 }
3251 return kSuccess;
3252}

References FlutterSendSemanticsActionInfo::action, fml::MallocMapping::Copy(), FlutterSendSemanticsActionInfo::data, FlutterSendSemanticsActionInfo::data_length, flutter::EmbedderEngine::DispatchSemanticsAction(), engine, kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, FlutterSendSemanticsActionInfo::node_id, and FlutterSendSemanticsActionInfo::view_id.

Referenced by FlutterEngineDispatchSemanticsAction(), and FlutterEngineGetProcAddresses().

◆ FlutterEngineSendViewFocusEvent()

FlutterEngineResult FlutterEngineSendViewFocusEvent ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterViewFocusEvent event 
)

Notifies the engine that platform view focus state has changed.

Parameters
[in]engineA running engine instance
[in]eventThe focus event data describing the change.

Definition at line 2628 of file embedder.cc.

2630 {
2631 if (!engine) {
2632 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2633 }
2634 if (!event) {
2636 "View focus event must not be null.");
2637 }
2638 // The engine must be running to focus a view.
2639 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2640 if (!embedder_engine->IsValid()) {
2641 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2642 }
2643
2644 if (!STRUCT_HAS_MEMBER(event, direction)) {
2646 "The event struct has invalid size.");
2647 }
2648
2649 flutter::ViewFocusEvent flutter_event(
2650 event->view_id, //
2651 static_cast<flutter::ViewFocusState>(event->state),
2652 static_cast<flutter::ViewFocusDirection>(event->direction));
2653
2654 embedder_engine->GetShell().GetPlatformView()->SendViewFocusEvent(
2655 flutter_event);
2656
2657 return kSuccess;
2658}

References FlutterViewFocusEvent::direction, engine, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, FlutterViewFocusEvent::state, STRUCT_HAS_MEMBER, and FlutterViewFocusEvent::view_id.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineSendWindowMetricsEvent()

FlutterEngineResult FlutterEngineSendWindowMetricsEvent ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const FlutterWindowMetricsEvent flutter_metrics 
)

Definition at line 2685 of file embedder.cc.

2687 {
2688 if (engine == nullptr || flutter_metrics == nullptr) {
2689 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
2690 }
2692 SAFE_ACCESS(flutter_metrics, view_id, kFlutterImplicitViewId);
2693
2694 std::variant<flutter::ViewportMetrics, std::string> metrics_or_error =
2695 MakeViewportMetricsFromWindowMetrics(flutter_metrics);
2696 if (const std::string* error = std::get_if<std::string>(&metrics_or_error)) {
2697 return LOG_EMBEDDER_ERROR(kInvalidArguments, error->c_str());
2698 }
2699
2700 auto metrics = std::get<flutter::ViewportMetrics>(metrics_or_error);
2701
2702 return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
2703 view_id, metrics)
2704 ? kSuccess
2706 "Viewport metrics were invalid.");
2707}

References engine, error, kFlutterImplicitViewId, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, MakeViewportMetricsFromWindowMetrics(), SAFE_ACCESS, and view_id.

Referenced by flutter::testing::expectSoftwareRenderingOutputMatches(), FlutterEngineGetProcAddresses(), GLFWframebufferSizeCallback(), GLFWwindowSizeCallback(), SendWindowMetrics(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_P(), flutter::testing::TEST_P(), flutter::testing::TEST_P(), flutter::testing::TEST_P(), flutter::testing::TEST_P(), and flutter::testing::TEST_P().

◆ FlutterEngineSetNextFrameCallback()

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 thread. The callback is executed only once from the raster thread; embedders must re-thread if necessary. Performing blocking calls in this callback may introduce application jank.

Parameters
[in]engineA running engine instance.
[in]callbackThe callback to execute.
[in]user_dataA baton passed by the engine to the callback. This baton is not interpreted by the engine in any way.
Returns
The result of the call.

Definition at line 3691 of file embedder.cc.

3694 {
3695 if (engine == nullptr) {
3696 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3697 }
3698
3699 if (callback == nullptr) {
3701 "Next frame callback was null.");
3702 }
3703
3704 flutter::EmbedderEngine* embedder_engine =
3705 reinterpret_cast<flutter::EmbedderEngine*>(engine);
3706
3707 fml::WeakPtr<flutter::PlatformView> weak_platform_view =
3708 embedder_engine->GetShell().GetPlatformView();
3709
3710 if (!weak_platform_view) {
3712 "Platform view unavailable.");
3713 }
3714
3715 weak_platform_view->SetNextFrameCallback(
3717
3718 return kSuccess;
3719}

References callback, engine, flutter::Shell::GetPlatformView(), flutter::EmbedderEngine::GetShell(), kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and user_data.

Referenced by FlutterEngineGetProcAddresses(), and flutter::testing::TEST_F().

◆ FlutterEngineShutdown()

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 embedder API after this point. Making additional calls with this handle is undefined behavior.

Note
This de-initializes the Flutter engine instance (via an implicit call to FlutterEngineDeinitialize) if necessary.
Parameters
[in]engineThe Flutter engine instance to collect.
Returns
The result of the call to shutdown the Flutter engine instance.

Definition at line 2674 of file embedder.cc.

2675 {
2676 auto result = FlutterEngineDeinitialize(engine);
2677 if (result != kSuccess) {
2678 return result;
2679 }
2680 auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
2681 delete embedder_engine;
2682 return kSuccess;
2683}

References engine, FlutterEngineDeinitialize(), and kSuccess.

Referenced by FlutterDesktopDestroyWindow(), FlutterDesktopShutDownEngine(), FlutterEngineGetProcAddresses(), flutter::testing::UniqueEngineTraits::Free(), main(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineTraceEventDurationBegin()

void FlutterEngineTraceEventDurationBegin ( const char *  name)

A profiling utility. Logs a trace duration begin event to the timeline. If the timeline is unavailable or disabled, this has no effect. Must be balanced with an duration end event (via FlutterEngineTraceEventDurationEnd) with the same name on the same thread. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.

Parameters
[in]nameThe name of the trace event.

Definition at line 3298 of file embedder.cc.

3298 {
3299 fml::tracing::TraceEvent0("flutter", name, /*flow_id_count=*/0,
3300 /*flow_ids=*/nullptr);
3301}

References name, and fml::tracing::TraceEvent0().

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineTraceEventDurationEnd()

void FlutterEngineTraceEventDurationEnd ( const char *  name)

A profiling utility. Logs a trace duration end event to the timeline. If the timeline is unavailable or disabled, this has no effect. This call must be preceded by a trace duration begin call (via FlutterEngineTraceEventDurationBegin) with the same name on the same thread. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.

Parameters
[in]nameThe name of the trace event.

Definition at line 3303 of file embedder.cc.

3303 {
3305}

References name, and fml::tracing::TraceEventEnd().

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineTraceEventInstant()

void FlutterEngineTraceEventInstant ( const char *  name)

A profiling utility. Logs a trace duration instant event to the timeline. If the timeline is unavailable or disabled, this has no effect. Can be called on any thread. Strings passed into the function will NOT be copied when added to the timeline. Only string literals may be passed in.

Parameters
[in]nameThe name of the trace event.

Definition at line 3307 of file embedder.cc.

3307 {
3308 fml::tracing::TraceEventInstant0("flutter", name, /*flow_id_count=*/0,
3309 /*flow_ids=*/nullptr);
3310}

References name, and fml::tracing::TraceEventInstant0().

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineUnregisterExternalTexture()

FlutterEngineResult FlutterEngineUnregisterExternalTexture ( FLUTTER_API_SYMBOL(FlutterEngine engine,
int64_t  texture_identifier 
)

Unregister a previous texture registration.

See also
FlutterEngineRegisterExternalTexture()
FlutterEngineMarkExternalTextureFrameAvailable()
Parameters
[in]engineA running engine instance.
[in]texture_identifierThe identifier of the texture for which new frame will not be available.
Returns
The result of the call.

Definition at line 3154 of file embedder.cc.

3156 {
3157 if (engine == nullptr) {
3158 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3159 }
3160
3161 if (texture_identifier == 0) {
3163 "Texture identifier was invalid.");
3164 }
3165
3166 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->UnregisterTexture(
3167 texture_identifier)) {
3169 "Could not un-register the specified texture.");
3170 }
3171
3172 return kSuccess;
3173}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses().

◆ FlutterEngineUpdateAccessibilityFeatures()

FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures ( FLUTTER_API_SYMBOL(FlutterEngine engine,
FlutterAccessibilityFeature  features 
)

Sets additional accessibility features.

Parameters
[in]engineA running engine instance
[in]featuresThe accessibility features to set.
Returns
The result of the call.

Definition at line 3207 of file embedder.cc.

3209 {
3210 if (engine == nullptr) {
3211 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3212 }
3213 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
3214 ->SetAccessibilityFeatures(flags)) {
3216 "Could not update accessibility features.");
3217 }
3218 return kSuccess;
3219}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterEngineUpdateLocales()

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 first item in the list of locales supplied. The other entries will be used as a fallback.

Parameters
[in]engineA running engine instance.
[in]localesThe updated locales in the order of preference.
[in]locales_countThe count of locales supplied.
Returns
Whether the locale updates were applied.

Definition at line 3390 of file embedder.cc.

3393 {
3394 if (engine == nullptr) {
3395 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3396 }
3397
3398 if (locales_count == 0) {
3399 return kSuccess;
3400 }
3401
3402 if (locales == nullptr) {
3403 return LOG_EMBEDDER_ERROR(kInvalidArguments, "No locales were specified.");
3404 }
3405
3406 rapidjson::Document document;
3407 auto& allocator = document.GetAllocator();
3408
3409 document.SetObject();
3410 document.AddMember("method", "setLocale", allocator);
3411
3412 rapidjson::Value args(rapidjson::kArrayType);
3413 args.Reserve(locales_count * 4, allocator);
3414 for (size_t i = 0; i < locales_count; ++i) {
3415 const FlutterLocale* locale = locales[i];
3416 const char* language_code_str = SAFE_ACCESS(locale, language_code, nullptr);
3417 if (language_code_str == nullptr || ::strlen(language_code_str) == 0) {
3418 return LOG_EMBEDDER_ERROR(
3420 "Language code is required but not present in FlutterLocale.");
3421 }
3422
3423 const char* country_code_str = SAFE_ACCESS(locale, country_code, "");
3424 const char* script_code_str = SAFE_ACCESS(locale, script_code, "");
3425 const char* variant_code_str = SAFE_ACCESS(locale, variant_code, "");
3426
3427 rapidjson::Value language_code, country_code, script_code, variant_code;
3428
3429 language_code.SetString(language_code_str, allocator);
3430 country_code.SetString(country_code_str ? country_code_str : "", allocator);
3431 script_code.SetString(script_code_str ? script_code_str : "", allocator);
3432 variant_code.SetString(variant_code_str ? variant_code_str : "", allocator);
3433
3434 // Required.
3435 args.PushBack(language_code, allocator);
3436 args.PushBack(country_code, allocator);
3437 args.PushBack(script_code, allocator);
3438 args.PushBack(variant_code, allocator);
3439 }
3440 document.AddMember("args", args, allocator);
3441
3442 return DispatchJSONPlatformMessage(engine, document, "flutter/localization")
3443 ? kSuccess
3445 "Could not send message to update locale of "
3446 "a running Flutter application.");
3447}

References allocator, args, DispatchJSONPlatformMessage(), engine, i, kInternalInconsistency, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, and SAFE_ACCESS.

Referenced by FlutterEngineGetProcAddresses(), SetUpLocales(), and flutter::testing::TEST_F().

◆ FlutterEngineUpdateSemanticsEnabled()

FlutterEngineResult FlutterEngineUpdateSemanticsEnabled ( FLUTTER_API_SYMBOL(FlutterEngine engine,
bool  enabled 
)

Enable or disable accessibility semantics.

Parameters
[in]engineA running engine instance.
[in]enabledWhen enabled, changes to the semantic contents of the window are sent via the FlutterUpdateSemanticsCallback2 registered to update_semantics_callback2 in FlutterProjectArgs.
Returns
The result of the call.

Definition at line 3193 of file embedder.cc.

3195 {
3196 if (engine == nullptr) {
3197 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3198 }
3199 if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetSemanticsEnabled(
3200 enabled)) {
3202 "Could not update semantics state.");
3203 }
3204 return kSuccess;
3205}

References engine, kInternalInconsistency, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterEngineGetProcAddresses(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterPlatformMessageCreateResponseHandle()

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 response to a message. This handle may be set on the response_handle field of any FlutterPlatformMessage sent to the engine.

The handle must be collected via a call to FlutterPlatformMessageReleaseResponseHandle. This may be done immediately after a call to FlutterEngineSendPlatformMessage with a platform message whose response handle contains the handle created using this call. In case a handle is created but never sent in a message, the release call must still be made. Not calling release on the handle results in a small memory leak.

The user data baton passed to the data callback is the one specified in this call as the third argument.

See also
FlutterPlatformMessageReleaseResponseHandle()
Parameters
[in]engineA running engine instance.
[in]data_callbackThe callback invoked by the engine when the Flutter application send a response on the handle.
[in]user_dataThe user data associated with the data callback.
[out]response_outThe response handle created when this call is successful.
Returns
The result of the call.

Definition at line 3053 of file embedder.cc.

3057 {
3058 if (engine == nullptr) {
3059 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
3060 }
3061
3062 if (data_callback == nullptr || response_out == nullptr) {
3063 return LOG_EMBEDDER_ERROR(
3064 kInvalidArguments, "Data callback or the response handle was invalid.");
3065 }
3066
3068 [user_data, data_callback](const uint8_t* data, size_t size) {
3069 data_callback(data, size, user_data);
3070 };
3071
3072 auto platform_task_runner = reinterpret_cast<flutter::EmbedderEngine*>(engine)
3073 ->GetTaskRunners()
3074 .GetPlatformTaskRunner();
3075
3076 auto handle = new FlutterPlatformMessageResponseHandle();
3077
3078 handle->message = std::make_unique<flutter::PlatformMessage>(
3079 "", // The channel is empty and unused as the response handle is going
3080 // to referenced directly in the |FlutterEngineSendPlatformMessage|
3081 // with the container message discarded.
3083 std::move(platform_task_runner), response_callback));
3084 *response_out = handle;
3085 return kSuccess;
3086}

References data, engine, kInvalidArguments, kSuccess, LOG_EMBEDDER_ERROR, fml::MakeRefCounted(), and user_data.

Referenced by FlutterDesktopMessengerSendWithReply(), FlutterEngineGetProcAddresses(), InternalSendPlatformMessage(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ FlutterPlatformMessageReleaseResponseHandle()

FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle ( FLUTTER_API_SYMBOL(FlutterEngine engine,
FlutterPlatformMessageResponseHandle response 
)

Collects the handle created using FlutterPlatformMessageCreateResponseHandle.

See also
FlutterPlatformMessageCreateResponseHandle()
Parameters
[in]engineA running engine instance.
[in]responseThe platform message response handle to collect. These handles are created using FlutterPlatformMessageCreateResponseHandle().
Returns
The result of the call.

Definition at line 3088 of file embedder.cc.

3090 {
3091 if (engine == nullptr) {
3092 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
3093 }
3094
3095 if (response == nullptr) {
3096 return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid response handle.");
3097 }
3098 delete response;
3099 return kSuccess;
3100}

References engine, kInvalidArguments, kSuccess, and LOG_EMBEDDER_ERROR.

Referenced by FlutterDesktopMessengerSendWithReply(), FlutterEngineGetProcAddresses(), InternalSendPlatformMessage(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ InferExternalViewEmbedderFromArgs()

static fml::StatusOr< std::unique_ptr< flutter::EmbedderExternalViewEmbedder > > InferExternalViewEmbedderFromArgs ( const FlutterCompositor compositor,
bool  enable_impeller 
)
static

Creates an EmbedderExternalViewEmbedder.

When a non-OK status is returned, engine startup should be halted.

Definition at line 1539 of file embedder.cc.

1540 {
1541 if (compositor == nullptr) {
1542 return std::unique_ptr<flutter::EmbedderExternalViewEmbedder>{nullptr};
1543 }
1544
1545 auto c_create_callback =
1546 SAFE_ACCESS(compositor, create_backing_store_callback, nullptr);
1547 auto c_collect_callback =
1548 SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
1549 auto c_present_callback =
1550 SAFE_ACCESS(compositor, present_layers_callback, nullptr);
1551 auto c_present_view_callback =
1552 SAFE_ACCESS(compositor, present_view_callback, nullptr);
1553 bool avoid_backing_store_cache =
1554 SAFE_ACCESS(compositor, avoid_backing_store_cache, false);
1555
1556 // Make sure the required callbacks are present
1557 if (!c_create_callback || !c_collect_callback) {
1559 "Required compositor callbacks absent.");
1560 }
1561 // Either the present view or the present layers callback must be provided.
1562 if ((!c_present_view_callback && !c_present_callback) ||
1563 (c_present_view_callback && c_present_callback)) {
1565 "Either present_layers_callback or "
1566 "present_view_callback must be provided but not both.");
1567 }
1568
1569 FlutterCompositor captured_compositor = *compositor;
1570
1572 create_render_target_callback =
1573 [captured_compositor, enable_impeller](
1574 GrDirectContext* context,
1575 const std::shared_ptr<impeller::AiksContext>& aiks_context,
1576 const auto& config) {
1577 return CreateEmbedderRenderTarget(&captured_compositor, config,
1578 context, aiks_context,
1579 enable_impeller);
1580 };
1581
1583 if (c_present_callback) {
1584 present_callback = [c_present_callback, user_data = compositor->user_data](
1585 FlutterViewId view_id, const auto& layers) {
1586 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1587 return c_present_callback(const_cast<const FlutterLayer**>(layers.data()),
1588 layers.size(), user_data);
1589 };
1590 } else {
1591 FML_DCHECK(c_present_view_callback != nullptr);
1592 present_callback = [c_present_view_callback,
1593 user_data = compositor->user_data](
1594 FlutterViewId view_id, const auto& layers) {
1595 TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
1596
1597 FlutterPresentViewInfo info = {
1599 .view_id = view_id,
1600 .layers = const_cast<const FlutterLayer**>(layers.data()),
1602 .user_data = user_data,
1603 };
1604
1605 return c_present_view_callback(&info);
1606 };
1607 }
1608
1609 return std::make_unique<flutter::EmbedderExternalViewEmbedder>(
1610 avoid_backing_store_cache, create_render_target_callback,
1611 present_callback);
1612}

References CreateEmbedderRenderTarget(), FML_DCHECK, fml::kInvalidArgument, layers, layers_count, SAFE_ACCESS, FlutterLayer::size, FlutterPresentViewInfo::struct_size, TRACE_EVENT0, user_data, FlutterCompositor::user_data, and view_id.

Referenced by FlutterEngineInitialize().

◆ InferMetalPlatformViewCreationCallback()

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 
)
static

Definition at line 517 of file embedder.cc.

524 {
525 if (config->type != kMetal) {
526 return nullptr;
527 }
528
529#ifdef SHELL_ENABLE_METAL
530 std::function<bool(flutter::GPUMTLTextureInfo texture)> metal_present =
531 [ptr = config->metal.present_drawable_callback,
533 FlutterMetalTexture embedder_texture;
534 embedder_texture.struct_size = sizeof(FlutterMetalTexture);
535 embedder_texture.texture = texture.texture;
536 embedder_texture.texture_id = texture.texture_id;
537 embedder_texture.user_data = texture.destruction_context;
538 embedder_texture.destruction_callback = texture.destruction_callback;
539 return ptr(user_data, &embedder_texture);
540 };
541 auto metal_get_texture =
543 const flutter::DlISize& frame_size) -> flutter::GPUMTLTextureInfo {
544 FlutterFrameInfo frame_info = {};
545 frame_info.struct_size = sizeof(FlutterFrameInfo);
546 frame_info.size = {static_cast<uint32_t>(frame_size.width),
547 static_cast<uint32_t>(frame_size.height)};
548 flutter::GPUMTLTextureInfo texture_info;
549
550 FlutterMetalTexture metal_texture = ptr(user_data, &frame_info);
551 texture_info.texture_id = metal_texture.texture_id;
552 texture_info.texture = metal_texture.texture;
553 texture_info.destruction_callback = metal_texture.destruction_callback;
554 texture_info.destruction_context = metal_texture.user_data;
555 return texture_info;
556 };
557
558 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
559 std::move(external_view_embedder);
560
561 std::unique_ptr<flutter::EmbedderSurface> embedder_surface;
562
563 if (enable_impeller) {
565 metal_dispatch_table = {
566 .present = metal_present,
567 .get_texture = metal_get_texture,
568 };
569 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalImpeller>(
570 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
573 metal_dispatch_table, view_embedder);
574 } else {
575#if !SLIMPELLER
577 {
578 .present = metal_present,
579 .get_texture = metal_get_texture,
580 };
581 embedder_surface = std::make_unique<flutter::EmbedderSurfaceMetalSkia>(
582 const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
585 metal_dispatch_table, view_embedder);
586#else // !SLIMPELLER
587 FML_LOG(FATAL) << "Impeller opt-out unavailable.";
588#endif // !SLIMPELLER
589 }
590
591 // The static leak checker gets confused by the use of fml::MakeCopyable.
592 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
593 return fml::MakeCopyable(
594 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
595 external_view_embedder = view_embedder](flutter::Shell& shell) mutable {
596 return std::make_unique<flutter::PlatformViewEmbedder>(
597 shell, // delegate
598 shell.GetTaskRunners(), // task runners
599 std::move(embedder_surface), // embedder surface
600 platform_dispatch_table, // platform dispatch table
601 std::move(external_view_embedder) // external view embedder
602 );
603 });
604#else // SHELL_ENABLE_METAL
605 FML_LOG(ERROR) << "This Flutter Engine does not support Metal rendering.";
606 return nullptr;
607#endif // SHELL_ENABLE_METAL
608}

References flutter::GPUMTLTextureInfo::destruction_callback, FlutterMetalTexture::destruction_callback, flutter::GPUMTLTextureInfo::destruction_context, FlutterMetalRendererConfig::device, FML_LOG, FlutterMetalRendererConfig::get_next_drawable_callback, flutter::Shell::GetTaskRunners(), kMetal, fml::MakeCopyable(), FlutterRendererConfig::metal, flutter::EmbedderSurfaceMetalImpeller::MetalDispatchTable::present, flutter::EmbedderSurfaceMetalSkia::MetalDispatchTable::present, FlutterMetalRendererConfig::present_command_queue, FlutterMetalRendererConfig::present_drawable_callback, FlutterFrameInfo::size, FlutterFrameInfo::struct_size, FlutterMetalTexture::struct_size, flutter::GPUMTLTextureInfo::texture, FlutterMetalTexture::texture, texture, flutter::GPUMTLTextureInfo::texture_id, FlutterMetalTexture::texture_id, FlutterRendererConfig::type, user_data, and FlutterMetalTexture::user_data.

Referenced by InferPlatformViewCreationCallback().

◆ InferOpenGLPlatformViewCreationCallback()

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 
)
inlinestatic

Definition at line 305 of file embedder.cc.

312 {
313#ifdef SHELL_ENABLE_GL
314 if (config->type != kOpenGL) {
315 return nullptr;
316 }
317
318 auto gl_make_current = [ptr = config->open_gl.make_current,
319 user_data]() -> bool { return ptr(user_data); };
320
321 auto gl_clear_current = [ptr = config->open_gl.clear_current,
322 user_data]() -> bool { return ptr(user_data); };
323
324 auto gl_present =
325 [present = config->open_gl.present,
326 present_with_info = config->open_gl.present_with_info,
327 user_data](flutter::GLPresentInfo gl_present_info) -> bool {
328 if (present) {
329 return present(user_data);
330 } else {
331 // Format the frame and buffer damages accordingly. Note that, since the
332 // current compute damage algorithm only returns one rectangle for damage
333 // we are assuming the number of rectangles provided in frame and buffer
334 // damage are always 1. Once the function that computes damage implements
335 // support for multiple damage rectangles, GLPresentInfo should also
336 // contain the number of damage rectangles.
337
338 std::optional<FlutterRect> frame_damage_rect;
339 if (gl_present_info.frame_damage) {
340 frame_damage_rect =
341 DlIRectToFlutterRect(*(gl_present_info.frame_damage));
342 }
343 std::optional<FlutterRect> buffer_damage_rect;
344 if (gl_present_info.buffer_damage) {
345 buffer_damage_rect =
346 DlIRectToFlutterRect(*(gl_present_info.buffer_damage));
347 }
348
349 FlutterDamage frame_damage{
350 .struct_size = sizeof(FlutterDamage),
351 .num_rects = frame_damage_rect ? size_t{1} : size_t{0},
352 .damage = frame_damage_rect ? &frame_damage_rect.value() : nullptr,
353 };
354 FlutterDamage buffer_damage{
355 .struct_size = sizeof(FlutterDamage),
356 .num_rects = buffer_damage_rect ? size_t{1} : size_t{0},
357 .damage = buffer_damage_rect ? &buffer_damage_rect.value() : nullptr,
358 };
359
360 // Construct the present information concerning the frame being rendered.
361 FlutterPresentInfo present_info = {
363 .fbo_id = gl_present_info.fbo_id,
364 .frame_damage = frame_damage,
365 .buffer_damage = buffer_damage,
366 };
367
368 return present_with_info(user_data, &present_info);
369 }
370 };
371
372 auto gl_fbo_callback =
373 [fbo_callback = config->open_gl.fbo_callback,
374 fbo_with_frame_info_callback =
376 user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
377 if (fbo_callback) {
378 return fbo_callback(user_data);
379 } else {
380 FlutterFrameInfo frame_info = {};
381 frame_info.struct_size = sizeof(FlutterFrameInfo);
382 frame_info.size = {gl_frame_info.width, gl_frame_info.height};
383 return fbo_with_frame_info_callback(user_data, &frame_info);
384 }
385 };
386
387 auto gl_populate_existing_damage =
388 [populate_existing_damage = config->open_gl.populate_existing_damage,
389 user_data](intptr_t id) -> flutter::GLFBOInfo {
390 // If no populate_existing_damage was provided, disable partial
391 // repaint.
392 if (!populate_existing_damage) {
393 return flutter::GLFBOInfo{
394 .fbo_id = static_cast<uint32_t>(id),
395 .existing_damage = std::nullopt,
396 };
397 }
398
399 // Given the FBO's ID, get its existing damage.
400 FlutterDamage existing_damage;
401 populate_existing_damage(user_data, id, &existing_damage);
402
403 std::optional<flutter::DlIRect> existing_damage_rect = std::nullopt;
404
405 // Verify that at least one damage rectangle was provided.
406 if (existing_damage.num_rects <= 0 || existing_damage.damage == nullptr) {
407 FML_LOG(INFO) << "No damage was provided. Forcing full repaint.";
408 } else {
409 existing_damage_rect = flutter::DlIRect();
410 for (size_t i = 0; i < existing_damage.num_rects; i++) {
411 existing_damage_rect = existing_damage_rect->Union(
412 FlutterRectToDlIRect(existing_damage.damage[i]));
413 }
414 }
415
416 // Pass the information about this FBO to the rendering backend.
417 return flutter::GLFBOInfo{
418 .fbo_id = static_cast<uint32_t>(id),
419 .existing_damage = existing_damage_rect,
420 };
421 };
422
423 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
424 std::function<bool()> gl_make_resource_current_callback = nullptr;
425 if (SAFE_ACCESS(open_gl_config, make_resource_current, nullptr) != nullptr) {
426 gl_make_resource_current_callback =
427 [ptr = config->open_gl.make_resource_current, user_data]() {
428 return ptr(user_data);
429 };
430 }
431
432 std::function<flutter::DlMatrix(void)> gl_surface_transformation_callback =
433 nullptr;
434 if (SAFE_ACCESS(open_gl_config, surface_transformation, nullptr) != nullptr) {
435 gl_surface_transformation_callback =
436 [ptr = config->open_gl.surface_transformation, user_data]() {
437 FlutterTransformation transformation = ptr(user_data);
438 // clang-format off
439 return flutter::DlMatrix(
440 transformation.scaleX, transformation.skewY, 0.0f, transformation.pers0,
441 transformation.skewX, transformation.scaleY, 0.0f, transformation.pers1,
442 0.0f, 0.0f, 1.0f, 0.0f,
443 transformation.transX, transformation.transY, 0.0f, transformation.pers2
444 );
445 // clang-format on
446 };
447
448 // If there is an external view embedder, ask it to apply the surface
449 // transformation to its surfaces as well.
450 if (external_view_embedder) {
451 external_view_embedder->SetSurfaceTransformationCallback(
452 gl_surface_transformation_callback);
453 }
454 }
455
456 flutter::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr;
457 if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) {
458 gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver,
459 user_data](const char* gl_proc_name) {
460 return ptr(user_data, gl_proc_name);
461 };
462 } else {
463#if FML_OS_LINUX || FML_OS_WIN
464 gl_proc_resolver = DefaultGLProcResolver;
465#endif // FML_OS_LINUX || FML_OS_WIN
466 }
467
468 bool fbo_reset_after_present =
469 SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false);
470
472 gl_make_current, // gl_make_current_callback
473 gl_clear_current, // gl_clear_current_callback
474 gl_present, // gl_present_callback
475 gl_fbo_callback, // gl_fbo_callback
476 gl_make_resource_current_callback, // gl_make_resource_current_callback
477 gl_surface_transformation_callback, // gl_surface_transformation_callback
478 gl_proc_resolver, // gl_proc_resolver
479 gl_populate_existing_damage, // gl_populate_existing_damage
480 };
481
482 return fml::MakeCopyable(
483 [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table,
484 enable_impeller,
485 external_view_embedder =
486 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
487 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
488 std::move(external_view_embedder);
489 if (enable_impeller) {
490 return std::make_unique<flutter::PlatformViewEmbedder>(
491 shell, // delegate
492 shell.GetTaskRunners(), // task runners
493 std::make_unique<flutter::EmbedderSurfaceGLImpeller>(
494 gl_dispatch_table, fbo_reset_after_present,
495 view_embedder), // embedder_surface
496 platform_dispatch_table, // embedder platform dispatch table
497 view_embedder // external view embedder
498 );
499 }
500 return std::make_unique<flutter::PlatformViewEmbedder>(
501 shell, // delegate
502 shell.GetTaskRunners(), // task runners
503 std::make_unique<flutter::EmbedderSurfaceGLSkia>(
504 gl_dispatch_table, fbo_reset_after_present,
505 view_embedder), // embedder_surface
506 platform_dispatch_table, // embedder platform dispatch table
507 view_embedder // external view embedder
508 );
509 });
510#else // SHELL_ENABLE_GL
511 FML_LOG(ERROR) << "This Flutter Engine does not support OpenGL rendering.";
512 return nullptr;
513#endif // SHELL_ENABLE_GL
514}

References FlutterOpenGLRendererConfig::clear_current, FlutterDamage::damage, FlutterOpenGLRendererConfig::fbo_callback, flutter::GLFBOInfo::fbo_id, FlutterOpenGLRendererConfig::fbo_with_frame_info_callback, FML_LOG, flutter::Shell::GetTaskRunners(), FlutterOpenGLRendererConfig::gl_proc_resolver, i, id, kOpenGL, FlutterOpenGLRendererConfig::make_current, FlutterOpenGLRendererConfig::make_resource_current, fml::MakeCopyable(), FlutterDamage::num_rects, FlutterRendererConfig::open_gl, FlutterTransformation::pers0, FlutterTransformation::pers1, FlutterTransformation::pers2, FlutterOpenGLRendererConfig::populate_existing_damage, FlutterOpenGLRendererConfig::present, FlutterOpenGLRendererConfig::present_with_info, SAFE_ACCESS, FlutterTransformation::scaleX, FlutterTransformation::scaleY, FlutterFrameInfo::size, FlutterTransformation::skewX, FlutterTransformation::skewY, FlutterDamage::struct_size, FlutterFrameInfo::struct_size, FlutterPresentInfo::struct_size, FlutterOpenGLRendererConfig::surface_transformation, FlutterTransformation::transX, FlutterTransformation::transY, FlutterRendererConfig::type, user_data, and FlutterUIntSize::width.

Referenced by InferPlatformViewCreationCallback().

◆ InferPlatformViewCreationCallback()

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 
)
static

Definition at line 811 of file embedder.cc.

818 {
819 if (config == nullptr) {
820 return nullptr;
821 }
822
823 switch (config->type) {
824 case kOpenGL:
826 config, user_data, platform_dispatch_table,
827 std::move(external_view_embedder), enable_impeller);
828 case kSoftware:
830 config, user_data, platform_dispatch_table,
831 std::move(external_view_embedder));
832 case kMetal:
834 config, user_data, platform_dispatch_table,
835 std::move(external_view_embedder), enable_impeller);
836 case kVulkan:
838 config, user_data, platform_dispatch_table,
839 std::move(external_view_embedder), enable_impeller);
840 default:
841 return nullptr;
842 }
843 return nullptr;
844}

References InferMetalPlatformViewCreationCallback(), InferOpenGLPlatformViewCreationCallback(), InferSoftwarePlatformViewCreationCallback(), InferVulkanPlatformViewCreationCallback(), kMetal, kOpenGL, kSoftware, kVulkan, FlutterRendererConfig::type, and user_data.

Referenced by FlutterEngineInitialize().

◆ InferSoftwarePlatformViewCreationCallback()

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 
)
static

Definition at line 774 of file embedder.cc.

780 {
781 if (config->type != kSoftware) {
782 return nullptr;
783 }
784
785 auto software_present_backing_store =
787 const void* allocation, size_t row_bytes, size_t height) -> bool {
788 return ptr(user_data, allocation, row_bytes, height);
789 };
790
792 software_dispatch_table = {
793 software_present_backing_store, // required
794 };
795
796 return fml::MakeCopyable(
797 [software_dispatch_table, platform_dispatch_table,
798 external_view_embedder =
799 std::move(external_view_embedder)](flutter::Shell& shell) mutable {
800 return std::make_unique<flutter::PlatformViewEmbedder>(
801 shell, // delegate
802 shell.GetTaskRunners(), // task runners
803 software_dispatch_table, // software dispatch table
804 platform_dispatch_table, // platform dispatch table
805 std::move(external_view_embedder) // external view embedder
806 );
807 });
808}

References flutter::Shell::GetTaskRunners(), height, kSoftware, fml::MakeCopyable(), FlutterRendererConfig::software, FlutterSoftwareRendererConfig::surface_present_callback, FlutterRendererConfig::type, and user_data.

Referenced by InferPlatformViewCreationCallback().

◆ InferVulkanPlatformViewCreationCallback()

static flutter::Shell::CreateCallback< flutter::PlatformView > InferVulkanPlatformViewCreationCallback ( const FlutterRendererConfig config,
void *  user_data,
const flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table,
std::unique_ptr< flutter::EmbedderExternalViewEmbedder external_view_embedder,
bool  enable_impeller 
)
static

Definition at line 611 of file embedder.cc.

618 {
619 if (config->type != kVulkan) {
620 return nullptr;
621 }
622
623#ifdef SHELL_ENABLE_VULKAN
624 std::function<void*(VkInstance, const char*)>
625 vulkan_get_instance_proc_address =
627 VkInstance instance, const char* proc_name) -> void* {
628 return ptr(user_data, instance, proc_name);
629 };
630
631 auto vulkan_get_next_image =
632 [ptr = config->vulkan.get_next_image_callback,
633 user_data](const flutter::DlISize& frame_size) -> FlutterVulkanImage {
634 FlutterFrameInfo frame_info = {
635 .struct_size = sizeof(FlutterFrameInfo),
636 .size = {static_cast<uint32_t>(frame_size.width),
637 static_cast<uint32_t>(frame_size.height)},
638 };
639
640 return ptr(user_data, &frame_info);
641 };
642
643 auto vulkan_present_image_callback =
644 [ptr = config->vulkan.present_image_callback, user_data](
645 VkImage image, VkFormat format) -> bool {
646 FlutterVulkanImage image_desc = {
648 .image = reinterpret_cast<uint64_t>(image),
649 .format = static_cast<uint32_t>(format),
650 };
651 return ptr(user_data, &image_desc);
652 };
653
654 auto vk_instance = static_cast<VkInstance>(config->vulkan.instance);
655 auto proc_addr =
656 vulkan_get_instance_proc_address(vk_instance, "vkGetInstanceProcAddr");
657
658 std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
659 std::move(external_view_embedder);
660
661#if IMPELLER_SUPPORTS_RENDERING
662 if (enable_impeller) {
664 vulkan_dispatch_table = {
666 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
667 .get_next_image = vulkan_get_next_image,
668 .present_image = vulkan_present_image_callback,
669 };
670
671 std::unique_ptr<flutter::EmbedderSurfaceVulkanImpeller> embedder_surface =
672 std::make_unique<flutter::EmbedderSurfaceVulkanImpeller>(
673 config->vulkan.version, vk_instance,
678 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
679 static_cast<VkDevice>(config->vulkan.device),
681 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
682 view_embedder);
683
684 return fml::MakeCopyable(
685 [embedder_surface = std::move(embedder_surface),
686 platform_dispatch_table,
687 external_view_embedder =
688 std::move(view_embedder)](flutter::Shell& shell) mutable {
689 return std::make_unique<flutter::PlatformViewEmbedder>(
690 shell, // delegate
691 shell.GetTaskRunners(), // task runners
692 std::move(embedder_surface), // embedder surface
693 platform_dispatch_table, // platform dispatch table
694 std::move(external_view_embedder) // external view embedder
695 );
696 });
697 } else {
699 {
701 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
702 .get_next_image = vulkan_get_next_image,
703 .present_image = vulkan_present_image_callback,
704 };
705
706 std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
707 std::make_unique<flutter::EmbedderSurfaceVulkan>(
708 config->vulkan.version, vk_instance,
713 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
714 static_cast<VkDevice>(config->vulkan.device),
716 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
717 view_embedder);
718
719 return fml::MakeCopyable(
720 [embedder_surface = std::move(embedder_surface),
721 platform_dispatch_table,
722 external_view_embedder =
723 std::move(view_embedder)](flutter::Shell& shell) mutable {
724 return std::make_unique<flutter::PlatformViewEmbedder>(
725 shell, // delegate
726 shell.GetTaskRunners(), // task runners
727 std::move(embedder_surface), // embedder surface
728 platform_dispatch_table, // platform dispatch table
729 std::move(external_view_embedder) // external view embedder
730 );
731 });
732 }
733#else
736 reinterpret_cast<PFN_vkGetInstanceProcAddr>(proc_addr),
737 .get_next_image = vulkan_get_next_image,
738 .present_image = vulkan_present_image_callback,
739 };
740
741 std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
742 std::make_unique<flutter::EmbedderSurfaceVulkan>(
743 config->vulkan.version, vk_instance,
748 static_cast<VkPhysicalDevice>(config->vulkan.physical_device),
749 static_cast<VkDevice>(config->vulkan.device),
751 static_cast<VkQueue>(config->vulkan.queue), vulkan_dispatch_table,
752 view_embedder);
753
754 return fml::MakeCopyable(
755 [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
756 external_view_embedder =
757 std::move(view_embedder)](flutter::Shell& shell) mutable {
758 return std::make_unique<flutter::PlatformViewEmbedder>(
759 shell, // delegate
760 shell.GetTaskRunners(), // task runners
761 std::move(embedder_surface), // embedder surface
762 platform_dispatch_table, // platform dispatch table
763 std::move(external_view_embedder) // external view embedder
764 );
765 });
766#endif // // IMPELLER_SUPPORTS_RENDERING
767#else // SHELL_ENABLE_VULKAN
768 FML_LOG(ERROR) << "This Flutter Engine does not support Vulkan rendering.";
769 return nullptr;
770#endif // SHELL_ENABLE_VULKAN
771}

References FlutterVulkanRendererConfig::device, FlutterVulkanRendererConfig::enabled_device_extension_count, FlutterVulkanRendererConfig::enabled_device_extensions, FlutterVulkanRendererConfig::enabled_instance_extension_count, FlutterVulkanRendererConfig::enabled_instance_extensions, FML_LOG, FlutterVulkanImage::format, format, flutter::EmbedderSurfaceVulkan::VulkanDispatchTable::get_instance_proc_address, flutter::EmbedderSurfaceVulkanImpeller::VulkanDispatchTable::get_instance_proc_address, FlutterVulkanRendererConfig::get_instance_proc_address_callback, FlutterVulkanRendererConfig::get_next_image_callback, flutter::Shell::GetTaskRunners(), image, instance, FlutterVulkanRendererConfig::instance, kVulkan, fml::MakeCopyable(), FlutterVulkanRendererConfig::physical_device, FlutterVulkanRendererConfig::present_image_callback, FlutterVulkanRendererConfig::queue, FlutterVulkanRendererConfig::queue_family_index, FlutterFrameInfo::struct_size, FlutterVulkanImage::struct_size, FlutterRendererConfig::type, user_data, FlutterVulkanRendererConfig::version, and FlutterRendererConfig::vulkan.

Referenced by InferPlatformViewCreationCallback().

◆ InternalSendPlatformMessage()

static FlutterEngineResult InternalSendPlatformMessage ( FLUTTER_API_SYMBOL(FlutterEngine engine,
const char *  channel,
const uint8_t *  data,
size_t  size,
FlutterDataCallback  data_callback,
void *  user_data 
)
static

Definition at line 2910 of file embedder.cc.

2916 {
2917 FlutterEngineResult result;
2918
2919 FlutterPlatformMessageResponseHandle* response_handle;
2921 engine, data_callback, user_data, &response_handle);
2922 if (result != kSuccess) {
2923 return result;
2924 }
2925
2927 sizeof(FlutterPlatformMessage), // struct_size
2928 channel, // channel
2929 data, // message
2930 size, // message_size
2931 response_handle, // response_handle
2932 };
2933
2935 // Whether `SendPlatformMessage` succeeds or not, the response handle must be
2936 // released.
2937 FlutterEngineResult release_result =
2939 if (result != kSuccess) {
2940 return result;
2941 }
2942
2943 return release_result;
2944}

References channel, data, engine, FlutterEngineSendPlatformMessage(), FlutterPlatformMessageCreateResponseHandle(), FlutterPlatformMessageReleaseResponseHandle(), kSuccess, message, and user_data.

Referenced by FlutterEngineSendKeyEvent().

◆ IsMetalRendererConfigValid()

static bool IsMetalRendererConfigValid ( const FlutterRendererConfig config)
static

Definition at line 191 of file embedder.cc.

191 {
192 if (config->type != kMetal) {
193 return false;
194 }
195
196 const FlutterMetalRendererConfig* metal_config = &config->metal;
197
198 bool device = SAFE_ACCESS(metal_config, device, nullptr);
199 bool command_queue =
200 SAFE_ACCESS(metal_config, present_command_queue, nullptr);
201
202 bool present = SAFE_ACCESS(metal_config, present_drawable_callback, nullptr);
203 bool get_texture =
204 SAFE_ACCESS(metal_config, get_next_drawable_callback, nullptr);
205
206 return device && command_queue && present && get_texture;
207}

References device, kMetal, FlutterRendererConfig::metal, SAFE_ACCESS, and FlutterRendererConfig::type.

Referenced by IsRendererValid().

◆ IsOpenGLRendererConfigValid()

static bool IsOpenGLRendererConfigValid ( const FlutterRendererConfig config)
static

Definition at line 158 of file embedder.cc.

158 {
159 if (config->type != kOpenGL) {
160 return false;
161 }
162
163 const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
164
165 if (!SAFE_EXISTS(open_gl_config, make_current) ||
166 !SAFE_EXISTS(open_gl_config, clear_current) ||
167 !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback,
168 fbo_with_frame_info_callback) ||
169 !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) {
170 return false;
171 }
172
173 return true;
174}

References kOpenGL, FlutterRendererConfig::open_gl, SAFE_EXISTS, SAFE_EXISTS_ONE_OF, and FlutterRendererConfig::type.

Referenced by IsRendererValid().

◆ IsRendererValid()

static bool IsRendererValid ( const FlutterRendererConfig config)
static

Definition at line 229 of file embedder.cc.

229 {
230 if (config == nullptr) {
231 return false;
232 }
233
234 switch (config->type) {
235 case kOpenGL:
236 return IsOpenGLRendererConfigValid(config);
237 case kSoftware:
238 return IsSoftwareRendererConfigValid(config);
239 case kMetal:
240 return IsMetalRendererConfigValid(config);
241 case kVulkan:
242 return IsVulkanRendererConfigValid(config);
243 default:
244 return false;
245 }
246
247 return false;
248}

References IsMetalRendererConfigValid(), IsOpenGLRendererConfigValid(), IsSoftwareRendererConfigValid(), IsVulkanRendererConfigValid(), kMetal, kOpenGL, kSoftware, kVulkan, and FlutterRendererConfig::type.

Referenced by FlutterEngineInitialize().

◆ IsSoftwareRendererConfigValid()

static bool IsSoftwareRendererConfigValid ( const FlutterRendererConfig config)
static

Definition at line 176 of file embedder.cc.

176 {
177 if (config->type != kSoftware) {
178 return false;
179 }
180
181 const FlutterSoftwareRendererConfig* software_config = &config->software;
182
183 if (SAFE_ACCESS(software_config, surface_present_callback, nullptr) ==
184 nullptr) {
185 return false;
186 }
187
188 return true;
189}

References kSoftware, SAFE_ACCESS, FlutterRendererConfig::software, and FlutterRendererConfig::type.

Referenced by IsRendererValid().

◆ IsVulkanRendererConfigValid()

static bool IsVulkanRendererConfigValid ( const FlutterRendererConfig config)
static

Definition at line 209 of file embedder.cc.

209 {
210 if (config->type != kVulkan) {
211 return false;
212 }
213
214 const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan;
215
216 if (!SAFE_EXISTS(vulkan_config, instance) ||
217 !SAFE_EXISTS(vulkan_config, physical_device) ||
218 !SAFE_EXISTS(vulkan_config, device) ||
219 !SAFE_EXISTS(vulkan_config, queue) ||
220 !SAFE_EXISTS(vulkan_config, get_instance_proc_address_callback) ||
221 !SAFE_EXISTS(vulkan_config, get_next_image_callback) ||
222 !SAFE_EXISTS(vulkan_config, present_image_callback)) {
223 return false;
224 }
225
226 return true;
227}

References device, instance, kVulkan, physical_device, queue, SAFE_EXISTS, FlutterRendererConfig::type, and FlutterRendererConfig::vulkan.

Referenced by IsRendererValid().

◆ LogEmbedderError()

static FlutterEngineResult LogEmbedderError ( FlutterEngineResult  code,
const char *  reason,
const char *  code_name,
const char *  function,
const char *  file,
int  line 
)
static

Definition at line 134 of file embedder.cc.

139 {
140#if FML_OS_WIN
141 constexpr char kSeparator = '\\';
142#else
143 constexpr char kSeparator = '/';
144#endif
145 const auto file_base =
146 (::strrchr(file, kSeparator) ? strrchr(file, kSeparator) + 1 : file);
147 char error[256] = {};
148 snprintf(error, (sizeof(error) / sizeof(char)),
149 "%s (%d): '%s' returned '%s'. %s", file_base, line, function,
150 code_name, reason);
151 std::cerr << error << std::endl;
152 return code;
153}

References error, and function.

◆ MakeRenderTargetFromBackingStoreImpeller() [1/2]

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 FlutterMetalBackingStore metal 
)
static

Definition at line 1233 of file embedder.cc.

1238 {
1239#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING)
1240 if (!metal->texture.texture) {
1241 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
1242 return nullptr;
1243 }
1244
1245 const auto size = impeller::ISize(config.size.width, config.size.height);
1246
1247 impeller::TextureDescriptor resolve_tex_desc;
1248 resolve_tex_desc.size = size;
1251 resolve_tex_desc.usage = impeller::TextureUsage::kRenderTarget |
1253
1254 auto resolve_tex = impeller::WrapTextureMTL(
1255 resolve_tex_desc, metal->texture.texture,
1257 user_data = metal->texture.user_data]() { callback(user_data); });
1258 if (!resolve_tex) {
1259 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
1260 return nullptr;
1261 }
1262
1263 aiks_context->GetContext()->UpdateOffscreenLayerPixelFormat(
1264 resolve_tex->GetTextureDescriptor().format);
1265
1266 resolve_tex->SetLabel("ImpellerBackingStoreResolve");
1267
1268 impeller::TextureDescriptor msaa_tex_desc;
1272 msaa_tex_desc.format = resolve_tex->GetTextureDescriptor().format;
1273 msaa_tex_desc.size = size;
1275
1276 auto msaa_tex =
1277 aiks_context->GetContext()->GetResourceAllocator()->CreateTexture(
1278 msaa_tex_desc);
1279 if (!msaa_tex) {
1280 FML_LOG(ERROR) << "Could not allocate MSAA color texture.";
1281 return nullptr;
1282 }
1283 msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA");
1284
1286 color0.texture = msaa_tex;
1290 color0.resolve_texture = resolve_tex;
1291
1292 impeller::RenderTarget render_target_desc;
1293 render_target_desc.SetColorAttachment(color0, 0u);
1294
1295 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1296 backing_store, aiks_context,
1297 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1298 on_release, fml::closure());
1299#else
1300 return nullptr;
1301#endif
1302}

References callback, impeller::ColorAttachment::clear_color, impeller::Color::DarkSlateGray(), FlutterMetalTexture::destruction_callback, FML_LOG, impeller::TextureDescriptor::format, FlutterSize::height, impeller::kClear, impeller::kCount1, impeller::kCount4, impeller::kDevicePrivate, impeller::kDeviceTransient, impeller::kMultisampleResolve, impeller::kRenderTarget, impeller::kShaderRead, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::TextureDescriptor::size, FlutterBackingStoreConfig::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, FlutterMetalTexture::texture, FlutterMetalBackingStore::texture, impeller::TextureDescriptor::type, impeller::TextureDescriptor::usage, user_data, FlutterMetalTexture::user_data, FlutterSize::width, and impeller::WrapTextureMTL().

◆ MakeRenderTargetFromBackingStoreImpeller() [2/2]

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 
)
static

Definition at line 1139 of file embedder.cc.

1144 {
1145#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
1146 auto format = FlutterFormatToImpellerPixelFormat(framebuffer->target);
1147 if (!format.has_value()) {
1148 return nullptr;
1149 }
1150
1151 const auto& gl_context =
1152 impeller::ContextGLES::Cast(*aiks_context->GetContext());
1153 const bool implicit_msaa = aiks_context->GetContext()
1154 ->GetCapabilities()
1155 ->SupportsImplicitResolvingMSAA();
1156 const auto size = impeller::ISize(config.size.width, config.size.height);
1157
1158 impeller::TextureDescriptor color0_tex;
1159 if (implicit_msaa) {
1162 } else {
1165 }
1166 color0_tex.format = format.value();
1167 color0_tex.size = size;
1168 color0_tex.usage = static_cast<impeller::TextureUsageMask>(
1171
1174 gl_context.GetReactor(), color0_tex, framebuffer->name);
1177 if (implicit_msaa) {
1179 color0.resolve_texture = color0.texture;
1180 } else {
1182 }
1183
1184 impeller::TextureDescriptor depth_stencil_texture_desc;
1185 depth_stencil_texture_desc.format = impeller::PixelFormat::kD24UnormS8Uint;
1186 depth_stencil_texture_desc.size = size;
1187 depth_stencil_texture_desc.usage = static_cast<impeller::TextureUsageMask>(
1189 if (implicit_msaa) {
1190 depth_stencil_texture_desc.type =
1192 depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount4;
1193 } else {
1194 depth_stencil_texture_desc.type = impeller::TextureType::kTexture2D;
1195 depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount1;
1196 }
1197
1198 auto depth_stencil_tex = impeller::TextureGLES::CreatePlaceholder(
1199 gl_context.GetReactor(), depth_stencil_texture_desc);
1200
1202 depth0.clear_depth = 0;
1203 depth0.texture = depth_stencil_tex;
1206
1208 stencil0.clear_stencil = 0;
1209 stencil0.texture = depth_stencil_tex;
1212
1213 impeller::RenderTarget render_target_desc;
1214
1215 render_target_desc.SetColorAttachment(color0, 0u);
1216 render_target_desc.SetDepthAttachment(depth0);
1217 render_target_desc.SetStencilAttachment(stencil0);
1218
1219 fml::closure framebuffer_destruct =
1220 [callback = framebuffer->destruction_callback,
1221 user_data = framebuffer->user_data]() { callback(user_data); };
1222
1223 return std::make_unique<flutter::EmbedderRenderTargetImpeller>(
1224 backing_store, aiks_context,
1225 std::make_unique<impeller::RenderTarget>(std::move(render_target_desc)),
1226 on_release, framebuffer_destruct);
1227#else
1228 return nullptr;
1229#endif
1230}

References callback, impeller::BackendCast< ContextGLES, Context >::Cast(), impeller::ColorAttachment::clear_color, impeller::DepthAttachment::clear_depth, impeller::StencilAttachment::clear_stencil, impeller::TextureGLES::CreatePlaceholder(), impeller::Color::DarkSlateGray(), FlutterOpenGLFramebuffer::destruction_callback, impeller::TextureDescriptor::format, format, FlutterSize::height, impeller::kClear, impeller::kCount1, impeller::kCount4, impeller::kD24UnormS8Uint, impeller::kDevicePrivate, impeller::kDontCare, impeller::kMultisampleResolve, impeller::kRenderTarget, impeller::kStore, impeller::kTexture2D, impeller::kTexture2DMultisample, impeller::Attachment::load_action, FlutterOpenGLFramebuffer::name, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetDepthAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, FlutterBackingStoreConfig::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, FlutterOpenGLFramebuffer::target, impeller::Attachment::texture, impeller::TextureDescriptor::type, impeller::TextureDescriptor::usage, user_data, FlutterOpenGLFramebuffer::user_data, FlutterSize::width, and impeller::TextureGLES::WrapFBO().

Referenced by CreateEmbedderRenderTarget().

◆ MakeRenderTargetFromSkSurface() [1/2]

static std::unique_ptr< flutter::EmbedderRenderTarget > MakeRenderTargetFromSkSurface ( FlutterBackingStore  backing_store,
sk_sp< SkSurface >  skia_surface,
fml::closure  on_release 
)
static

Definition at line 1372 of file embedder.cc.

1374 {
1375 return MakeRenderTargetFromSkSurface(backing_store, std::move(skia_surface),
1376 std::move(on_release), nullptr, nullptr);
1377}

References MakeRenderTargetFromSkSurface().

◆ MakeRenderTargetFromSkSurface() [2/2]

static std::unique_ptr< flutter::EmbedderRenderTarget > MakeRenderTargetFromSkSurface ( FlutterBackingStore  backing_store,
sk_sp< SkSurface >  skia_surface,
fml::closure  on_release,
flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback  on_make_current,
flutter::EmbedderRenderTarget::MakeOrClearCurrentCallback  on_clear_current 
)
static

Definition at line 1356 of file embedder.cc.

1362 {
1363 if (!skia_surface) {
1364 return nullptr;
1365 }
1366 return std::make_unique<flutter::EmbedderRenderTargetSkia>(
1367 backing_store, std::move(skia_surface), std::move(on_release),
1368 std::move(on_make_current), std::move(on_clear_current));
1369}

Referenced by CreateEmbedderRenderTarget(), and MakeRenderTargetFromSkSurface().

◆ MakeSkSurfaceFromBackingStore() [1/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterMetalBackingStore metal 
)
static

Definition at line 1075 of file embedder.cc.

1078 {
1079#if defined(SHELL_ENABLE_METAL) && !SLIMPELLER
1080 GrMtlTextureInfo texture_info;
1081 if (!metal->texture.texture) {
1082 FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
1083 return nullptr;
1084 }
1085 sk_cfp<FlutterMetalTextureHandle> mtl_texture;
1086 mtl_texture.retain(metal->texture.texture);
1087 texture_info.fTexture = mtl_texture;
1088 GrBackendTexture backend_texture =
1089 GrBackendTextures::MakeMtl(config.size.width, //
1090 config.size.height, //
1091 skgpu::Mipmapped::kNo, //
1092 texture_info //
1093 );
1094
1095 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
1096
1097 auto surface = SkSurfaces::WrapBackendTexture(
1098 context, // context
1099 backend_texture, // back-end texture
1100 kTopLeft_GrSurfaceOrigin, // surface origin
1101 1, // sample count
1102 kBGRA_8888_SkColorType, // color type
1103 nullptr, // color space
1104 &surface_properties, // surface properties
1105 static_cast<SkSurfaces::TextureReleaseProc>(
1106 metal->texture.destruction_callback), // release proc
1107 metal->texture.user_data // release context
1108 );
1109
1110 if (!surface) {
1111 FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
1112 return nullptr;
1113 }
1114
1115 return surface;
1116#else
1117 return nullptr;
1118#endif
1119}

References FlutterMetalTexture::destruction_callback, FML_LOG, FlutterSize::height, FlutterBackingStoreConfig::size, surface, FlutterMetalTexture::texture, FlutterMetalBackingStore::texture, FlutterMetalTexture::user_data, and FlutterSize::width.

◆ MakeSkSurfaceFromBackingStore() [2/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterOpenGLFramebuffer framebuffer 
)
static

Definition at line 892 of file embedder.cc.

895 {
896#ifdef SHELL_ENABLE_GL
897 GrGLFramebufferInfo framebuffer_info = {};
898 framebuffer_info.fFormat = framebuffer->target;
899 framebuffer_info.fFBOID = framebuffer->name;
900
901 auto backend_render_target =
902 GrBackendRenderTargets::MakeGL(config.size.width, // width
903 config.size.height, // height
904 1, // sample count
905 0, // stencil bits
906 framebuffer_info // framebuffer info
907 );
908
909 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
910
911 std::optional<SkColorType> color_type =
912 FlutterFormatToSkColorType(framebuffer->target);
913 if (!color_type) {
914 return nullptr;
915 }
916
917 auto surface = SkSurfaces::WrapBackendRenderTarget(
918 context, // context
919 backend_render_target, // backend render target
920 kBottomLeft_GrSurfaceOrigin, // surface origin
921 color_type.value(), // color type
922 SkColorSpace::MakeSRGB(), // color space
923 &surface_properties, // surface properties
924 static_cast<SkSurfaces::RenderTargetReleaseProc>(
925 framebuffer->destruction_callback), // release proc
926 framebuffer->user_data // release context
927 );
928
929 if (!surface) {
930 FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
931 return nullptr;
932 }
933 return surface;
934#else
935 return nullptr;
936#endif
937}

References color_type, FlutterOpenGLFramebuffer::destruction_callback, FML_LOG, FlutterSize::height, FlutterOpenGLFramebuffer::name, FlutterBackingStoreConfig::size, surface, FlutterOpenGLFramebuffer::target, FlutterOpenGLFramebuffer::user_data, and FlutterSize::width.

◆ MakeSkSurfaceFromBackingStore() [3/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterOpenGLSurface surface 
)
static

Definition at line 939 of file embedder.cc.

942 {
943#ifdef SHELL_ENABLE_GL
944 GrGLFramebufferInfo framebuffer_info = {};
945 framebuffer_info.fFormat = SAFE_ACCESS(surface, format, GL_BGRA8_EXT);
946 framebuffer_info.fFBOID = 0;
947
948 auto backend_render_target =
949 GrBackendRenderTargets::MakeGL(config.size.width, // width
950 config.size.height, // height
951 1, // sample count
952 0, // stencil bits
953 framebuffer_info // framebuffer info
954 );
955
956 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
957
958 std::optional<SkColorType> color_type =
959 FlutterFormatToSkColorType(surface->format);
960 if (!color_type) {
961 return nullptr;
962 }
963
964 auto sk_surface = SkSurfaces::WrapBackendRenderTarget(
965 context, // context
966 backend_render_target, // backend render target
967 kBottomLeft_GrSurfaceOrigin, // surface origin
968 color_type.value(), // color type
969 SkColorSpace::MakeSRGB(), // color space
970 &surface_properties, // surface properties
971 static_cast<SkSurfaces::RenderTargetReleaseProc>(
972 surface->destruction_callback), // release proc
973 surface->user_data // release context
974 );
975
976 if (!sk_surface) {
977 FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
978 return nullptr;
979 }
980 return sk_surface;
981#else
982 return nullptr;
983#endif
984}

References color_type, FML_LOG, format, FlutterSize::height, SAFE_ACCESS, FlutterBackingStoreConfig::size, surface, and FlutterSize::width.

◆ MakeSkSurfaceFromBackingStore() [4/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterOpenGLTexture texture 
)
static

Definition at line 846 of file embedder.cc.

849 {
850#ifdef SHELL_ENABLE_GL
851 GrGLTextureInfo texture_info;
852 texture_info.fTarget = texture->target;
853 texture_info.fID = texture->name;
854 texture_info.fFormat = texture->format;
855
856 GrBackendTexture backend_texture =
857 GrBackendTextures::MakeGL(config.size.width, config.size.height,
858 skgpu::Mipmapped::kNo, texture_info);
859
860 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
861
862 std::optional<SkColorType> color_type =
863 FlutterFormatToSkColorType(texture->format);
864 if (!color_type) {
865 return nullptr;
866 }
867
868 auto surface = SkSurfaces::WrapBackendTexture(
869 context, // context
870 backend_texture, // back-end texture
871 kBottomLeft_GrSurfaceOrigin, // surface origin
872 1, // sample count
873 color_type.value(), // color type
874 SkColorSpace::MakeSRGB(), // color space
875 &surface_properties, // surface properties
876 static_cast<SkSurfaces::TextureReleaseProc>(
877 texture->destruction_callback), // release proc
878 texture->user_data // release context
879 );
880
881 if (!surface) {
882 FML_LOG(ERROR) << "Could not wrap embedder supplied render texture.";
883 return nullptr;
884 }
885
886 return surface;
887#else
888 return nullptr;
889#endif
890}

References color_type, FML_LOG, FlutterSize::height, FlutterBackingStoreConfig::size, surface, texture, and FlutterSize::width.

Referenced by CreateEmbedderRenderTarget().

◆ MakeSkSurfaceFromBackingStore() [5/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterSoftwareBackingStore software 
)
static

Definition at line 986 of file embedder.cc.

989 {
990 const auto image_info =
991 SkImageInfo::MakeN32Premul(config.size.width, config.size.height);
992
993 struct Captures {
994 VoidCallback destruction_callback;
995 void* user_data;
996 };
997 auto captures = std::make_unique<Captures>();
998 captures->destruction_callback = software->destruction_callback;
999 captures->user_data = software->user_data;
1000 auto release_proc = [](void* pixels, void* context) {
1001 auto captures = reinterpret_cast<Captures*>(context);
1002 if (captures->destruction_callback) {
1003 captures->destruction_callback(captures->user_data);
1004 }
1005 delete captures;
1006 };
1007
1008 auto surface =
1009 SkSurfaces::WrapPixels(image_info, // image info
1010 const_cast<void*>(software->allocation), // pixels
1011 software->row_bytes, // row bytes
1012 release_proc, // release proc
1013 captures.get() // get context
1014 );
1015
1016 if (!surface) {
1017 FML_LOG(ERROR)
1018 << "Could not wrap embedder supplied software render buffer.";
1019 if (software->destruction_callback) {
1020 software->destruction_callback(software->user_data);
1021 }
1022 return nullptr;
1023 }
1024 if (surface) {
1025 captures.release(); // Skia has assumed ownership of the struct.
1026 }
1027 return surface;
1028}

References FlutterSoftwareBackingStore::allocation, FlutterSoftwareBackingStore::destruction_callback, FML_LOG, FlutterSize::height, FlutterSoftwareBackingStore::row_bytes, FlutterBackingStoreConfig::size, surface, user_data, FlutterSoftwareBackingStore::user_data, and FlutterSize::width.

◆ MakeSkSurfaceFromBackingStore() [6/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterSoftwareBackingStore2 software 
)
static

Definition at line 1030 of file embedder.cc.

1033 {
1034 const auto color_info = getSkColorInfo(software->pixel_format);
1035 if (!color_info) {
1036 return nullptr;
1037 }
1038
1039 const auto image_info = SkImageInfo::Make(
1040 SkISize::Make(config.size.width, config.size.height), *color_info);
1041
1042 struct Captures {
1043 VoidCallback destruction_callback;
1044 void* user_data;
1045 };
1046 auto captures = std::make_unique<Captures>();
1047 captures->destruction_callback = software->destruction_callback;
1048 captures->user_data = software->user_data;
1049 auto release_proc = [](void* pixels, void* context) {
1050 auto captures = reinterpret_cast<Captures*>(context);
1051 if (captures->destruction_callback) {
1052 captures->destruction_callback(captures->user_data);
1053 }
1054 };
1055
1056 auto surface =
1057 SkSurfaces::WrapPixels(image_info, // image info
1058 const_cast<void*>(software->allocation), // pixels
1059 software->row_bytes, // row bytes
1060 release_proc, // release proc
1061 captures.release() // release context
1062 );
1063
1064 if (!surface) {
1065 FML_LOG(ERROR)
1066 << "Could not wrap embedder supplied software render buffer.";
1067 if (software->destruction_callback) {
1068 software->destruction_callback(software->user_data);
1069 }
1070 return nullptr;
1071 }
1072 return surface;
1073}

References FlutterSoftwareBackingStore2::allocation, FlutterSoftwareBackingStore2::destruction_callback, FML_LOG, getSkColorInfo(), FlutterSize::height, FlutterSoftwareBackingStore2::pixel_format, FlutterSoftwareBackingStore2::row_bytes, FlutterBackingStoreConfig::size, surface, user_data, FlutterSoftwareBackingStore2::user_data, and FlutterSize::width.

◆ MakeSkSurfaceFromBackingStore() [7/7]

static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore ( GrDirectContext *  context,
const FlutterBackingStoreConfig config,
const FlutterVulkanBackingStore vulkan 
)
static

Definition at line 1304 of file embedder.cc.

1307 {
1308#ifdef SHELL_ENABLE_VULKAN
1309 if (!vulkan->image) {
1310 FML_LOG(ERROR) << "Embedder supplied null Vulkan image.";
1311 return nullptr;
1312 }
1313 GrVkImageInfo image_info = {
1314 .fImage = reinterpret_cast<VkImage>(vulkan->image->image),
1315 .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
1316 .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
1317 .fFormat = static_cast<VkFormat>(vulkan->image->format),
1318 .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
1319 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1320 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1321 VK_IMAGE_USAGE_SAMPLED_BIT,
1322 .fSampleCount = 1,
1323 .fLevelCount = 1,
1324 };
1325 auto backend_texture = GrBackendTextures::MakeVk(
1326 config.size.width, config.size.height, image_info);
1327
1328 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
1329
1330 auto surface = SkSurfaces::WrapBackendTexture(
1331 context, // context
1332 backend_texture, // back-end texture
1333 kTopLeft_GrSurfaceOrigin, // surface origin
1334 1, // sample count
1336 static_cast<VkFormat>(vulkan->image->format)), // color type
1337 SkColorSpace::MakeSRGB(), // color space
1338 &surface_properties, // surface properties
1339 static_cast<SkSurfaces::TextureReleaseProc>(
1340 vulkan->destruction_callback), // release proc
1341 vulkan->user_data // release context
1342 );
1343
1344 if (!surface) {
1345 FML_LOG(ERROR) << "Could not wrap embedder supplied Vulkan render texture.";
1346 return nullptr;
1347 }
1348
1349 return surface;
1350#else
1351 return nullptr;
1352#endif
1353}

References flutter::GPUSurfaceVulkan::ColorTypeFromFormat(), FML_LOG, FlutterSize::height, FlutterBackingStoreConfig::size, surface, and FlutterSize::width.

◆ MakeViewportMetricsFromWindowMetrics()

static std::variant< flutter::ViewportMetrics, std::string > MakeViewportMetricsFromWindowMetrics ( const FlutterWindowMetricsEvent flutter_metrics)
static

Definition at line 1616 of file embedder.cc.

1617 {
1618 if (flutter_metrics == nullptr) {
1619 return "Invalid metrics handle.";
1620 }
1621
1623
1624 metrics.physical_width = SAFE_ACCESS(flutter_metrics, width, 0.0);
1625 metrics.physical_height = SAFE_ACCESS(flutter_metrics, height, 0.0);
1626
1627 if (SAFE_ACCESS(flutter_metrics, has_constraints, false)) {
1629 flutter_metrics, min_width_constraint, metrics.physical_width);
1631 flutter_metrics, max_width_constraint, metrics.physical_width);
1633 flutter_metrics, min_height_constraint, metrics.physical_height);
1635 flutter_metrics, max_height_constraint, metrics.physical_height);
1636 } else {
1641 }
1642
1643 if (metrics.physical_width < metrics.physical_min_width_constraint ||
1647 return "Window metrics are invalid. Width and height must be within the "
1648 "specified constraints.";
1649 }
1650
1651 metrics.device_pixel_ratio = SAFE_ACCESS(flutter_metrics, pixel_ratio, 1.0);
1652 metrics.physical_view_inset_top =
1653 SAFE_ACCESS(flutter_metrics, physical_view_inset_top, 0.0);
1655 SAFE_ACCESS(flutter_metrics, physical_view_inset_right, 0.0);
1657 SAFE_ACCESS(flutter_metrics, physical_view_inset_bottom, 0.0);
1658 metrics.physical_view_inset_left =
1659 SAFE_ACCESS(flutter_metrics, physical_view_inset_left, 0.0);
1660 metrics.display_id = SAFE_ACCESS(flutter_metrics, display_id, 0);
1661
1662 if (metrics.device_pixel_ratio <= 0.0) {
1663 return "Device pixel ratio was invalid. It must be greater than zero.";
1664 }
1665
1666 if (metrics.physical_view_inset_top < 0 ||
1667 metrics.physical_view_inset_right < 0 ||
1668 metrics.physical_view_inset_bottom < 0 ||
1669 metrics.physical_view_inset_left < 0) {
1670 return "Physical view insets are invalid. They must be non-negative.";
1671 }
1672
1673 if (metrics.physical_view_inset_top > metrics.physical_height ||
1674 metrics.physical_view_inset_right > metrics.physical_width ||
1675 metrics.physical_view_inset_bottom > metrics.physical_height ||
1676 metrics.physical_view_inset_left > metrics.physical_width) {
1677 return "Physical view insets are invalid. They cannot be greater than "
1678 "physical height or width.";
1679 }
1680
1681 return metrics;
1682}

References flutter::ViewportMetrics::device_pixel_ratio, flutter::ViewportMetrics::display_id, height, flutter::ViewportMetrics::physical_height, flutter::ViewportMetrics::physical_max_height_constraint, flutter::ViewportMetrics::physical_max_width_constraint, flutter::ViewportMetrics::physical_min_height_constraint, flutter::ViewportMetrics::physical_min_width_constraint, flutter::ViewportMetrics::physical_view_inset_bottom, flutter::ViewportMetrics::physical_view_inset_left, flutter::ViewportMetrics::physical_view_inset_right, flutter::ViewportMetrics::physical_view_inset_top, flutter::ViewportMetrics::physical_width, SAFE_ACCESS, and width.

Referenced by FlutterEngineAddView(), and FlutterEngineSendWindowMetricsEvent().

◆ MapKeyEventDeviceType()

◆ MapKeyEventType()

static flutter::KeyEventType MapKeyEventType ( FlutterKeyEventType  event_kind)
inlinestatic

◆ PointerDataButtonsForLegacyEvent()

◆ PopulateAOTSnapshotMappingCallbacks()

void PopulateAOTSnapshotMappingCallbacks ( const FlutterProjectArgs args,
flutter::Settings settings 
)

Definition at line 1816 of file embedder.cc.

1818 { // NOLINT(google-runtime-references)
1819 // There are no ownership concerns here as all mappings are owned by the
1820 // embedder and not the engine.
1821 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
1822 return [mapping, size]() {
1823 return std::make_unique<fml::NonOwnedMapping>(mapping, size);
1824 };
1825 };
1826
1827 if (SAFE_ACCESS(args, aot_data, nullptr) != nullptr) {
1828 settings.vm_snapshot_data =
1829 make_mapping_callback(args->aot_data->vm_snapshot_data, 0);
1830
1831 settings.vm_snapshot_instr =
1832 make_mapping_callback(args->aot_data->vm_snapshot_instrs, 0);
1833
1834 settings.isolate_snapshot_data =
1835 make_mapping_callback(args->aot_data->vm_isolate_data, 0);
1836
1837 settings.isolate_snapshot_instr =
1838 make_mapping_callback(args->aot_data->vm_isolate_instrs, 0);
1839 }
1840
1841 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1842 settings.vm_snapshot_data = make_mapping_callback(
1843 args->vm_snapshot_data, SAFE_ACCESS(args, vm_snapshot_data_size, 0));
1844 }
1845
1846 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1847 settings.vm_snapshot_instr = make_mapping_callback(
1848 args->vm_snapshot_instructions,
1849 SAFE_ACCESS(args, vm_snapshot_instructions_size, 0));
1850 }
1851
1852 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1853 settings.isolate_snapshot_data =
1854 make_mapping_callback(args->isolate_snapshot_data,
1855 SAFE_ACCESS(args, isolate_snapshot_data_size, 0));
1856 }
1857
1858 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1859 settings.isolate_snapshot_instr = make_mapping_callback(
1860 args->isolate_snapshot_instructions,
1861 SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0));
1862 }
1863}

References args, flutter::Settings::isolate_snapshot_data, flutter::Settings::isolate_snapshot_instr, SAFE_ACCESS, flutter::Settings::vm_snapshot_data, and flutter::Settings::vm_snapshot_instr.

Referenced by FlutterEngineInitialize().

◆ PopulateJITSnapshotMappingCallbacks()

void PopulateJITSnapshotMappingCallbacks ( const FlutterProjectArgs args,
flutter::Settings settings 
)

Definition at line 1773 of file embedder.cc.

1774 {
1775 auto make_mapping_callback = [](const char* path, bool executable) {
1776 return [path, executable]() {
1777 if (executable) {
1779 } else {
1781 }
1782 };
1783 };
1784
1785 // Users are allowed to specify only certain snapshots if they so desire.
1786 if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
1787 settings.vm_snapshot_data = make_mapping_callback(
1788 reinterpret_cast<const char*>(args->vm_snapshot_data), false);
1789 }
1790
1791 if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
1792 settings.vm_snapshot_instr = make_mapping_callback(
1793 reinterpret_cast<const char*>(args->vm_snapshot_instructions), true);
1794 }
1795
1796 if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
1797 settings.isolate_snapshot_data = make_mapping_callback(
1798 reinterpret_cast<const char*>(args->isolate_snapshot_data), false);
1799 }
1800
1801 if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
1802 settings.isolate_snapshot_instr = make_mapping_callback(
1803 reinterpret_cast<const char*>(args->isolate_snapshot_instructions),
1804 true);
1805 }
1806
1807#if !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
1808 settings.dart_library_sources_kernel = []() {
1809 return std::make_unique<fml::NonOwnedMapping>(kPlatformStrongDill,
1811 };
1812#endif // !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE ==
1813 // FLUTTER_RUNTIME_MODE_DEBUG)
1814}

References args, fml::FileMapping::CreateReadExecute(), fml::FileMapping::CreateReadOnly(), flutter::Settings::dart_library_sources_kernel, flutter::Settings::isolate_snapshot_data, flutter::Settings::isolate_snapshot_instr, kPlatformStrongDill, kPlatformStrongDillSize, SAFE_ACCESS, flutter::Settings::vm_snapshot_data, and flutter::Settings::vm_snapshot_instr.

Referenced by FlutterEngineInitialize().

◆ ToPointerDataChange()

◆ ToPointerDataKind()

◆ ToPointerDataSignalKind()

Variable Documentation

◆ kFlutterImplicitViewId

◆ kFlutterKeyDataChannel

const char* kFlutterKeyDataChannel = "flutter/keydata"

Definition at line 132 of file embedder.cc.

Referenced by FlutterEngineSendKeyEvent().

◆ kFlutterSemanticsCustomActionIdBatchEnd

const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1

FlutterSemanticsCustomAction ID used as a sentinel to signal the end of a batch of semantics custom action updates. This is unused if using FlutterUpdateSemanticsCallback2.

Definition at line 108 of file embedder.cc.

Referenced by CreateEmbedderSemanticsUpdateCallbackV1(), and flutter::testing::TEST_F().

◆ kFlutterSemanticsNodeIdBatchEnd

const int32_t kFlutterSemanticsNodeIdBatchEnd = -1

FlutterSemanticsNode ID used as a sentinel to signal the end of a batch of semantics node updates. This is unused if using FlutterUpdateSemanticsCallback2.

Definition at line 107 of file embedder.cc.

Referenced by CreateEmbedderSemanticsUpdateCallbackV1(), flutter::testing::TEST_F(), flutter::testing::TEST_F(), and flutter::testing::TEST_F().

◆ kPlatformStrongDill

const uint8_t kPlatformStrongDill[]
extern

◆ kPlatformStrongDillSize

const intptr_t kPlatformStrongDillSize
extern