diff --git a/embedder/embedder.h b/embedder/embedder.h index 67c5437e..66a25c7f 100644 --- a/embedder/embedder.h +++ b/embedder/embedder.h @@ -9,6 +9,39 @@ #include #include +// This file defines an Application Binary Interface (ABI), which requires more +// stability than regular code to remain functional for exchanging messages +// between different versions of the embedding and the engine, to allow for both +// forward and backward compatibility. +// +// Specifically, +// - The order, type, and size of the struct members below must remain the same, +// and members should not be removed. +// - New structures that are part of the ABI must be defined with "size_t +// struct_size;" as their first member, which should be initialized using +// "sizeof(Type)". +// - Enum values must not change or be removed. +// - Enum members without explicit values must not be reordered. +// - Function signatures (names, argument counts, argument order, and argument +// type) cannot change. +// - The core behavior of existing functions cannot change. +// +// These changes are allowed: +// - Adding new struct members at the end of a structure. +// - Adding new enum members with a new value. +// - Renaming a struct member as long as its type, size, and intent remain the +// same. +// - Renaming an enum member as long as its value and intent remains the same. +// +// It is expected that struct members and implicitly-valued enums will not +// always be declared in an order that is optimal for the reader, since members +// will be added over time, and they can't be reordered. +// +// Existing functions should continue to appear from the caller's point of view +// to operate as they did when they were first introduced, so introduce a new +// function instead of modifying the core behavior of a function (and continue +// to support the existing function with the previous behavior). + #if defined(__cplusplus) extern "C" { #endif @@ -39,6 +72,11 @@ typedef enum { typedef enum { kOpenGL, kSoftware, + /// Metal is only supported on Darwin platforms (macOS / iOS). + /// iOS version >= 10.0 (device), 13.0 (simulator) + /// macOS version >= 10.14 + kMetal, + kVulkan, } FlutterRendererType; /// Additional accessibility features that may be enabled by the platform. @@ -54,8 +92,12 @@ typedef enum { /// Request that text be rendered at a bold font weight. kFlutterAccessibilityFeatureBoldText = 1 << 3, /// Request that certain animations be simplified and parallax effects - // removed. + /// removed. kFlutterAccessibilityFeatureReduceMotion = 1 << 4, + /// Request that UI be rendered with darker colors. + kFlutterAccessibilityFeatureHighContrast = 1 << 5, + /// Request to show on/off labels inside switches. + kFlutterAccessibilityFeatureOnOffSwitchLabels = 1 << 6, } FlutterAccessibilityFeature; /// The set of possible actions that can be conveyed to a semantics node. @@ -111,6 +153,8 @@ typedef enum { kFlutterSemanticsActionMoveCursorForwardByWord = 1 << 19, /// Move the cursor backward by one word. kFlutterSemanticsActionMoveCursorBackwardByWord = 1 << 20, + /// Replace the current text in the text field. + kFlutterSemanticsActionSetText = 1 << 21, } FlutterSemanticsAction; /// The set of properties that may be associated with a semantics node. @@ -165,6 +209,12 @@ typedef enum { /// `PageView` widget does not have implicit scrolling, so that users don't /// navigate to the next page when reaching the end of the current one. kFlutterSemanticsFlagHasImplicitScrolling = 1 << 18, + /// Whether the value of the semantics node is coming from a multi-line text + /// field. + /// + /// This is used for text fields to distinguish single-line text fields from + /// multi-line ones. + kFlutterSemanticsFlagIsMultiline = 1 << 19, /// Whether the semantic node is read only. /// /// Only applicable when kFlutterSemanticsFlagIsTextField flag is on. @@ -173,6 +223,10 @@ typedef enum { kFlutterSemanticsFlagIsFocusable = 1 << 21, /// Whether the semantics node represents a link. kFlutterSemanticsFlagIsLink = 1 << 22, + /// Whether the semantics node represents a slider. + kFlutterSemanticsFlagIsSlider = 1 << 23, + /// Whether the semantics node represents a keyboard key. + kFlutterSemanticsFlagIsKeyboardKey = 1 << 24, } FlutterSemanticsFlag; typedef enum { @@ -184,6 +238,18 @@ typedef enum { kFlutterTextDirectionLTR = 2, } FlutterTextDirection; +/// Valid values for priority of Thread. +typedef enum { + /// Suitable for threads that shouldn't disrupt high priority work. + kBackground = 0, + /// Default priority level. + kNormal = 1, + /// Suitable for threads which generate data for the display. + kDisplay = 2, + /// Suitable for thread which raster data. + kRaster = 3, +} FlutterThreadPriority; + typedef struct _FlutterEngine* FLUTTER_API_SYMBOL(FlutterEngine); typedef struct { @@ -272,13 +338,90 @@ typedef bool (*TextureFrameCallback)(void* /* user data */, size_t /* height */, FlutterOpenGLTexture* /* texture out */); typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */); +typedef void (*OnPreEngineRestartCallback)(void* /* user data */); + +/// A structure to represent the width and height. +typedef struct { + double width; + double height; +} FlutterSize; + +/// A structure to represent the width and height. +/// +/// See: \ref FlutterSize when the value are not integers. +typedef struct { + uint32_t width; + uint32_t height; +} FlutterUIntSize; + +/// A structure to represent a rectangle. +typedef struct { + double left; + double top; + double right; + double bottom; +} FlutterRect; + +/// A structure to represent a 2D point. +typedef struct { + double x; + double y; +} FlutterPoint; + +/// A structure to represent a rounded rectangle. +typedef struct { + FlutterRect rect; + FlutterSize upper_left_corner_radius; + FlutterSize upper_right_corner_radius; + FlutterSize lower_right_corner_radius; + FlutterSize lower_left_corner_radius; +} FlutterRoundedRect; + +/// This information is passed to the embedder when requesting a frame buffer +/// object. +/// +/// See: \ref FlutterOpenGLRendererConfig.fbo_with_frame_info_callback. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterFrameInfo). + size_t struct_size; + /// The size of the surface that will be backed by the fbo. + FlutterUIntSize size; +} FlutterFrameInfo; + +/// Callback for when a frame buffer object is requested. +typedef uint32_t (*UIntFrameInfoCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + +/// This information is passed to the embedder when a surface is presented. +/// +/// See: \ref FlutterOpenGLRendererConfig.present_with_info. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterPresentInfo). + size_t struct_size; + /// Id of the fbo backing the surface that was presented. + uint32_t fbo_id; +} FlutterPresentInfo; + +/// Callback for when a surface is presented. +typedef bool (*BoolPresentInfoCallback)( + void* /* user data */, + const FlutterPresentInfo* /* present info */); typedef struct { /// The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig). size_t struct_size; BoolCallback make_current; BoolCallback clear_current; + /// Specifying one (and only one) of `present` or `present_with_info` is + /// required. Specifying both is an error and engine initialization will be + /// terminated. The return value indicates success of the present call. BoolCallback present; + /// Specifying one (and only one) of the `fbo_callback` or + /// `fbo_with_frame_info_callback` is required. Specifying both is an error + /// and engine intialization will be terminated. The return value indicates + /// the id of the frame buffer object that flutter will obtain the gl surface + /// from. UIntCallback fbo_callback; /// This is an optional callback. Flutter will ask the emebdder to create a GL /// context current on a background thread. If the embedder is able to do so, @@ -309,8 +452,218 @@ typedef struct { /// that external texture details can be supplied to the engine for subsequent /// composition. TextureFrameCallback gl_external_texture_frame_callback; + /// Specifying one (and only one) of the `fbo_callback` or + /// `fbo_with_frame_info_callback` is required. Specifying both is an error + /// and engine intialization will be terminated. The return value indicates + /// the id of the frame buffer object (fbo) that flutter will obtain the gl + /// surface from. When using this variant, the embedder is passed a + /// `FlutterFrameInfo` struct that indicates the properties of the surface + /// that flutter will acquire from the returned fbo. + UIntFrameInfoCallback fbo_with_frame_info_callback; + /// Specifying one (and only one) of `present` or `present_with_info` is + /// required. Specifying both is an error and engine initialization will be + /// terminated. When using this variant, the embedder is passed a + /// `FlutterPresentInfo` struct that the embedder can use to release any + /// resources. The return value indicates success of the present call. + BoolPresentInfoCallback present_with_info; } FlutterOpenGLRendererConfig; +/// Alias for id. +typedef const void* FlutterMetalDeviceHandle; + +/// Alias for id. +typedef const void* FlutterMetalCommandQueueHandle; + +/// Alias for id. +typedef const void* FlutterMetalTextureHandle; + +/// Pixel format for the external texture. +typedef enum { + kYUVA, + kRGBA, +} FlutterMetalExternalTexturePixelFormat; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterMetalExternalTexture). + size_t struct_size; + /// Height of the texture. + size_t width; + /// Height of the texture. + size_t height; + /// The pixel format type of the external. + FlutterMetalExternalTexturePixelFormat pixel_format; + /// Represents the size of the `textures` array. + size_t num_textures; + /// Supported textures are YUVA and RGBA, in case of YUVA we expect 2 texture + /// handles to be provided by the embedder, Y first and UV next. In case of + /// RGBA only one should be passed. + /// These are individually aliases for id. These textures are + /// retained by the engine for the period of the composition. Once these + /// textures have been unregistered via the + /// `FlutterEngineUnregisterExternalTexture`, the embedder has to release + /// these textures. + FlutterMetalTextureHandle* textures; +} FlutterMetalExternalTexture; + +/// Callback to provide an external texture for a given texture_id. +/// See: external_texture_frame_callback. +typedef bool (*FlutterMetalTextureFrameCallback)( + void* /* user data */, + int64_t /* texture identifier */, + size_t /* width */, + size_t /* height */, + FlutterMetalExternalTexture* /* texture out */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterMetalTexture). + size_t struct_size; + /// Embedder provided unique identifier to the texture buffer. Given that the + /// `texture` handle is passed to the engine to render to, the texture buffer + /// is itself owned by the embedder. This `texture_id` is then also given to + /// the embedder in the present callback. + int64_t texture_id; + /// Handle to the MTLTexture that is owned by the embedder. Engine will render + /// the frame into this texture. + FlutterMetalTextureHandle texture; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; +} FlutterMetalTexture; + +/// Callback for when a metal texture is requested. +typedef FlutterMetalTexture (*FlutterMetalTextureCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + +/// Callback for when a metal texture is presented. The texture_id here +/// corresponds to the texture_id provided by the embedder in the +/// `FlutterMetalTextureCallback` callback. +typedef bool (*FlutterMetalPresentCallback)( + void* /* user data */, + const FlutterMetalTexture* /* texture */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterMetalRendererConfig). + size_t struct_size; + /// Alias for id. + FlutterMetalDeviceHandle device; + /// Alias for id. + FlutterMetalCommandQueueHandle present_command_queue; + /// The callback that gets invoked when the engine requests the embedder for a + /// texture to render to. + FlutterMetalTextureCallback get_next_drawable_callback; + /// The callback presented to the embedder to present a fully populated metal + /// texture to the user. + FlutterMetalPresentCallback present_drawable_callback; + /// When the embedder specifies that a texture has a frame available, the + /// engine will call this method (on an internal engine managed thread) so + /// that external texture details can be supplied to the engine for subsequent + /// composition. + FlutterMetalTextureFrameCallback external_texture_frame_callback; +} FlutterMetalRendererConfig; + +/// Alias for VkInstance. +typedef void* FlutterVulkanInstanceHandle; + +/// Alias for VkPhysicalDevice. +typedef void* FlutterVulkanPhysicalDeviceHandle; + +/// Alias for VkDevice. +typedef void* FlutterVulkanDeviceHandle; + +/// Alias for VkQueue. +typedef void* FlutterVulkanQueueHandle; + +/// Alias for VkImage. +typedef uint64_t FlutterVulkanImageHandle; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanImage). + size_t struct_size; + /// Handle to the VkImage that is owned by the embedder. The engine will + /// bind this image for writing the frame. + FlutterVulkanImageHandle image; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; +} FlutterVulkanImage; + +/// Callback to fetch a Vulkan function pointer for a given instance. Normally, +/// this should return the results of vkGetInstanceProcAddr. +typedef void* (*FlutterVulkanInstanceProcAddressCallback)( + void* /* user data */, + FlutterVulkanInstanceHandle /* instance */, + const char* /* name */); + +/// Callback for when a VkImage is requested. +typedef FlutterVulkanImage (*FlutterVulkanImageCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + +/// Callback for when a VkImage has been written to and is ready for use by the +/// embedder. +typedef bool (*FlutterVulkanPresentCallback)( + void* /* user data */, + const FlutterVulkanImage* /* image */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). + size_t struct_size; + + /// The Vulkan API version. This should match the value set in + /// VkApplicationInfo::apiVersion when the VkInstance was created. + uint32_t version; + /// VkInstance handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. + FlutterVulkanInstanceHandle instance; + /// VkPhysicalDevice handle. + FlutterVulkanPhysicalDeviceHandle physical_device; + /// VkDevice handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. + FlutterVulkanDeviceHandle device; + /// The queue family index of the VkQueue supplied in the next field. + uint32_t queue_family_index; + /// VkQueue handle. + FlutterVulkanQueueHandle queue; + /// The number of instance extensions available for enumerating in the next + /// field. + size_t enabled_instance_extension_count; + /// Array of enabled instance extension names. This should match the names + /// passed to `VkInstanceCreateInfo.ppEnabledExtensionNames` when the instance + /// was created, but any subset of enabled instance extensions may be + /// specified. + /// This field is optional; `nullptr` may be specified. + /// This memory is only accessed during the call to FlutterEngineInitialize. + const char** enabled_instance_extensions; + /// The number of device extensions available for enumerating in the next + /// field. + size_t enabled_device_extension_count; + /// Array of enabled logical device extension names. This should match the + /// names passed to `VkDeviceCreateInfo.ppEnabledExtensionNames` when the + /// logical device was created, but any subset of enabled logical device + /// extensions may be specified. + /// This field is optional; `nullptr` may be specified. + /// This memory is only accessed during the call to FlutterEngineInitialize. + /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME + const char** enabled_device_extensions; + /// The callback invoked when resolving Vulkan function pointers. + FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; + /// The callback invoked when the engine requests a VkImage from the embedder + /// for rendering the next frame. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. + FlutterVulkanImageCallback get_next_image_callback; + /// The callback invoked when a VkImage has been written to and is ready for + /// use by the embedder. Prior to calling this callback, the engine performs + /// a host sync, and so the VkImage can be used in a pipeline by the embedder + /// without any additional synchronization. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. + FlutterVulkanPresentCallback present_image_callback; + +} FlutterVulkanRendererConfig; + typedef struct { /// The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig). size_t struct_size; @@ -326,6 +679,8 @@ typedef struct { union { FlutterOpenGLRendererConfig open_gl; FlutterSoftwareRendererConfig software; + FlutterMetalRendererConfig metal; + FlutterVulkanRendererConfig vulkan; }; } FlutterRendererConfig; @@ -338,6 +693,18 @@ typedef struct { size_t height; /// Scale factor for the physical screen. double pixel_ratio; + /// Horizontal physical location of the left side of the window on the screen. + size_t left; + /// Vertical physical location of the top of the window on the screen. + size_t top; + /// Top inset of window. + double physical_view_inset_top; + /// Right inset of window. + double physical_view_inset_right; + /// Bottom inset of window. + double physical_view_inset_bottom; + /// Left inset of window. + double physical_view_inset_left; } FlutterWindowMetricsEvent; /// The phase of the pointer event. @@ -374,12 +741,20 @@ typedef enum { kRemove, /// The pointer moved while up. kHover, + /// A pan/zoom started on this pointer. + kPanZoomStart, + /// The pan/zoom updated. + kPanZoomUpdate, + /// The pan/zoom ended. + kPanZoomEnd, } FlutterPointerPhase; /// The device type that created a pointer event. typedef enum { kFlutterPointerDeviceKindMouse = 1, kFlutterPointerDeviceKindTouch, + kFlutterPointerDeviceKindStylus, + kFlutterPointerDeviceKindTrackpad, } FlutterPointerDeviceKind; /// Flags for the `buttons` field of `FlutterPointerEvent` when `device_kind` @@ -428,8 +803,90 @@ typedef struct { FlutterPointerDeviceKind device_kind; /// The buttons currently pressed, if any. int64_t buttons; + /// The x offset of the pan/zoom in physical pixels. + double pan_x; + /// The y offset of the pan/zoom in physical pixels. + double pan_y; + /// The scale of the pan/zoom, where 1.0 is the initial scale. + double scale; + /// The rotation of the pan/zoom in radians, where 0.0 is the initial angle. + double rotation; } FlutterPointerEvent; +typedef enum { + kFlutterKeyEventTypeUp = 1, + kFlutterKeyEventTypeDown, + kFlutterKeyEventTypeRepeat, +} FlutterKeyEventType; + +/// A structure to represent a key event. +/// +/// Sending `FlutterKeyEvent` via `FlutterEngineSendKeyEvent` results in a +/// corresponding `FlutterKeyEvent` to be dispatched in the framework. It is +/// embedder's responsibility to ensure the regularity of sent events, since the +/// framework only performs simple one-to-one mapping. The events must conform +/// the following rules: +/// +/// * Each key press sequence shall consist of one key down event (`kind` being +/// `kFlutterKeyEventTypeDown`), zero or more repeat events, and one key up +/// event, representing a physical key button being pressed, held, and +/// released. +/// * All events throughout a key press sequence shall have the same `physical` +/// and `logical`. Having different `character`s is allowed. +/// +/// A `FlutterKeyEvent` with `physical` 0 and `logical` 0 is an empty event. +/// This is the only case either `physical` or `logical` can be 0. An empty +/// event must be sent if a key message should be converted to no +/// `FlutterKeyEvent`s, for example, when a key down message is received for a +/// key that has already been pressed according to the record. This is to ensure +/// some `FlutterKeyEvent` arrives at the framework before raw key message. +/// See https://github.com/flutter/flutter/issues/87230. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterKeyEvent). + size_t struct_size; + /// The timestamp at which the key event was generated. The timestamp should + /// be specified in microseconds and the clock should be the same as that used + /// by `FlutterEngineGetCurrentTime`. + double timestamp; + /// The event kind. + FlutterKeyEventType type; + /// The USB HID code for the physical key of the event. + /// + /// For the full definition and list of pre-defined physical keys, see + /// `PhysicalKeyboardKey` from the framework. + /// + /// The only case that `physical` might be 0 is when this is an empty event. + /// See `FlutterKeyEvent` for introduction. + uint64_t physical; + /// The key ID for the logical key of this event. + /// + /// For the full definition and a list of pre-defined logical keys, see + /// `LogicalKeyboardKey` from the framework. + /// + /// The only case that `logical` might be 0 is when this is an empty event. + /// See `FlutterKeyEvent` for introduction. + uint64_t logical; + /// Null-terminated character input from the event. Can be null. Ignored for + /// up events. + const char* character; + /// True if this event does not correspond to a native event. + /// + /// The embedder is likely to skip events and/or construct new events that do + /// not correspond to any native events in order to conform the regularity + /// of events (as documented in `FlutterKeyEvent`). An example is when a key + /// up is missed due to loss of window focus, on a platform that provides + /// query to key pressing status, the embedder might realize that the key has + /// been released at the next key event, and should construct a synthesized up + /// event immediately before the actual event. + /// + /// An event being synthesized means that the `timestamp` might greatly + /// deviate from the actual time when the event occurs physically. + bool synthesized; +} FlutterKeyEvent; + +typedef void (*FlutterKeyEventCallback)(bool /* handled */, + void* /* user_data */); + struct _FlutterPlatformMessageResponseHandle; typedef struct _FlutterPlatformMessageResponseHandle FlutterPlatformMessageResponseHandle; @@ -457,31 +914,6 @@ typedef void (*FlutterDataCallback)(const uint8_t* /* data */, size_t /* size */, void* /* user data */); -typedef struct { - double left; - double top; - double right; - double bottom; -} FlutterRect; - -typedef struct { - double x; - double y; -} FlutterPoint; - -typedef struct { - double width; - double height; -} FlutterSize; - -typedef struct { - FlutterRect rect; - FlutterSize upper_left_corner_radius; - FlutterSize upper_right_corner_radius; - FlutterSize lower_right_corner_radius; - FlutterSize lower_left_corner_radius; -} FlutterRoundedRect; - /// The identifier of the platform view. This identifier is specified by the /// application when a platform view is added to the scene via the /// `SceneBuilder.addPlatformView` call. @@ -559,7 +991,7 @@ typedef struct { /// Has length `custom_accessibility_actions_count`. const int32_t* custom_accessibility_actions; /// Identifier of the platform view associated with this semantics node, or - /// zero if none. + /// -1 if none. FlutterPlatformViewIdentifier platform_view_id; } FlutterSemanticsNode; @@ -653,6 +1085,9 @@ typedef struct { /// and platform task runners. This makes the Flutter engine use the same /// thread for both task runners. const FlutterTaskRunnerDescription* render_task_runner; + /// Specify a callback that is used to set the thread priority for embedder + /// task runners. + void (*thread_priority_setter)(FlutterThreadPriority); } FlutterCustomTaskRunners; typedef struct { @@ -685,6 +1120,36 @@ typedef struct { VoidCallback destruction_callback; } FlutterSoftwareBackingStore; +typedef struct { + /// The size of this struct. Must be sizeof(FlutterMetalBackingStore). + size_t struct_size; + union { + // A Metal texture for Flutter to render into. Ownership is not transferred + // to Flutter; the texture is CFRetained on successfully being passed in and + // CFReleased when no longer used. + FlutterMetalTexture texture; + }; +} FlutterMetalBackingStore; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). + size_t struct_size; + /// The image that the layer will be rendered to. This image must already be + /// available for the engine to bind for writing when it's given to the engine + /// via the backing store creation callback. The engine will perform a host + /// sync for all layers prior to calling the compositor present callback, and + /// so the written layer images can be freely bound by the embedder without + /// any additional synchronization. + const FlutterVulkanImage* image; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; +} FlutterVulkanBackingStore; + typedef enum { /// Indicates that the Flutter application requested that an opacity be /// applied to the platform view. @@ -742,6 +1207,10 @@ typedef enum { kFlutterBackingStoreTypeOpenGL, /// Specified an software allocation for Flutter to render into using the CPU. kFlutterBackingStoreTypeSoftware, + /// Specifies a Metal backing store. This is backed by a Metal texture. + kFlutterBackingStoreTypeMetal, + /// Specifies a Vulkan backing store. This is backed by a Vulkan VkImage. + kFlutterBackingStoreTypeVulkan, } FlutterBackingStoreType; typedef struct { @@ -761,6 +1230,10 @@ typedef struct { FlutterOpenGLBackingStore open_gl; /// The description of the software backing store. FlutterSoftwareBackingStore software; + // The description of the Metal backing store. + FlutterMetalBackingStore metal; + // The description of the Vulkan backing store. + FlutterVulkanBackingStore vulkan; }; } FlutterBackingStore; @@ -835,6 +1308,8 @@ typedef struct { /// Callback invoked by the engine to composite the contents of each layer /// onto the screen. FlutterLayersPresentCallback present_layers_callback; + /// Avoid caching backing stores provided by this compositor. + bool avoid_backing_store_cache; } FlutterCompositor; typedef struct { @@ -861,6 +1336,52 @@ typedef struct { const char* variant_code; } FlutterLocale; +/// Callback that returns the system locale. +/// +/// Embedders that implement this callback should return the `FlutterLocale` +/// from the `supported_locales` list that most closely matches the +/// user/device's preferred locale. +/// +/// This callback does not currently provide the user_data baton. +/// https://github.com/flutter/flutter/issues/79826 +typedef const FlutterLocale* (*FlutterComputePlatformResolvedLocaleCallback)( + const FlutterLocale** /* supported_locales*/, + size_t /* Number of locales*/); + +/// Display refers to a graphics hardware system consisting of a framebuffer, +/// typically a monitor or a screen. This ID is unique per display and is +/// stable until the Flutter application restarts. +typedef uint64_t FlutterEngineDisplayId; + +typedef struct { + /// This size of this struct. Must be sizeof(FlutterDisplay). + size_t struct_size; + + FlutterEngineDisplayId display_id; + + /// This is set to true if the embedder only has one display. In cases where + /// this is set to true, the value of display_id is ignored. In cases where + /// this is not set to true, it is expected that a valid display_id be + /// provided. + bool single_display; + + /// This represents the refresh period in frames per second. This value may be + /// zero if the device is not running or unavailable or unknown. + double refresh_rate; +} FlutterEngineDisplay; + +/// The update type parameter that is passed to +/// `FlutterEngineNotifyDisplayUpdate`. +typedef enum { + /// `FlutterEngineDisplay`s that were active during start-up. A display is + /// considered active if: + /// 1. The frame buffer hardware is connected. + /// 2. The display is drawable, e.g. it isn't being mirrored from another + /// connected display or sleeping. + kFlutterEngineDisplaysUpdateTypeStartup, + kFlutterEngineDisplaysUpdateTypeCount, +} FlutterEngineDisplaysUpdateType; + typedef int64_t FlutterEngineDartPort; typedef enum { @@ -974,42 +1495,21 @@ typedef struct { }; } FlutterEngineAOTDataSource; +// Logging callback for Dart application messages. +// +// The `tag` parameter contains a null-terminated string containing a logging +// tag or component name that can be used to identify system log messages from +// the app. The `message` parameter contains a null-terminated string +// containing the message to be logged. `user_data` is a user data baton passed +// in `FlutterEngineRun`. +typedef void (*FlutterLogMessageCallback)(const char* /* tag */, + const char* /* message */, + void* /* user_data */); + /// An opaque object that describes the AOT data that can be used to launch a /// FlutterEngine instance in AOT mode. typedef struct _FlutterEngineAOTData* FlutterEngineAOTData; -//------------------------------------------------------------------------------ -/// @brief 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. -/// -/// @param[in] source The source of the AOT data. -/// @param[out] data_out The AOT data on success. Unchanged on failure. -/// -/// @return Returns if the AOT data could be successfully resolved. -/// -FLUTTER_EXPORT -FlutterEngineResult FlutterEngineCreateAOTData( - const FlutterEngineAOTDataSource* source, - FlutterEngineAOTData* data_out); - -//------------------------------------------------------------------------------ -/// @brief 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. -/// -/// @param[in] data The data to collect. -/// -/// @return Returns if the AOT data was successfully collected. -/// -FLUTTER_EXPORT -FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data); - typedef struct { /// The size of this struct. Must be sizeof(FlutterProjectArgs). size_t struct_size; @@ -1060,9 +1560,10 @@ typedef struct { /// `switches.h` engine source file. const char* const* command_line_argv; /// The callback invoked by the engine in order to give the embedder the - /// chance to respond to platform messages from the Dart application. The - /// callback will be invoked on the thread on which the `FlutterEngineRun` - /// call is made. + /// chance to respond to platform messages from the Dart application. + /// The callback will be invoked on the thread on which the `FlutterEngineRun` + /// call is made. The second parameter, `user_data`, is supplied when + /// `FlutterEngineRun` or `FlutterEngineInitialize` is called. FlutterPlatformMessageCallback platform_message_callback; /// The VM snapshot data buffer used in AOT operation. This buffer must be /// mapped in as read-only. For more information refer to the documentation on @@ -1205,8 +1706,90 @@ typedef struct { /// /// Embedders can provide either snapshot buffers or aot_data, but not both. FlutterEngineAOTData aot_data; + + /// A callback that computes the locale the platform would natively resolve + /// to. + /// + /// The input parameter is an array of FlutterLocales which represent the + /// locales supported by the app. One of the input supported locales should + /// be selected and returned to best match with the user/device's preferred + /// locale. The implementation should produce a result that as closely + /// matches what the platform would natively resolve to as possible. + FlutterComputePlatformResolvedLocaleCallback + compute_platform_resolved_locale_callback; + + /// The command line argument count for arguments passed through to the Dart + /// entrypoint. + int dart_entrypoint_argc; + + /// The command line arguments passed through to the Dart entrypoint. The + /// strings must be `NULL` terminated. + /// + /// The strings will be copied out and so any strings passed in here can + /// be safely collected after initializing the engine with + /// `FlutterProjectArgs`. + const char* const* dart_entrypoint_argv; + + // Logging callback for Dart application messages. + // + // This callback is used by embedder to log print messages from the running + // Flutter application. This callback is made on an internal engine managed + // thread and embedders must re-thread if necessary. Performing blocking calls + // in this callback may introduce application jank. + FlutterLogMessageCallback log_message_callback; + + // A tag string associated with application log messages. + // + // A log message tag string that can be used convey application, subsystem, + // or component name to embedder's logger. This string will be passed to to + // callbacks on `log_message_callback`. Defaults to "flutter" if unspecified. + const char* log_tag; + + // A callback that is invoked right before the engine is restarted. + // + // This optional callback is typically used to reset states to as if the + // engine has just been started, and usually indicates the user has requested + // a hot restart (Shift-R in the Flutter CLI.) It is not called the first time + // the engine starts. + // + // The first argument is the `user_data` from `FlutterEngineInitialize`. + OnPreEngineRestartCallback on_pre_engine_restart_callback; } FlutterProjectArgs; +#ifndef FLUTTER_ENGINE_NO_PROTOTYPES + +//------------------------------------------------------------------------------ +/// @brief 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. +/// +/// @param[in] source The source of the AOT data. +/// @param[out] data_out The AOT data on success. Unchanged on failure. +/// +/// @return Returns if the AOT data could be successfully resolved. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineCreateAOTData( + const FlutterEngineAOTDataSource* source, + FlutterEngineAOTData* data_out); + +//------------------------------------------------------------------------------ +/// @brief 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. +/// +/// @param[in] data The data to collect. +/// +/// @return Returns if the AOT data was successfully collected. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data); + //------------------------------------------------------------------------------ /// @brief Initialize and run a Flutter engine instance and return a handle /// to it. This is a convenience method for the pair of calls to @@ -1327,6 +1910,32 @@ FlutterEngineResult FlutterEngineSendPointerEvent( const FlutterPointerEvent* events, size_t events_count); +//------------------------------------------------------------------------------ +/// @brief 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. +/// +/// @param[in] engine A running engine instance. +/// @param[in] event The event data to be sent. This function will no +/// longer access `event` after returning. +/// @param[in] callback The callback invoked by the engine when the +/// Flutter application has decided whether it +/// handles this event. Accepts nullptr. +/// @param[in] user_data The context associated with the callback. The +/// exact same value will used to invoke `callback`. +/// Accepts nullptr. +/// +/// @return The result of the call. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSendKeyEvent(FLUTTER_API_SYMBOL(FlutterEngine) + engine, + const FlutterKeyEvent* event, + FlutterKeyEventCallback callback, + void* user_data); + FLUTTER_EXPORT FlutterEngineResult FlutterEngineSendPlatformMessage( FLUTTER_API_SYMBOL(FlutterEngine) engine, @@ -1790,6 +2399,211 @@ FlutterEngineResult FlutterEnginePostCallbackOnAllNativeThreads( FlutterNativeThreadCallback callback, void* user_data); +//------------------------------------------------------------------------------ +/// @brief Posts updates corresponding to display changes to a running engine +/// instance. +/// +/// @param[in] update_type The type of update pushed to the engine. +/// @param[in] displays The displays affected by this update. +/// @param[in] display_count Size of the displays array, must be at least 1. +/// +/// @return the result of the call made to the engine. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineNotifyDisplayUpdate( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterEngineDisplaysUpdateType update_type, + const FlutterEngineDisplay* displays, + size_t display_count); + +//------------------------------------------------------------------------------ +/// @brief Schedule a new frame to redraw the content. +/// +/// @param[in] engine A running engine instance. +/// +/// @return the result of the call made to the engine. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) + engine); + +#endif // !FLUTTER_ENGINE_NO_PROTOTYPES + +// Typedefs for the function pointers in FlutterEngineProcTable. +typedef FlutterEngineResult (*FlutterEngineCreateAOTDataFnPtr)( + const FlutterEngineAOTDataSource* source, + FlutterEngineAOTData* data_out); +typedef FlutterEngineResult (*FlutterEngineCollectAOTDataFnPtr)( + FlutterEngineAOTData data); +typedef FlutterEngineResult (*FlutterEngineRunFnPtr)( + size_t version, + const FlutterRendererConfig* config, + const FlutterProjectArgs* args, + void* user_data, + FLUTTER_API_SYMBOL(FlutterEngine) * engine_out); +typedef FlutterEngineResult (*FlutterEngineShutdownFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEngineInitializeFnPtr)( + size_t version, + const FlutterRendererConfig* config, + const FlutterProjectArgs* args, + void* user_data, + FLUTTER_API_SYMBOL(FlutterEngine) * engine_out); +typedef FlutterEngineResult (*FlutterEngineDeinitializeFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEngineRunInitializedFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEngineSendWindowMetricsEventFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterWindowMetricsEvent* event); +typedef FlutterEngineResult (*FlutterEngineSendPointerEventFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPointerEvent* events, + size_t events_count); +typedef FlutterEngineResult (*FlutterEngineSendKeyEventFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterKeyEvent* event, + FlutterKeyEventCallback callback, + void* user_data); +typedef FlutterEngineResult (*FlutterEngineSendPlatformMessageFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPlatformMessage* message); +typedef FlutterEngineResult ( + *FlutterEnginePlatformMessageCreateResponseHandleFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterDataCallback data_callback, + void* user_data, + FlutterPlatformMessageResponseHandle** response_out); +typedef FlutterEngineResult ( + *FlutterEnginePlatformMessageReleaseResponseHandleFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterPlatformMessageResponseHandle* response); +typedef FlutterEngineResult (*FlutterEngineSendPlatformMessageResponseFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterPlatformMessageResponseHandle* handle, + const uint8_t* data, + size_t data_length); +typedef FlutterEngineResult (*FlutterEngineRegisterExternalTextureFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier); +typedef FlutterEngineResult (*FlutterEngineUnregisterExternalTextureFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier); +typedef FlutterEngineResult ( + *FlutterEngineMarkExternalTextureFrameAvailableFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier); +typedef FlutterEngineResult (*FlutterEngineUpdateSemanticsEnabledFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + bool enabled); +typedef FlutterEngineResult (*FlutterEngineUpdateAccessibilityFeaturesFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterAccessibilityFeature features); +typedef FlutterEngineResult (*FlutterEngineDispatchSemanticsActionFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + uint64_t id, + FlutterSemanticsAction action, + const uint8_t* data, + size_t data_length); +typedef FlutterEngineResult (*FlutterEngineOnVsyncFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + intptr_t baton, + uint64_t frame_start_time_nanos, + uint64_t frame_target_time_nanos); +typedef FlutterEngineResult (*FlutterEngineReloadSystemFontsFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef void (*FlutterEngineTraceEventDurationBeginFnPtr)(const char* name); +typedef void (*FlutterEngineTraceEventDurationEndFnPtr)(const char* name); +typedef void (*FlutterEngineTraceEventInstantFnPtr)(const char* name); +typedef FlutterEngineResult (*FlutterEnginePostRenderThreadTaskFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + VoidCallback callback, + void* callback_data); +typedef uint64_t (*FlutterEngineGetCurrentTimeFnPtr)(); +typedef FlutterEngineResult (*FlutterEngineRunTaskFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterTask* task); +typedef FlutterEngineResult (*FlutterEngineUpdateLocalesFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterLocale** locales, + size_t locales_count); +typedef bool (*FlutterEngineRunsAOTCompiledDartCodeFnPtr)(void); +typedef FlutterEngineResult (*FlutterEnginePostDartObjectFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterEngineDartPort port, + const FlutterEngineDartObject* object); +typedef FlutterEngineResult (*FlutterEngineNotifyLowMemoryWarningFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEnginePostCallbackOnAllNativeThreadsFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterNativeThreadCallback callback, + void* user_data); +typedef FlutterEngineResult (*FlutterEngineNotifyDisplayUpdateFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterEngineDisplaysUpdateType update_type, + const FlutterEngineDisplay* displays, + size_t display_count); +typedef FlutterEngineResult (*FlutterEngineScheduleFrameFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); + +/// Function-pointer-based versions of the APIs above. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterEngineProcs). + size_t struct_size; + + FlutterEngineCreateAOTDataFnPtr CreateAOTData; + FlutterEngineCollectAOTDataFnPtr CollectAOTData; + FlutterEngineRunFnPtr Run; + FlutterEngineShutdownFnPtr Shutdown; + FlutterEngineInitializeFnPtr Initialize; + FlutterEngineDeinitializeFnPtr Deinitialize; + FlutterEngineRunInitializedFnPtr RunInitialized; + FlutterEngineSendWindowMetricsEventFnPtr SendWindowMetricsEvent; + FlutterEngineSendPointerEventFnPtr SendPointerEvent; + FlutterEngineSendKeyEventFnPtr SendKeyEvent; + FlutterEngineSendPlatformMessageFnPtr SendPlatformMessage; + FlutterEnginePlatformMessageCreateResponseHandleFnPtr + PlatformMessageCreateResponseHandle; + FlutterEnginePlatformMessageReleaseResponseHandleFnPtr + PlatformMessageReleaseResponseHandle; + FlutterEngineSendPlatformMessageResponseFnPtr SendPlatformMessageResponse; + FlutterEngineRegisterExternalTextureFnPtr RegisterExternalTexture; + FlutterEngineUnregisterExternalTextureFnPtr UnregisterExternalTexture; + FlutterEngineMarkExternalTextureFrameAvailableFnPtr + MarkExternalTextureFrameAvailable; + FlutterEngineUpdateSemanticsEnabledFnPtr UpdateSemanticsEnabled; + FlutterEngineUpdateAccessibilityFeaturesFnPtr UpdateAccessibilityFeatures; + FlutterEngineDispatchSemanticsActionFnPtr DispatchSemanticsAction; + FlutterEngineOnVsyncFnPtr OnVsync; + FlutterEngineReloadSystemFontsFnPtr ReloadSystemFonts; + FlutterEngineTraceEventDurationBeginFnPtr TraceEventDurationBegin; + FlutterEngineTraceEventDurationEndFnPtr TraceEventDurationEnd; + FlutterEngineTraceEventInstantFnPtr TraceEventInstant; + FlutterEnginePostRenderThreadTaskFnPtr PostRenderThreadTask; + FlutterEngineGetCurrentTimeFnPtr GetCurrentTime; + FlutterEngineRunTaskFnPtr RunTask; + FlutterEngineUpdateLocalesFnPtr UpdateLocales; + FlutterEngineRunsAOTCompiledDartCodeFnPtr RunsAOTCompiledDartCode; + FlutterEnginePostDartObjectFnPtr PostDartObject; + FlutterEngineNotifyLowMemoryWarningFnPtr NotifyLowMemoryWarning; + FlutterEnginePostCallbackOnAllNativeThreadsFnPtr + PostCallbackOnAllNativeThreads; + FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate; + FlutterEngineScheduleFrameFnPtr ScheduleFrame; +} FlutterEngineProcTable; + +//------------------------------------------------------------------------------ +/// @brief Gets the table of engine function pointers. +/// +/// @param[out] table The table to fill with pointers. This should be +/// zero-initialized, except for struct_size. +/// +/// @return Returns whether the table was successfully populated. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineGetProcAddresses( + FlutterEngineProcTable* table); + #if defined(__cplusplus) } // extern "C" #endif