diff --git a/engine/src/flutter/lib/snapshot/BUILD.gn b/engine/src/flutter/lib/snapshot/BUILD.gn index 01cbbc12277..37e21beb0cb 100644 --- a/engine/src/flutter/lib/snapshot/BUILD.gn +++ b/engine/src/flutter/lib/snapshot/BUILD.gn @@ -264,6 +264,7 @@ compile_platform("strong_platform") { is_runtime_mode_release = flutter_runtime_mode == "release" || flutter_runtime_mode == "jit_release" args = [ + "--enable-experiment=generic-metadata", "--nnbd-agnostic", "--target=flutter", "-Ddart.vm.product=$is_runtime_mode_release", diff --git a/engine/src/flutter/lib/ui/annotations.dart b/engine/src/flutter/lib/ui/annotations.dart index 85f062cea02..2b9bfae471a 100644 --- a/engine/src/flutter/lib/ui/annotations.dart +++ b/engine/src/flutter/lib/ui/annotations.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; // TODO(dnfield): Update this if/when we default this to on in the tool, diff --git a/engine/src/flutter/lib/ui/channel_buffers.dart b/engine/src/flutter/lib/ui/channel_buffers.dart index d491f2fe766..7b742f90075 100644 --- a/engine/src/flutter/lib/ui/channel_buffers.dart +++ b/engine/src/flutter/lib/ui/channel_buffers.dart @@ -5,7 +5,7 @@ // KEEP THIS SYNCHRONIZED WITH ../web_ui/lib/channel_buffers.dart -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Signature for [ChannelBuffers.drain]'s `callback` argument. diff --git a/engine/src/flutter/lib/ui/compositing.dart b/engine/src/flutter/lib/ui/compositing.dart index ce87901e82a..3f7e8d62f9d 100644 --- a/engine/src/flutter/lib/ui/compositing.dart +++ b/engine/src/flutter/lib/ui/compositing.dart @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// An opaque object representing a composited scene. @@ -41,12 +40,17 @@ class Scene extends NativeFieldWrapperClass1 { ); } - String? _toImage(int width, int height, _Callback<_Image?> callback) native 'Scene_toImage'; + @FfiNative, Uint32, Uint32, Handle)>('Scene::toImage') + external String? _toImage(int width, int height, _Callback<_Image?> callback); /// Releases the resources used by this scene. /// /// After calling this function, the scene is cannot be used further. - void dispose() native 'Scene_dispose'; + /// + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('Scene::dispose') + external void dispose(); } // Lightweight wrapper of a native layer object. @@ -211,7 +215,9 @@ class SceneBuilder extends NativeFieldWrapperClass1 { SceneBuilder() { _constructor(); } - void _constructor() native 'SceneBuilder_constructor'; + + @FfiNative('SceneBuilder::Create') + external void _constructor(); // Layers used in this scene. // @@ -307,8 +313,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushTransform(EngineLayer layer, Float64List matrix4, EngineLayer? oldLayer) - native 'SceneBuilder_pushTransform'; + @FfiNative, Handle, Handle, Handle)>('SceneBuilder::pushTransformHandle') + external void _pushTransform(EngineLayer layer, Float64List matrix4, EngineLayer? oldLayer); /// Pushes an offset operation onto the operation stack. /// @@ -332,8 +338,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushOffset(EngineLayer layer, double dx, double dy, EngineLayer? oldLayer) - native 'SceneBuilder_pushOffset'; + @FfiNative, Handle, Double, Double, Handle)>('SceneBuilder::pushOffset') + external void _pushOffset(EngineLayer layer, double dx, double dy, EngineLayer? oldLayer); /// Pushes a rectangular clip operation onto the operation stack. /// @@ -361,8 +367,15 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushClipRect(EngineLayer outEngineLayer, double left, double right, double top, - double bottom, int clipBehavior, EngineLayer? oldLayer) native 'SceneBuilder_pushClipRect'; + @FfiNative, Handle, Double, Double, Double, Double, Int32, Handle)>('SceneBuilder::pushClipRect') + external void _pushClipRect( + EngineLayer outEngineLayer, + double left, + double right, + double top, + double bottom, + int clipBehavior, + EngineLayer? oldLayer); /// Pushes a rounded-rectangular clip operation onto the operation stack. /// @@ -389,8 +402,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushClipRRect(EngineLayer layer, Float32List rrect, int clipBehavior, EngineLayer? oldLayer) - native 'SceneBuilder_pushClipRRect'; + @FfiNative, Handle, Handle, Int32, Handle)>('SceneBuilder::pushClipRRect') + external void _pushClipRRect(EngineLayer layer, Float32List rrect, int clipBehavior, EngineLayer? oldLayer); /// Pushes a path clip operation onto the operation stack. /// @@ -417,8 +430,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushClipPath(EngineLayer layer, Path path, int clipBehavior, EngineLayer? oldLayer) - native 'SceneBuilder_pushClipPath'; + @FfiNative, Handle, Pointer, Int32, Handle)>('SceneBuilder::pushClipPath') + external void _pushClipPath(EngineLayer layer, Path path, int clipBehavior, EngineLayer? oldLayer); /// Pushes an opacity operation onto the operation stack. /// @@ -445,8 +458,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushOpacity(EngineLayer layer, int alpha, double dx, double dy, EngineLayer? oldLayer) - native 'SceneBuilder_pushOpacity'; + @FfiNative, Handle, Int32, Double, Double, Handle)>('SceneBuilder::pushOpacity') + external void _pushOpacity(EngineLayer layer, int alpha, double dx, double dy, EngineLayer? oldLayer); /// Pushes a color filter operation onto the operation stack. /// @@ -473,8 +486,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushColorFilter(EngineLayer layer, _ColorFilter filter, EngineLayer? oldLayer) - native 'SceneBuilder_pushColorFilter'; + @FfiNative, Handle, Pointer, Handle)>('SceneBuilder::pushColorFilter') + external void _pushColorFilter(EngineLayer layer, _ColorFilter filter, EngineLayer? oldLayer); /// Pushes an image filter operation onto the operation stack. /// @@ -501,8 +514,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushImageFilter(EngineLayer outEngineLayer, _ImageFilter filter, EngineLayer? oldLayer) - native 'SceneBuilder_pushImageFilter'; + @FfiNative, Handle, Pointer, Handle)>('SceneBuilder::pushImageFilter') + external void _pushImageFilter(EngineLayer outEngineLayer, _ImageFilter filter, EngineLayer? oldLayer); /// Pushes a backdrop filter operation onto the operation stack. /// @@ -528,8 +541,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushBackdropFilter(EngineLayer outEngineLayer, _ImageFilter filter, int blendMode, EngineLayer? oldLayer) - native 'SceneBuilder_pushBackdropFilter'; + @FfiNative, Handle, Pointer, Int32, Handle)>('SceneBuilder::pushBackdropFilter') + external void _pushBackdropFilter(EngineLayer outEngineLayer, _ImageFilter filter, int blendMode, EngineLayer? oldLayer); /// Pushes a shader mask operation onto the operation stack. /// @@ -566,7 +579,9 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushShaderMask( + @FfiNative, Handle, Pointer, Double, Double, Double, Double, Int32, Int32, Handle)>( + 'SceneBuilder::pushShaderMask') + external void _pushShaderMask( EngineLayer engineLayer, Shader shader, double maskRectLeft, @@ -575,7 +590,7 @@ class SceneBuilder extends NativeFieldWrapperClass1 { double maskRectBottom, int blendMode, int filterQualityIndex, - EngineLayer? oldLayer) native 'SceneBuilder_pushShaderMask'; + EngineLayer? oldLayer); /// Pushes a physical layer operation for an arbitrary shape onto the /// operation stack. @@ -610,14 +625,15 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return layer; } - void _pushPhysicalShape( + @FfiNative, Handle, Pointer, Double, Int32, Int32, Int32, Handle)>('SceneBuilder::pushPhysicalShape') + external void _pushPhysicalShape( EngineLayer outEngineLayer, Path path, double elevation, int color, int shadowColor, int clipBehavior, - EngineLayer? oldLayer) native 'SceneBuilder_pushPhysicalShape'; + EngineLayer? oldLayer); /// Ends the effect of the most recently pushed operation. /// @@ -632,7 +648,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _pop(); } - void _pop() native 'SceneBuilder_pop'; + @FfiNative)>('SceneBuilder::pop', isLeaf: true) + external void _pop(); /// Add a retained engine layer subtree from previous frames. /// @@ -671,7 +688,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _addRetained(wrapper._nativeLayer!); } - void _addRetained(EngineLayer retainedLayer) native 'SceneBuilder_addRetained'; + @FfiNative, Handle)>('SceneBuilder::addRetained') + external void _addRetained(EngineLayer retainedLayer); /// Adds an object to the scene that displays performance statistics. /// @@ -701,13 +719,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _addPerformanceOverlay(enabledOptions, bounds.left, bounds.right, bounds.top, bounds.bottom); } - void _addPerformanceOverlay( - int enabledOptions, - double left, - double right, - double top, - double bottom, - ) native 'SceneBuilder_addPerformanceOverlay'; + @FfiNative, Uint64, Double, Double, Double, Double)>('SceneBuilder::addPerformanceOverlay', isLeaf: true) + external void _addPerformanceOverlay(int enabledOptions, double left, double right, double top, double bottom); /// Adds a [Picture] to the scene. /// @@ -723,8 +736,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _addPicture(offset.dx, offset.dy, picture, hints); } - void _addPicture(double dx, double dy, Picture picture, int hints) - native 'SceneBuilder_addPicture'; + @FfiNative, Double, Double, Pointer, Int32)>('SceneBuilder::addPicture') + external void _addPicture(double dx, double dy, Picture picture, int hints); /// Adds a backend texture to the scene. /// @@ -749,8 +762,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _addTexture(offset.dx, offset.dy, width, height, textureId, freeze, filterQuality.index); } - void _addTexture(double dx, double dy, double width, double height, int textureId, bool freeze, - int filterQuality) native 'SceneBuilder_addTexture'; + @FfiNative, Double, Double, Double, Double, Int64, Bool, Int32)>('SceneBuilder::addTexture', isLeaf: true) + external void _addTexture(double dx, double dy, double width, double height, int textureId, bool freeze, int filterQuality); /// Adds a platform view (e.g an iOS UIView) to the scene. /// @@ -778,8 +791,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { _addPlatformView(offset.dx, offset.dy, width, height, viewId); } - void _addPlatformView(double dx, double dy, double width, double height, int viewId) - native 'SceneBuilder_addPlatformView'; + @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addPlatformView', isLeaf: true) + external void _addPlatformView(double dx, double dy, double width, double height, int viewId); /// Sets a threshold after which additional debugging information should be recorded. /// @@ -787,8 +800,8 @@ class SceneBuilder extends NativeFieldWrapperClass1 { /// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev). /// We'll hopefully be able to figure out how to make this feature more useful /// to you. - void setRasterizerTracingThreshold(int frameInterval) - native 'SceneBuilder_setRasterizerTracingThreshold'; + @FfiNative, Uint32)>('SceneBuilder::setRasterizerTracingThreshold', isLeaf: true) + external void setRasterizerTracingThreshold(int frameInterval); /// Sets whether the raster cache should checkerboard cached entries. This is /// only useful for debugging purposes. @@ -805,15 +818,15 @@ class SceneBuilder extends NativeFieldWrapperClass1 { /// /// Currently this interface is difficult to use by end-developers. If you're /// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev). - void setCheckerboardRasterCacheImages(bool checkerboard) - native 'SceneBuilder_setCheckerboardRasterCacheImages'; + @FfiNative, Bool)>('SceneBuilder::setCheckerboardRasterCacheImages', isLeaf: true) + external void setCheckerboardRasterCacheImages(bool checkerboard); /// Sets whether the compositor should checkerboard layers that are rendered /// to offscreen bitmaps. /// /// This is only useful for debugging purposes. - void setCheckerboardOffscreenLayers(bool checkerboard) - native 'SceneBuilder_setCheckerboardOffscreenLayers'; + @FfiNative, Bool)>('SceneBuilder::setCheckerboardOffscreenLayers', isLeaf: true) + external void setCheckerboardOffscreenLayers(bool checkerboard); /// Finishes building the scene. /// @@ -829,5 +842,6 @@ class SceneBuilder extends NativeFieldWrapperClass1 { return scene; } - void _build(Scene outScene) native 'SceneBuilder_build'; + @FfiNative, Handle)>('SceneBuilder::build') + external void _build(Scene outScene); } diff --git a/engine/src/flutter/lib/ui/compositing/scene.cc b/engine/src/flutter/lib/ui/compositing/scene.cc index a6448970f66..236adc20d9b 100644 --- a/engine/src/flutter/lib/ui/compositing/scene.cc +++ b/engine/src/flutter/lib/ui/compositing/scene.cc @@ -21,12 +21,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); -#define FOR_EACH_BINDING(V) \ - V(Scene, toImage) \ - V(Scene, dispose) - -DART_BIND_ALL(Scene, FOR_EACH_BINDING) - void Scene::create(Dart_Handle scene_handle, std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, diff --git a/engine/src/flutter/lib/ui/compositing/scene.h b/engine/src/flutter/lib/ui/compositing/scene.h index f7a8d937118..93add4c751c 100644 --- a/engine/src/flutter/lib/ui/compositing/scene.h +++ b/engine/src/flutter/lib/ui/compositing/scene.h @@ -12,10 +12,6 @@ #include "flutter/lib/ui/dart_wrapper.h" #include "third_party/skia/include/core/SkPicture.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Scene : public RefCountedDartWrappable { @@ -38,8 +34,6 @@ class Scene : public RefCountedDartWrappable { void dispose(); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: explicit Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, diff --git a/engine/src/flutter/lib/ui/compositing/scene_builder.cc b/engine/src/flutter/lib/ui/compositing/scene_builder.cc index 210d28af650..b2569790b9d 100644 --- a/engine/src/flutter/lib/ui/compositing/scene_builder.cc +++ b/engine/src/flutter/lib/ui/compositing/scene_builder.cc @@ -33,44 +33,8 @@ namespace flutter { -static void SceneBuilder_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&SceneBuilder::create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder); -#define FOR_EACH_BINDING(V) \ - V(SceneBuilder, pushOffset) \ - V(SceneBuilder, pushTransform) \ - V(SceneBuilder, pushClipRect) \ - V(SceneBuilder, pushClipRRect) \ - V(SceneBuilder, pushClipPath) \ - V(SceneBuilder, pushOpacity) \ - V(SceneBuilder, pushColorFilter) \ - V(SceneBuilder, pushImageFilter) \ - V(SceneBuilder, pushBackdropFilter) \ - V(SceneBuilder, pushShaderMask) \ - V(SceneBuilder, pushPhysicalShape) \ - V(SceneBuilder, pop) \ - V(SceneBuilder, addPlatformView) \ - V(SceneBuilder, addRetained) \ - V(SceneBuilder, addPicture) \ - V(SceneBuilder, addTexture) \ - V(SceneBuilder, addPerformanceOverlay) \ - V(SceneBuilder, setRasterizerTracingThreshold) \ - V(SceneBuilder, setCheckerboardOffscreenLayers) \ - V(SceneBuilder, setCheckerboardRasterCacheImages) \ - V(SceneBuilder, build) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void SceneBuilder::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"SceneBuilder_constructor", SceneBuilder_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - SceneBuilder::SceneBuilder() { // Add a ContainerLayer as the root layer, so that AddLayer operations are // always valid. diff --git a/engine/src/flutter/lib/ui/compositing/scene_builder.h b/engine/src/flutter/lib/ui/compositing/scene_builder.h index fe9d3c76cbe..a1fb47603f3 100644 --- a/engine/src/flutter/lib/ui/compositing/scene_builder.h +++ b/engine/src/flutter/lib/ui/compositing/scene_builder.h @@ -28,11 +28,20 @@ class SceneBuilder : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(SceneBuilder); public: - static fml::RefPtr create() { - return fml::MakeRefCounted(); + static void Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } + ~SceneBuilder() override; + void pushTransformHandle(Dart_Handle layer_handle, + Dart_Handle matrix4_handle, + fml::RefPtr oldLayer) { + tonic::Float64List matrix4(matrix4_handle); + pushTransform(layer_handle, matrix4, oldLayer); + } void pushTransform(Dart_Handle layer_handle, tonic::Float64List& matrix4, fml::RefPtr oldLayer); @@ -123,8 +132,6 @@ class SceneBuilder : public RefCountedDartWrappable { return layer_stack_; } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: SceneBuilder(); diff --git a/engine/src/flutter/lib/ui/dart_runtime_hooks.cc b/engine/src/flutter/lib/ui/dart_runtime_hooks.cc index 60b7cf08d78..4a5ff462d20 100644 --- a/engine/src/flutter/lib/ui/dart_runtime_hooks.cc +++ b/engine/src/flutter/lib/ui/dart_runtime_hooks.cc @@ -33,24 +33,6 @@ using tonic::ToDart; namespace flutter { -#define REGISTER_FUNCTION(name, count) {"" #name, name, count, true}, -#define DECLARE_FUNCTION(name, count) \ - extern void name(Dart_NativeArguments args); - -#define BUILTIN_NATIVE_LIST(V) \ - V(Logger_PrintString, 1) \ - V(Logger_PrintDebugString, 1) \ - V(DartPluginRegistrant_EnsureInitialized, 0) \ - V(ScheduleMicrotask, 1) \ - V(GetCallbackHandle, 1) \ - V(GetCallbackFromHandle, 1) - -BUILTIN_NATIVE_LIST(DECLARE_FUNCTION); - -void DartRuntimeHooks::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)}); -} - static void PropagateIfError(Dart_Handle result) { if (Dart_IsError(result)) { FML_LOG(ERROR) << "Dart Error: " << ::Dart_GetError(result); @@ -156,32 +138,13 @@ void DartRuntimeHooks::Install(bool is_ui_isolate, InitDartIO(builtin, script_uri); } -void Logger_PrintDebugString(Dart_NativeArguments args) { +void DartRuntimeHooks::Logger_PrintDebugString(std::string message) { #ifndef NDEBUG - Logger_PrintString(args); + DartRuntimeHooks::Logger_PrintString(message); #endif } -// Implementation of native functions which are used for some -// test/debug functionality in standalone dart mode. -void Logger_PrintString(Dart_NativeArguments args) { - // Obtain the log buffer from Dart code. - std::string message; - { - Dart_Handle str = Dart_GetNativeArgument(args, 0); - uint8_t* chars = nullptr; - intptr_t length = 0; - Dart_Handle result = Dart_StringToUTF8(str, &chars, &length); - if (Dart_IsError(result)) { - Dart_PropagateError(result); - return; - } - if (length > 0) { - message = std::string{reinterpret_cast(chars), - static_cast(length)}; - } - } - +void DartRuntimeHooks::Logger_PrintString(std::string message) { const auto& tag = UIDartState::Current()->logger_prefix(); UIDartState::Current()->LogMessage(tag, message); @@ -202,8 +165,7 @@ void Logger_PrintString(Dart_NativeArguments args) { } } -void ScheduleMicrotask(Dart_NativeArguments args) { - Dart_Handle closure = Dart_GetNativeArgument(args, 0); +void DartRuntimeHooks::ScheduleMicrotask(Dart_Handle closure) { UIDartState::Current()->ScheduleMicrotask(closure); } @@ -280,8 +242,7 @@ static std::string GetFunctionName(Dart_Handle func) { return DartConverter::FromDart(result); } -void GetCallbackHandle(Dart_NativeArguments args) { - Dart_Handle func = Dart_GetNativeArgument(args, 0); +Dart_Handle DartRuntimeHooks::GetCallbackHandle(Dart_Handle func) { std::string name = GetFunctionName(func); std::string class_name = GetFunctionClassName(func); std::string library_path = GetFunctionLibraryUrl(func); @@ -291,21 +252,18 @@ void GetCallbackHandle(Dart_NativeArguments args) { // closures (e.g. `(int a, int b) => a + b;`) also cannot be used as // callbacks, so `func` must be a tear-off of a named static function. if (!Dart_IsTearOff(func) || name.empty()) { - Dart_SetReturnValue(args, Dart_Null()); - return; + return Dart_Null(); } - Dart_SetReturnValue( - args, DartConverter::ToDart(DartCallbackCache::GetCallbackHandle( - name, class_name, library_path))); + return DartConverter::ToDart( + DartCallbackCache::GetCallbackHandle(name, class_name, library_path)); } -void GetCallbackFromHandle(Dart_NativeArguments args) { - Dart_Handle h = Dart_GetNativeArgument(args, 0); - int64_t handle = DartConverter::FromDart(h); - Dart_SetReturnValue(args, DartCallbackCache::GetCallback(handle)); +Dart_Handle DartRuntimeHooks::GetCallbackFromHandle(int64_t handle) { + return DartCallbackCache::GetCallback(handle); } -void DartPluginRegistrant_EnsureInitialized(Dart_NativeArguments args) { +void DartPluginRegistrant_EnsureInitialized() { + tonic::DartApiScope api_scope; FindAndInvokeDartPluginRegistrant(); } diff --git a/engine/src/flutter/lib/ui/dart_runtime_hooks.h b/engine/src/flutter/lib/ui/dart_runtime_hooks.h index 62f4234cd16..163df335733 100644 --- a/engine/src/flutter/lib/ui/dart_runtime_hooks.h +++ b/engine/src/flutter/lib/ui/dart_runtime_hooks.h @@ -14,12 +14,23 @@ namespace flutter { class DartRuntimeHooks { public: static void Install(bool is_ui_isolate, const std::string& script_uri); - static void RegisterNatives(tonic::DartLibraryNatives* natives); + + static void Logger_PrintDebugString(std::string message); + + static void Logger_PrintString(std::string message); + + static void ScheduleMicrotask(Dart_Handle closure); + + static Dart_Handle GetCallbackHandle(Dart_Handle func); + + static Dart_Handle GetCallbackFromHandle(int64_t handle); private: FML_DISALLOW_IMPLICIT_CONSTRUCTORS(DartRuntimeHooks); }; +void DartPluginRegistrant_EnsureInitialized(); + } // namespace flutter #endif // FLUTTER_LIB_UI_DART_RUNTIME_HOOKS_H_ diff --git a/engine/src/flutter/lib/ui/dart_ui.cc b/engine/src/flutter/lib/ui/dart_ui.cc index bf3e190deab..3e699de34de 100644 --- a/engine/src/flutter/lib/ui/dart_ui.cc +++ b/engine/src/flutter/lib/ui/dart_ui.cc @@ -34,70 +34,271 @@ #include "flutter/lib/ui/text/paragraph_builder.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "third_party/tonic/converter/dart_converter.h" +#include "third_party/tonic/dart_args.h" #include "third_party/tonic/logging/dart_error.h" using tonic::ToDart; namespace flutter { -namespace { -static tonic::DartLibraryNatives* g_natives; +typedef CanvasImage Image; +typedef CanvasPathMeasure PathMeasure; +typedef CanvasGradient Gradient; +typedef CanvasPath Path; -Dart_NativeFunction GetNativeFunction(Dart_Handle name, - int argument_count, - bool* auto_setup_scope) { - return g_natives->GetNativeFunction(name, argument_count, auto_setup_scope); -} +// List of native static functions used as @FfiNative functions. +// Items are tuples of ('function_name', 'parameter_count'), where: +// 'function_name' is the fully qualified name of the native function. +// 'parameter_count' is the number of parameters the function has. +// +// These are used to: +// - Instantiate FfiDispatcher templates to automatically create FFI Native +// bindings. +// If the name does not match a native function, the template will fail to +// instatiate, resulting in a compile time error. +// - Resolve the native function pointer associated with an @FfiNative function. +// If there is a mismatch between name or parameter count an @FfiNative is +// trying to resolve, an exception will be thrown. +#define FFI_FUNCTION_LIST(V) \ + /* Constructors */ \ + V(Canvas::Create, 6) \ + V(ColorFilter::Create, 1) \ + V(FragmentProgram::Create, 1) \ + V(Gradient::Create, 1) \ + V(ImageFilter::Create, 1) \ + V(ImageShader::Create, 1) \ + V(ParagraphBuilder::Create, 9) \ + V(PathMeasure::Create, 3) \ + V(Path::Create, 1) \ + V(PictureRecorder::Create, 1) \ + V(SceneBuilder::Create, 1) \ + V(SemanticsUpdateBuilder::Create, 1) \ + /* Other */ \ + V(FontCollection::LoadFontFromList, 3) \ + V(ImageDescriptor::initEncoded, 3) \ + V(ImmutableBuffer::init, 3) \ + V(ImageDescriptor::initRaw, 6) \ + V(IsolateNameServerNatives::LookupPortByName, 1) \ + V(IsolateNameServerNatives::RegisterPortWithName, 2) \ + V(IsolateNameServerNatives::RemovePortNameMapping, 1) \ + V(NativeStringAttribute::initLocaleStringAttribute, 4) \ + V(NativeStringAttribute::initSpellOutStringAttribute, 3) \ + V(PlatformConfigurationNativeApi::DefaultRouteName, 0) \ + V(PlatformConfigurationNativeApi::ScheduleFrame, 0) \ + V(PlatformConfigurationNativeApi::Render, 1) \ + V(PlatformConfigurationNativeApi::UpdateSemantics, 1) \ + V(PlatformConfigurationNativeApi::SetNeedsReportTimings, 1) \ + V(PlatformConfigurationNativeApi::SetIsolateDebugName, 1) \ + V(PlatformConfigurationNativeApi::GetPersistentIsolateData, 0) \ + V(PlatformConfigurationNativeApi::ComputePlatformResolvedLocale, 1) \ + V(PlatformConfigurationNativeApi::SendPlatformMessage, 3) \ + V(PlatformConfigurationNativeApi::RespondToPlatformMessage, 2) \ + V(DartRuntimeHooks::Logger_PrintDebugString, 1) \ + V(DartRuntimeHooks::Logger_PrintString, 1) \ + V(DartRuntimeHooks::ScheduleMicrotask, 1) \ + V(DartRuntimeHooks::GetCallbackHandle, 1) \ + V(DartRuntimeHooks::GetCallbackFromHandle, 1) \ + V(DartPluginRegistrant_EnsureInitialized, 0) \ + V(Vertices::init, 6) -const uint8_t* GetSymbol(Dart_NativeFunction native_function) { - return g_natives->GetSymbol(native_function); -} +// List of native instance methods used as @FfiNative functions. +// Items are tuples of ('class_name', 'method_name', 'parameter_count'), where: +// 'class_name' is the name of the class containing the method. +// 'method_name' is the name of the method. +// 'parameter_count' is the number of parameters the method has. +// +// These are used to: +// - Instantiate FfiDispatcher templates to automatically create FFI Native +// bindings. +// If the name does not match a native function, the template will fail to +// instatiate, resulting in a compile time error. +// - Resolve the native function pointer associated with an @FfiNative function. +// If there is a mismatch between names or parameter count an @FfiNative is +// trying to resolve, an exception will be thrown. +#define FFI_METHOD_LIST(V) \ + V(Image, dispose, 1) \ + V(Image, width, 1) \ + V(Image, height, 1) \ + V(Image, toByteData, 3) \ + V(Canvas, clipPath, 3) \ + V(Canvas, clipRect, 7) \ + V(Canvas, clipRRect, 3) \ + V(Canvas, drawArc, 10) \ + V(Canvas, drawAtlas, 10) \ + V(Canvas, drawCircle, 6) \ + V(Canvas, drawColor, 3) \ + V(Canvas, drawDRRect, 5) \ + V(Canvas, drawImage, 7) \ + V(Canvas, drawImageNine, 13) \ + V(Canvas, drawImageRect, 13) \ + V(Canvas, drawLine, 7) \ + V(Canvas, drawOval, 7) \ + V(Canvas, drawPaint, 3) \ + V(Canvas, drawPath, 4) \ + V(Canvas, drawPicture, 2) \ + V(Canvas, drawPoints, 5) \ + V(Canvas, drawRRect, 4) \ + V(Canvas, drawRect, 7) \ + V(Canvas, drawShadow, 5) \ + V(Canvas, drawVertices, 5) \ + V(Canvas, getSaveCount, 1) \ + V(Canvas, restore, 1) \ + V(Canvas, rotate, 2) \ + V(Canvas, save, 1) \ + V(Canvas, saveLayer, 7) \ + V(Canvas, saveLayerWithoutBounds, 3) \ + V(Canvas, scale, 3) \ + V(Canvas, skew, 3) \ + V(Canvas, transform, 2) \ + V(Canvas, translate, 3) \ + V(Codec, dispose, 1) \ + V(Codec, frameCount, 1) \ + V(Codec, getNextFrame, 2) \ + V(Codec, repetitionCount, 1) \ + V(ColorFilter, initLinearToSrgbGamma, 1) \ + V(ColorFilter, initMatrix, 2) \ + V(ColorFilter, initMode, 3) \ + V(ColorFilter, initSrgbToLinearGamma, 1) \ + V(EngineLayer, dispose, 1) \ + V(FragmentProgram, init, 3) \ + V(FragmentProgram, shader, 4) \ + V(Gradient, initLinear, 6) \ + V(Gradient, initRadial, 8) \ + V(Gradient, initSweep, 9) \ + V(Gradient, initTwoPointConical, 11) \ + V(ImageDescriptor, bytesPerPixel, 1) \ + V(ImageDescriptor, dispose, 1) \ + V(ImageDescriptor, height, 1) \ + V(ImageDescriptor, instantiateCodec, 4) \ + V(ImageDescriptor, width, 1) \ + V(ImageFilter, initBlur, 4) \ + V(ImageFilter, initDilate, 3) \ + V(ImageFilter, initErode, 3) \ + V(ImageFilter, initColorFilter, 2) \ + V(ImageFilter, initComposeFilter, 3) \ + V(ImageFilter, initMatrix, 3) \ + V(ImageShader, initWithImage, 6) \ + V(ImmutableBuffer, dispose, 1) \ + V(ImmutableBuffer, length, 1) \ + V(ParagraphBuilder, addPlaceholder, 6) \ + V(ParagraphBuilder, addText, 2) \ + V(ParagraphBuilder, build, 2) \ + V(ParagraphBuilder, pop, 1) \ + V(ParagraphBuilder, pushStyle, 16) \ + V(Paragraph, alphabeticBaseline, 1) \ + V(Paragraph, computeLineMetrics, 1) \ + V(Paragraph, didExceedMaxLines, 1) \ + V(Paragraph, getLineBoundary, 2) \ + V(Paragraph, getPositionForOffset, 3) \ + V(Paragraph, getRectsForPlaceholders, 1) \ + V(Paragraph, getRectsForRange, 5) \ + V(Paragraph, getWordBoundary, 2) \ + V(Paragraph, height, 1) \ + V(Paragraph, ideographicBaseline, 1) \ + V(Paragraph, layout, 2) \ + V(Paragraph, longestLine, 1) \ + V(Paragraph, maxIntrinsicWidth, 1) \ + V(Paragraph, minIntrinsicWidth, 1) \ + V(Paragraph, paint, 4) \ + V(Paragraph, width, 1) \ + V(PathMeasure, setPath, 3) \ + V(PathMeasure, getLength, 2) \ + V(PathMeasure, getPosTan, 3) \ + V(PathMeasure, getSegment, 6) \ + V(PathMeasure, isClosed, 2) \ + V(PathMeasure, nextContour, 1) \ + V(Path, addArc, 7) \ + V(Path, addOval, 5) \ + V(Path, addPath, 4) \ + V(Path, addPathWithMatrix, 5) \ + V(Path, addPolygon, 3) \ + V(Path, addRRect, 2) \ + V(Path, addRect, 5) \ + V(Path, arcTo, 8) \ + V(Path, arcToPoint, 8) \ + V(Path, clone, 2) \ + V(Path, close, 1) \ + V(Path, conicTo, 6) \ + V(Path, contains, 3) \ + V(Path, cubicTo, 7) \ + V(Path, extendWithPath, 4) \ + V(Path, extendWithPathAndMatrix, 5) \ + V(Path, getBounds, 1) \ + V(Path, getFillType, 1) \ + V(Path, lineTo, 3) \ + V(Path, moveTo, 3) \ + V(Path, op, 4) \ + V(Path, quadraticBezierTo, 5) \ + V(Path, relativeArcToPoint, 5) \ + V(Path, relativeConicTo, 8) \ + V(Path, relativeCubicTo, 7) \ + V(Path, relativeLineTo, 3) \ + V(Path, relativeMoveTo, 3) \ + V(Path, relativeQuadraticBezierTo, 5) \ + V(Path, reset, 1) \ + V(Path, setFillType, 2) \ + V(Path, shift, 4) \ + V(Path, transform, 3) \ + V(PictureRecorder, endRecording, 2) \ + V(Picture, GetAllocationSize, 1) \ + V(Picture, dispose, 1) \ + V(Picture, toImage, 4) \ + V(SceneBuilder, addPerformanceOverlay, 6) \ + V(SceneBuilder, addPicture, 5) \ + V(SceneBuilder, addPlatformView, 6) \ + V(SceneBuilder, addRetained, 2) \ + V(SceneBuilder, addTexture, 8) \ + V(SceneBuilder, build, 2) \ + V(SceneBuilder, pop, 1) \ + V(SceneBuilder, pushBackdropFilter, 5) \ + V(SceneBuilder, pushClipPath, 5) \ + V(SceneBuilder, pushClipRRect, 5) \ + V(SceneBuilder, pushClipRect, 8) \ + V(SceneBuilder, pushColorFilter, 4) \ + V(SceneBuilder, pushImageFilter, 4) \ + V(SceneBuilder, pushOffset, 5) \ + V(SceneBuilder, pushOpacity, 6) \ + V(SceneBuilder, pushPhysicalShape, 8) \ + V(SceneBuilder, pushShaderMask, 10) \ + V(SceneBuilder, pushTransformHandle, 4) \ + V(SceneBuilder, setCheckerboardOffscreenLayers, 2) \ + V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ + V(SceneBuilder, setRasterizerTracingThreshold, 2) \ + V(Scene, dispose, 1) \ + V(Scene, toImage, 4) \ + V(SemanticsUpdateBuilder, build, 2) \ + V(SemanticsUpdateBuilder, updateCustomAction, 5) \ + V(SemanticsUpdateBuilder, updateNode, 36) \ + V(SemanticsUpdate, dispose, 1) -} // namespace - -void DartUI::InitForGlobal() { - if (!g_natives) { - g_natives = new tonic::DartLibraryNatives(); - Canvas::RegisterNatives(g_natives); - CanvasGradient::RegisterNatives(g_natives); - CanvasImage::RegisterNatives(g_natives); - CanvasPath::RegisterNatives(g_natives); - CanvasPathMeasure::RegisterNatives(g_natives); - Codec::RegisterNatives(g_natives); - ColorFilter::RegisterNatives(g_natives); - DartRuntimeHooks::RegisterNatives(g_natives); - EngineLayer::RegisterNatives(g_natives); - FontCollection::RegisterNatives(g_natives); - FragmentProgram::RegisterNatives(g_natives); - ImageDescriptor::RegisterNatives(g_natives); - ImageFilter::RegisterNatives(g_natives); - ImageShader::RegisterNatives(g_natives); - ImmutableBuffer::RegisterNatives(g_natives); - IsolateNameServerNatives::RegisterNatives(g_natives); - NativeStringAttribute::RegisterNatives(g_natives); - Paragraph::RegisterNatives(g_natives); - ParagraphBuilder::RegisterNatives(g_natives); - Picture::RegisterNatives(g_natives); - PictureRecorder::RegisterNatives(g_natives); - Scene::RegisterNatives(g_natives); - SceneBuilder::RegisterNatives(g_natives); - SemanticsUpdate::RegisterNatives(g_natives); - SemanticsUpdateBuilder::RegisterNatives(g_natives); - Vertices::RegisterNatives(g_natives); - PlatformConfiguration::RegisterNatives(g_natives); +#define FFI_FUNCTION_MATCH(FUNCTION, ARGS) \ + if (strcmp(name, #FUNCTION) == 0 && args == ARGS) { \ + return reinterpret_cast( \ + tonic::FfiDispatcher::Call); \ } + +#define FFI_METHOD_MATCH(CLASS, METHOD, ARGS) \ + if (strcmp(name, #CLASS "::" #METHOD) == 0 && args == ARGS) { \ + return reinterpret_cast( \ + tonic::FfiDispatcher::Call); \ + } + +void* ResolveFfiNativeFunction(const char* name, uintptr_t args) { + FFI_FUNCTION_LIST(FFI_FUNCTION_MATCH) + FFI_METHOD_LIST(FFI_METHOD_MATCH) + return nullptr; } void DartUI::InitForIsolate(const Settings& settings) { - FML_DCHECK(g_natives); - - Dart_Handle dart_ui = Dart_LookupLibrary(ToDart("dart:ui")); + auto dart_ui = Dart_LookupLibrary(ToDart("dart:ui")); if (Dart_IsError(dart_ui)) { Dart_PropagateError(dart_ui); } + // Set up FFI Native resolver for dart:ui. Dart_Handle result = - Dart_SetNativeResolver(dart_ui, GetNativeFunction, GetSymbol); + Dart_SetFfiNativeResolver(dart_ui, ResolveFfiNativeFunction); if (Dart_IsError(result)) { Dart_PropagateError(result); } diff --git a/engine/src/flutter/lib/ui/dart_ui.h b/engine/src/flutter/lib/ui/dart_ui.h index 9b6bfe0926b..55f85311d69 100644 --- a/engine/src/flutter/lib/ui/dart_ui.h +++ b/engine/src/flutter/lib/ui/dart_ui.h @@ -12,7 +12,6 @@ namespace flutter { class DartUI { public: - static void InitForGlobal(); static void InitForIsolate(const Settings& settings); private: diff --git a/engine/src/flutter/lib/ui/geometry.dart b/engine/src/flutter/lib/ui/geometry.dart index cf4bb483917..e29965c36d3 100644 --- a/engine/src/flutter/lib/ui/geometry.dart +++ b/engine/src/flutter/lib/ui/geometry.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Base class for [Size] and [Offset], which are both ways to describe diff --git a/engine/src/flutter/lib/ui/hash_codes.dart b/engine/src/flutter/lib/ui/hash_codes.dart index 71da5b3642b..fd00c721666 100644 --- a/engine/src/flutter/lib/ui/hash_codes.dart +++ b/engine/src/flutter/lib/ui/hash_codes.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; class _HashEnd { const _HashEnd(); } diff --git a/engine/src/flutter/lib/ui/hooks.dart b/engine/src/flutter/lib/ui/hooks.dart index b2c3619272f..866edf17c17 100644 --- a/engine/src/flutter/lib/ui/hooks.dart +++ b/engine/src/flutter/lib/ui/hooks.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; @pragma('vm:entry-point') diff --git a/engine/src/flutter/lib/ui/isolate_name_server.dart b/engine/src/flutter/lib/ui/isolate_name_server.dart index c2ef18b3a58..3f5c0e06350 100644 --- a/engine/src/flutter/lib/ui/isolate_name_server.dart +++ b/engine/src/flutter/lib/ui/isolate_name_server.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Static methods to allow for simple sharing of [SendPort]s across [Isolate]s. @@ -72,10 +72,12 @@ class IsolateNameServer { return _removePortNameMapping(name); } - static SendPort? _lookupPortByName(String name) - native 'IsolateNameServerNatives_LookupPortByName'; - static bool _registerPortWithName(SendPort port, String name) - native 'IsolateNameServerNatives_RegisterPortWithName'; - static bool _removePortNameMapping(String name) - native 'IsolateNameServerNatives_RemovePortNameMapping'; + @FfiNative('IsolateNameServerNatives::LookupPortByName') + external static SendPort? _lookupPortByName(String name); + + @FfiNative('IsolateNameServerNatives::RegisterPortWithName') + external static bool _registerPortWithName(SendPort port, String name); + + @FfiNative('IsolateNameServerNatives::RemovePortNameMapping') + external static bool _removePortNameMapping(String name); } diff --git a/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.cc b/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.cc index dc2433d9460..ab68a417bb5 100644 --- a/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.cc +++ b/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.cc @@ -26,46 +26,26 @@ Dart_Handle IsolateNameServerNatives::LookupPortByName( return Dart_NewSendPort(port); } -Dart_Handle IsolateNameServerNatives::RegisterPortWithName( - Dart_Handle port_handle, - const std::string& name) { +bool IsolateNameServerNatives::RegisterPortWithName(Dart_Handle port_handle, + const std::string& name) { auto name_server = UIDartState::Current()->GetIsolateNameServer(); if (!name_server) { - return Dart_False(); + return false; } Dart_Port port = ILLEGAL_PORT; Dart_SendPortGetId(port_handle, &port); if (!name_server->RegisterIsolatePortWithName(port, name)) { - return Dart_False(); + return false; } - return Dart_True(); + return true; } -Dart_Handle IsolateNameServerNatives::RemovePortNameMapping( - const std::string& name) { +bool IsolateNameServerNatives::RemovePortNameMapping(const std::string& name) { auto name_server = UIDartState::Current()->GetIsolateNameServer(); - if (!name_server) { - return Dart_False(); + if (!name_server || !name_server->RemoveIsolateNameMapping(name)) { + return false; } - if (!name_server->RemoveIsolateNameMapping(name)) { - return Dart_False(); - } - return Dart_True(); -} - -#define FOR_EACH_BINDING(V) \ - V(IsolateNameServerNatives, LookupPortByName) \ - V(IsolateNameServerNatives, RegisterPortWithName) \ - V(IsolateNameServerNatives, RemovePortNameMapping) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK_STATIC) - -#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \ - DART_REGISTER_NATIVE_STATIC(CLASS, METHOD), - -void IsolateNameServerNatives::RegisterNatives( - tonic::DartLibraryNatives* natives) { - natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE_STATIC_)}); + return true; } } // namespace flutter diff --git a/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h b/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h index e2ad83f9fe3..cd7c0a77e47 100644 --- a/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h +++ b/engine/src/flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h @@ -9,19 +9,14 @@ #include "third_party/dart/runtime/include/dart_api.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class IsolateNameServerNatives { public: static Dart_Handle LookupPortByName(const std::string& name); - static Dart_Handle RegisterPortWithName(Dart_Handle port_handle, - const std::string& name); - static Dart_Handle RemovePortNameMapping(const std::string& name); - static void RegisterNatives(tonic::DartLibraryNatives* natives); + static bool RegisterPortWithName(Dart_Handle port_handle, + const std::string& name); + static bool RemovePortNameMapping(const std::string& name); }; } // namespace flutter diff --git a/engine/src/flutter/lib/ui/key.dart b/engine/src/flutter/lib/ui/key.dart index f3ced0774ac..3a6056ee0ba 100644 --- a/engine/src/flutter/lib/ui/key.dart +++ b/engine/src/flutter/lib/ui/key.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; diff --git a/engine/src/flutter/lib/ui/lerp.dart b/engine/src/flutter/lib/ui/lerp.dart index 96565023b21..046807487af 100644 --- a/engine/src/flutter/lib/ui/lerp.dart +++ b/engine/src/flutter/lib/ui/lerp.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Linearly interpolate between two numbers, `a` and `b`, by an extrapolation diff --git a/engine/src/flutter/lib/ui/natives.dart b/engine/src/flutter/lib/ui/natives.dart index b7830fe23a7..1bc42d855f8 100644 --- a/engine/src/flutter/lib/ui/natives.dart +++ b/engine/src/flutter/lib/ui/natives.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; // ignore_for_file: avoid_classes_with_only_static_members @@ -20,7 +20,8 @@ class DartPluginRegistrant { _ensureInitialized(); } } - static void _ensureInitialized() native 'DartPluginRegistrant_EnsureInitialized'; + @FfiNative('DartPluginRegistrant_EnsureInitialized') + external static void _ensureInitialized(); } // Corelib 'print' implementation. @@ -33,8 +34,11 @@ void _printDebug(Object? arg) { } class _Logger { - static void _printString(String? s) native 'Logger_PrintString'; - static void _printDebugString(String? s) native 'Logger_PrintDebugString'; + @FfiNative('DartRuntimeHooks::Logger_PrintString') + external static void _printString(String? s); + + @FfiNative('DartRuntimeHooks::Logger_PrintDebugString') + external static void _printDebugString(String? s); } // If we actually run on big endian machines, we'll need to do something smarter @@ -88,10 +92,14 @@ List saveCompilationTrace() { throw UnimplementedError(); } -void _scheduleMicrotask(void Function() callback) native 'ScheduleMicrotask'; +@FfiNative('DartRuntimeHooks::ScheduleMicrotask') +external void _scheduleMicrotask(void Function() callback); -int? _getCallbackHandle(Function closure) native 'GetCallbackHandle'; -Function? _getCallbackFromHandle(int handle) native 'GetCallbackFromHandle'; +@FfiNative('DartRuntimeHooks::GetCallbackHandle') +external int? _getCallbackHandle(Function closure); + +@FfiNative('DartRuntimeHooks::GetCallbackFromHandle') +external Function? _getCallbackFromHandle(int handle); typedef _PrintClosure = void Function(String line); diff --git a/engine/src/flutter/lib/ui/painting.dart b/engine/src/flutter/lib/ui/painting.dart index 2a33b976926..c010af1dbcf 100644 --- a/engine/src/flutter/lib/ui/painting.dart +++ b/engine/src/flutter/lib/ui/painting.dart @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; // Some methods in this file assert that their arguments are not null. These @@ -1012,7 +1011,6 @@ enum PaintingStyle { stroke, } - /// Different ways to clip a widget's content. enum Clip { /// No clip at all. @@ -1413,7 +1411,6 @@ class Paint { final _ColorFilter? nativeFilter = _objects?[_kColorFilterIndex] as _ColorFilter?; return nativeFilter?.creator; } - set colorFilter(ColorFilter? value) { final _ColorFilter? nativeFilter = value?._toNativeColorFilter(); if (nativeFilter == null) { @@ -1451,7 +1448,6 @@ class Paint { final _ImageFilter? nativeFilter = _objects?[_kImageFilterIndex] as _ImageFilter?; return nativeFilter?.creator; } - set imageFilter(ImageFilter? value) { if (value == null) { if (_objects != null) { @@ -1848,9 +1844,11 @@ class _Image extends NativeFieldWrapperClass1 { @pragma('vm:entry-point') _Image._(); - int get width native 'Image_width'; + @FfiNative)>('Image::width', isLeaf: true) + external int get width; - int get height native 'Image_height'; + @FfiNative)>('Image::height', isLeaf: true) + external int get height; Future toByteData({ImageByteFormat format = ImageByteFormat.rawRgba}) { return _futurize((_Callback callback) { @@ -1861,7 +1859,8 @@ class _Image extends NativeFieldWrapperClass1 { } /// Returns an error message on failure, null on success. - String? _toByteData(int format, _Callback callback) native 'Image_toByteData'; + @FfiNative, Int32, Handle)>('Image::toByteData') + external String? _toByteData(int format, _Callback callback); bool _disposed = false; void dispose() { @@ -1877,7 +1876,10 @@ class _Image extends NativeFieldWrapperClass1 { _dispose(); } - void _dispose() native 'Image_dispose'; + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('Image::dispose') + external void _dispose(); Set _handles = {}; @@ -1944,7 +1946,6 @@ class FrameInfo { /// A zero duration indicates that the frame should be shown indefinitely. final Duration duration; - /// The [Image] object for this frame. /// /// This object must be disposed by the recipient of this frame info. @@ -1974,7 +1975,9 @@ class Codec extends NativeFieldWrapperClass1 { int? _cachedFrameCount; /// Number of frames in this image. int get frameCount => _cachedFrameCount ??= _frameCount; - int get _frameCount native 'Codec_frameCount'; + + @FfiNative)>('Codec::frameCount', isLeaf: true) + external int get _frameCount; int? _cachedRepetitionCount; /// Number of times to repeat the animation. @@ -1982,7 +1985,9 @@ class Codec extends NativeFieldWrapperClass1 { /// * 0 when the animation should be played once. /// * -1 for infinity repetitions. int get repetitionCount => _cachedRepetitionCount ??= _repetitionCount; - int get _repetitionCount native 'Codec_repetitionCount'; + + @FfiNative)>('Codec::repetitionCount', isLeaf: true) + external int get _repetitionCount; /// Fetches the next animation frame. /// @@ -2011,11 +2016,16 @@ class Codec extends NativeFieldWrapperClass1 { } /// Returns an error message on failure, null on success. - String? _getNextFrame(void Function(_Image?, int) callback) native 'Codec_getNextFrame'; + @FfiNative, Handle)>('Codec::getNextFrame') + external String? _getNextFrame(void Function(_Image?, int) callback); /// Release the resources used by this object. The object is no longer usable /// after this method is called. - void dispose() native 'Codec_dispose'; + /// + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('Codec::dispose') + external void dispose(); } /// Instantiates an image [Codec]. @@ -2078,8 +2088,7 @@ void decodeImageFromList(Uint8List list, ImageDecoderCallback callback) { _decodeImageFromListAsync(list, callback); } -Future _decodeImageFromListAsync(Uint8List list, - ImageDecoderCallback callback) async { +Future _decodeImageFromListAsync(Uint8List list, ImageDecoderCallback callback) async { final Codec codec = await instantiateImageCodec(list); final FrameInfo frameInfo = await codec.getNextFrame(); callback(frameInfo.image); @@ -2264,7 +2273,11 @@ class EngineLayer extends NativeFieldWrapperClass1 { /// Once this EngineLayer is disposed, it is no longer eligible for use as a /// retained layer, and must not be passed as an `oldLayer` to any of the /// [SceneBuilder] methods which accept that parameter. - void dispose() native 'EngineLayer_dispose'; + /// + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('EngineLayer::dispose') + external void dispose(); } /// A complex, one-dimensional subset of a plane. @@ -2289,7 +2302,9 @@ class Path extends NativeFieldWrapperClass1 { /// Create a new empty [Path] object. @pragma('vm:entry-point') Path() { _constructor(); } - void _constructor() native 'Path_constructor'; + + @FfiNative('Path::Create') + external void _constructor(); /// Avoids creating a new native backing for the path for methods that will /// create it later, such as [Path.from], [shift] and [transform]. @@ -2304,7 +2319,9 @@ class Path extends NativeFieldWrapperClass1 { source._clone(clonedPath); return clonedPath; } - void _clone(Path outPath) native 'Path_clone'; + + @FfiNative, Handle)>('Path::clone') + external void _clone(Path outPath); /// Determines how the interior of this path is calculated. /// @@ -2312,51 +2329,64 @@ class Path extends NativeFieldWrapperClass1 { PathFillType get fillType => PathFillType.values[_getFillType()]; set fillType(PathFillType value) => _setFillType(value.index); - int _getFillType() native 'Path_getFillType'; - void _setFillType(int fillType) native 'Path_setFillType'; + @FfiNative)>('Path::getFillType', isLeaf: true) + external int _getFillType(); + + @FfiNative, Int32)>('Path::setFillType', isLeaf: true) + external void _setFillType(int fillType); /// Starts a new sub-path at the given coordinate. - void moveTo(double x, double y) native 'Path_moveTo'; + @FfiNative, Float, Float)>('Path::moveTo', isLeaf: true) + external void moveTo(double x, double y); /// Starts a new sub-path at the given offset from the current point. - void relativeMoveTo(double dx, double dy) native 'Path_relativeMoveTo'; + @FfiNative, Float, Float)>('Path::relativeMoveTo', isLeaf: true) + external void relativeMoveTo(double dx, double dy); /// Adds a straight line segment from the current point to the given /// point. - void lineTo(double x, double y) native 'Path_lineTo'; + @FfiNative, Float, Float)>('Path::lineTo', isLeaf: true) + external void lineTo(double x, double y); /// Adds a straight line segment from the current point to the point /// at the given offset from the current point. - void relativeLineTo(double dx, double dy) native 'Path_relativeLineTo'; + @FfiNative, Float, Float)>('Path::relativeLineTo', isLeaf: true) + external void relativeLineTo(double dx, double dy); /// Adds a quadratic bezier segment that curves from the current /// point to the given point (x2,y2), using the control point /// (x1,y1). - void quadraticBezierTo(double x1, double y1, double x2, double y2) native 'Path_quadraticBezierTo'; + @FfiNative, Float, Float, Float, Float)>('Path::quadraticBezierTo', isLeaf: true) + external void quadraticBezierTo(double x1, double y1, double x2, double y2); /// Adds a quadratic bezier segment that curves from the current /// point to the point at the offset (x2,y2) from the current point, /// using the control point at the offset (x1,y1) from the current /// point. - void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) native 'Path_relativeQuadraticBezierTo'; + @FfiNative, Float, Float, Float, Float)>('Path::relativeQuadraticBezierTo', isLeaf: true) + external void relativeQuadraticBezierTo( + double x1, double y1, double x2, double y2); /// Adds a cubic bezier segment that curves from the current point /// to the given point (x3,y3), using the control points (x1,y1) and /// (x2,y2). - void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) native 'Path_cubicTo'; + @FfiNative, Float, Float, Float, Float, Float, Float)>('Path::cubicTo', isLeaf: true) + external void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3); /// Adds a cubic bezier segment that curves from the current point /// to the point at the offset (x3,y3) from the current point, using /// the control points at the offsets (x1,y1) and (x2,y2) from the /// current point. - void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3) native 'Path_relativeCubicTo'; + @FfiNative, Float, Float, Float, Float, Float, Float)>('Path::relativeCubicTo', isLeaf: true) + external void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3); /// Adds a bezier segment that curves from the current point to the /// given point (x2,y2), using the control points (x1,y1) and the /// weight w. If the weight is greater than 1, then the curve is a /// hyperbola; if the weight equals 1, it's a parabola; and if it is /// less than 1, it is an ellipse. - void conicTo(double x1, double y1, double x2, double y2, double w) native 'Path_conicTo'; + @FfiNative, Float, Float, Float, Float, Float)>('Path::conicTo', isLeaf: true) + external void conicTo(double x1, double y1, double x2, double y2, double w); /// Adds a bezier segment that curves from the current point to the /// point at the offset (x2,y2) from the current point, using the @@ -2364,7 +2394,8 @@ class Path extends NativeFieldWrapperClass1 { /// the weight w. If the weight is greater than 1, then the curve is /// a hyperbola; if the weight equals 1, it's a parabola; and if it /// is less than 1, it is an ellipse. - void relativeConicTo(double x1, double y1, double x2, double y2, double w) native 'Path_relativeConicTo'; + @FfiNative, Float, Float, Float, Float, Float)>('Path::relativeConicTo', isLeaf: true) + external void relativeConicTo(double x1, double y1, double x2, double y2, double w); /// If the `forceMoveTo` argument is false, adds a straight line /// segment and an arc segment. @@ -2386,8 +2417,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_rectIsValid(rect)); _arcTo(rect.left, rect.top, rect.right, rect.bottom, startAngle, sweepAngle, forceMoveTo); } - void _arcTo(double left, double top, double right, double bottom, - double startAngle, double sweepAngle, bool forceMoveTo) native 'Path_arcTo'; + + @FfiNative, Float, Float, Float, Float, Float, Float, Bool)>('Path::arcTo', isLeaf: true) + external void _arcTo(double left, double top, double right, double bottom, double startAngle, double sweepAngle, bool forceMoveTo); /// Appends up to four conic curves weighted to describe an oval of `radius` /// and rotated by `rotation` (measured in degrees and clockwise). @@ -2409,13 +2441,11 @@ class Path extends NativeFieldWrapperClass1 { }) { assert(_offsetIsValid(arcEnd)); assert(_radiusIsValid(radius)); - _arcToPoint(arcEnd.dx, arcEnd.dy, radius.x, radius.y, rotation, - largeArc, clockwise); + _arcToPoint(arcEnd.dx, arcEnd.dy, radius.x, radius.y, rotation, largeArc, clockwise); } - void _arcToPoint(double arcEndX, double arcEndY, double radiusX, - double radiusY, double rotation, bool largeArc, - bool clockwise) native 'Path_arcToPoint'; + @FfiNative, Float, Float, Float, Float, Float, Bool, Bool)>('Path::arcToPoint', isLeaf: true) + external void _arcToPoint(double arcEndX, double arcEndY, double radiusX, double radiusY, double rotation, bool largeArc, bool clockwise); /// Appends up to four conic curves weighted to describe an oval of `radius` /// and rotated by `rotation` (measured in degrees and clockwise). @@ -2431,7 +2461,8 @@ class Path extends NativeFieldWrapperClass1 { /// `arcEndDelta.dx` and `arcEndDelta.dy` are zero. The radii are scaled to /// fit the last path point if both are greater than zero but too small to /// describe an arc. - void relativeArcToPoint(Offset arcEndDelta, { + void relativeArcToPoint( + Offset arcEndDelta, { Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, @@ -2439,13 +2470,18 @@ class Path extends NativeFieldWrapperClass1 { }) { assert(_offsetIsValid(arcEndDelta)); assert(_radiusIsValid(radius)); - _relativeArcToPoint(arcEndDelta.dx, arcEndDelta.dy, radius.x, radius.y, - rotation, largeArc, clockwise); + _relativeArcToPoint(arcEndDelta.dx, arcEndDelta.dy, radius.x, radius.y, rotation, largeArc, clockwise); } - void _relativeArcToPoint(double arcEndX, double arcEndY, double radiusX, - double radiusY, double rotation, - bool largeArc, bool clockwise) - native 'Path_relativeArcToPoint'; + + @FfiNative, Float, Float, Float, Float, Float, Bool, Bool)>('Path::relativeArcToPoint', isLeaf: true) + external void _relativeArcToPoint( + double arcEndX, + double arcEndY, + double radiusX, + double radiusY, + double rotation, + bool largeArc, + bool clockwise); /// Adds a new sub-path that consists of four lines that outline the /// given rectangle. @@ -2453,7 +2489,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_rectIsValid(rect)); _addRect(rect.left, rect.top, rect.right, rect.bottom); } - void _addRect(double left, double top, double right, double bottom) native 'Path_addRect'; + + @FfiNative, Float, Float, Float, Float)>('Path::addRect', isLeaf: true) + external void _addRect(double left, double top, double right, double bottom); /// Adds a new sub-path that consists of a curve that forms the /// ellipse that fills the given rectangle. @@ -2464,7 +2502,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_rectIsValid(oval)); _addOval(oval.left, oval.top, oval.right, oval.bottom); } - void _addOval(double left, double top, double right, double bottom) native 'Path_addOval'; + + @FfiNative, Float, Float, Float, Float)>('Path::addOval', isLeaf: true) + external void _addOval(double left, double top, double right, double bottom); /// Adds a new sub-path with one arc segment that consists of the arc /// that follows the edge of the oval bounded by the given @@ -2478,8 +2518,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_rectIsValid(oval)); _addArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle); } - void _addArc(double left, double top, double right, double bottom, - double startAngle, double sweepAngle) native 'Path_addArc'; + + @FfiNative, Float, Float, Float, Float, Float, Float)>('Path::addArc', isLeaf: true) + external void _addArc(double left, double top, double right, double bottom, double startAngle, double sweepAngle); /// Adds a new sub-path with a sequence of line segments that connect the given /// points. @@ -2492,7 +2533,9 @@ class Path extends NativeFieldWrapperClass1 { assert(points != null); _addPolygon(_encodePointList(points), close); } - void _addPolygon(Float32List points, bool close) native 'Path_addPolygon'; + + @FfiNative, Handle, Bool)>('Path::addPolygon') + external void _addPolygon(Float32List points, bool close); /// Adds a new sub-path that consists of the straight lines and /// curves needed to form the rounded rectangle described by the @@ -2501,7 +2544,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_rrectIsValid(rrect)); _addRRect(rrect._getValue32()); } - void _addRRect(Float32List rrect) native 'Path_addRRect'; + + @FfiNative, Handle)>('Path::addRRect') + external void _addRRect(Float32List rrect); /// Adds the sub-paths of `path`, offset by `offset`, to this path. /// @@ -2518,8 +2563,12 @@ class Path extends NativeFieldWrapperClass1 { _addPath(path, offset.dx, offset.dy); } } - void _addPath(Path path, double dx, double dy) native 'Path_addPath'; - void _addPathWithMatrix(Path path, double dx, double dy, Float64List matrix) native 'Path_addPathWithMatrix'; + + @FfiNative, Pointer, Double, Double)>('Path::addPath') + external void _addPath(Path path, double dx, double dy); + + @FfiNative, Pointer, Double, Double, Handle)>('Path::addPathWithMatrix') + external void _addPathWithMatrix(Path path, double dx, double dy, Float64List matrix); /// Adds the sub-paths of `path`, offset by `offset`, to this path. /// The current sub-path is extended with the first sub-path @@ -2538,17 +2587,23 @@ class Path extends NativeFieldWrapperClass1 { _extendWithPath(path, offset.dx, offset.dy); } } - void _extendWithPath(Path path, double dx, double dy) native 'Path_extendWithPath'; - void _extendWithPathAndMatrix(Path path, double dx, double dy, Float64List matrix) native 'Path_extendWithPathAndMatrix'; + + @FfiNative, Pointer, Double, Double)>('Path::extendWithPath') + external void _extendWithPath(Path path, double dx, double dy); + + @FfiNative, Pointer, Double, Double, Handle)>('Path::extendWithPathAndMatrix') + external void _extendWithPathAndMatrix(Path path, double dx, double dy, Float64List matrix); /// Closes the last sub-path, as if a straight line had been drawn /// from the current point to the first point of the sub-path. - void close() native 'Path_close'; + @FfiNative)>('Path::close', isLeaf: true) + external void close(); /// Clears the [Path] object of all sub-paths, returning it to the /// same state it had when it was created. The _current point_ is /// reset to the origin. - void reset() native 'Path_reset'; + @FfiNative)>('Path::reset', isLeaf: true) + external void reset(); /// Tests to see if the given point is within the path. (That is, whether the /// point would be in the visible portion of the path if the path was used @@ -2561,7 +2616,9 @@ class Path extends NativeFieldWrapperClass1 { assert(_offsetIsValid(point)); return _contains(point.dx, point.dy); } - bool _contains(double x, double y) native 'Path_contains'; + + @FfiNative, Double, Double)>('Path::contains', isLeaf: true) + external bool _contains(double x, double y); /// Returns a copy of the path with all the segments of every /// sub-path translated by the given offset. @@ -2571,7 +2628,9 @@ class Path extends NativeFieldWrapperClass1 { _shift(path, offset.dx, offset.dy); return path; } - void _shift(Path outPath, double dx, double dy) native 'Path_shift'; + + @FfiNative, Handle, Double, Double)>('Path::shift') + external void _shift(Path outPath, double dx, double dy); /// Returns a copy of the path with all the segments of every /// sub-path transformed by the given matrix. @@ -2581,7 +2640,9 @@ class Path extends NativeFieldWrapperClass1 { _transform(path, matrix4); return path; } - void _transform(Path outPath, Float64List matrix4) native 'Path_transform'; + + @FfiNative, Handle, Handle)>('Path::transform') + external void _transform(Path outPath, Float64List matrix4); /// Computes the bounding rectangle for this path. /// @@ -2602,7 +2663,9 @@ class Path extends NativeFieldWrapperClass1 { final Float32List rect = _getBounds(); return Rect.fromLTRB(rect[0], rect[1], rect[2], rect[3]); } - Float32List _getBounds() native 'Path_getBounds'; + + @FfiNative)>('Path::getBounds') + external Float32List _getBounds(); /// Combines the two paths according to the manner specified by the given /// `operation`. @@ -2619,7 +2682,9 @@ class Path extends NativeFieldWrapperClass1 { } throw StateError('Path.combine() failed. This may be due an invalid path; in particular, check for NaN values.'); } - bool _op(Path path1, Path path2, int operation) native 'Path_op'; + + @FfiNative, Pointer, Pointer, Int32)>('Path::op') + external bool _op(Path path1, Path path2, int operation); /// Creates a [PathMetrics] object for this path, which can describe various /// properties about the contours of the path. @@ -2809,7 +2874,6 @@ class PathMetric { final _PathMeasure _measure; - /// Computes the position of the current contour at the given offset, and the /// angle of the path at that point. /// @@ -2840,16 +2904,21 @@ class _PathMeasure extends NativeFieldWrapperClass1 { _PathMeasure(Path path, bool forceClosed) { _constructor(path, forceClosed); } - void _constructor(Path path, bool forceClosed) native 'PathMeasure_constructor'; + + @FfiNative, Bool)>('PathMeasure::Create') + external void _constructor(Path path, bool forceClosed); double length(int contourIndex) { assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); return _length(contourIndex); } - double _length(int contourIndex) native 'PathMeasure_getLength'; + + @FfiNative, Int32)>('PathMeasure::getLength', isLeaf: true) + external double _length(int contourIndex); Tangent? getTangentForOffset(int contourIndex, double distance) { - assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); + assert(contourIndex <= currentContourIndex, + 'Iterator must be advanced before index $contourIndex can be used.'); final Float32List posTan = _getPosTan(contourIndex, distance); // first entry == 0 indicates that Skia returned false if (posTan[0] == 0.0) { @@ -2861,21 +2930,28 @@ class _PathMeasure extends NativeFieldWrapperClass1 { ); } } - Float32List _getPosTan(int contourIndex, double distance) native 'PathMeasure_getPosTan'; - Path extractPath(int contourIndex, double start, double end, {bool startWithMoveTo = true}) { + @FfiNative, Int32, Float)>('PathMeasure::getPosTan') + external Float32List _getPosTan(int contourIndex, double distance); + + Path extractPath(int contourIndex, double start, double end, + {bool startWithMoveTo = true}) { assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); final Path path = Path._(); - _extractPath(path, contourIndex, start, end, startWithMoveTo: startWithMoveTo); + _extractPath(path, contourIndex, start, end, startWithMoveTo); return path; } - void _extractPath(Path outPath, int contourIndex, double start, double end, {bool startWithMoveTo = true}) native 'PathMeasure_getSegment'; + + @FfiNative, Handle, Int32, Float, Float, Bool)>('PathMeasure::getSegment') + external void _extractPath(Path outPath, int contourIndex, double start, double end, bool startWithMoveTo); bool isClosed(int contourIndex) { assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); return _isClosed(contourIndex); } - bool _isClosed(int contourIndex) native 'PathMeasure_isClosed'; + + @FfiNative, Int32)>('PathMeasure::isClosed', isLeaf: true) + external bool _isClosed(int contourIndex); // Move to the next contour in the path. // @@ -2888,7 +2964,9 @@ class _PathMeasure extends NativeFieldWrapperClass1 { } return next; } - bool _nativeNextContour() native 'PathMeasure_nextContour'; + + @FfiNative)>('PathMeasure::nextContour', isLeaf: true) + external bool _nativeNextContour(); /// The index of the current contour in the list of contours in the path. /// @@ -3198,11 +3276,20 @@ class _ColorFilter extends NativeFieldWrapperClass1 { /// the values used for the filter. final ColorFilter creator; - void _constructor() native 'ColorFilter_constructor'; - void _initMode(int color, int blendMode) native 'ColorFilter_initMode'; - void _initMatrix(Float32List matrix) native 'ColorFilter_initMatrix'; - void _initLinearToSrgbGamma() native 'ColorFilter_initLinearToSrgbGamma'; - void _initSrgbToLinearGamma() native 'ColorFilter_initSrgbToLinearGamma'; + @FfiNative('ColorFilter::Create') + external void _constructor(); + + @FfiNative, Int32, Int32)>('ColorFilter::initMode', isLeaf: true) + external void _initMode(int color, int blendMode); + + @FfiNative, Handle)>('ColorFilter::initMatrix') + external void _initMatrix(Float32List matrix); + + @FfiNative)>('ColorFilter::initLinearToSrgbGamma', isLeaf: true) + external void _initLinearToSrgbGamma(); + + @FfiNative)>('ColorFilter::initSrgbToLinearGamma', isLeaf: true) + external void _initSrgbToLinearGamma(); } /// A filter operation to apply to a raster image. @@ -3259,7 +3346,7 @@ abstract class ImageFilter { /// subsequently applying `inner` and `outer`, i.e., /// result = outer(inner(source)). factory ImageFilter.compose({ required ImageFilter outer, required ImageFilter inner }) { - assert (inner != null && outer != null); + assert(inner != null && outer != null); return _ComposeImageFilter(innerFilter: inner, outerFilter: outer); } @@ -3315,7 +3402,7 @@ class _GaussianBlurImageFilter implements ImageFilter { _ImageFilter _toNativeImageFilter() => nativeFilter; String get _modeString { - switch(tileMode) { + switch (tileMode) { case TileMode.clamp: return 'clamp'; case TileMode.mirror: return 'mirror'; case TileMode.repeated: return 'repeated'; @@ -3437,16 +3524,19 @@ class _ComposeImageFilter implements ImageFilter { /// ImageFilter, because we want ImageFilter to be efficiently comparable, so that /// widgets can check for ImageFilter equality to avoid repainting. class _ImageFilter extends NativeFieldWrapperClass1 { - void _constructor() native 'ImageFilter_constructor'; + @FfiNative('ImageFilter::Create') + external void _constructor(); /// Creates an image filter that applies a Gaussian blur. _ImageFilter.blur(_GaussianBlurImageFilter filter) : assert(filter != null), - creator = filter { // ignore: prefer_initializing_formals + creator = filter { // ignore: prefer_initializing_formals _constructor(); _initBlur(filter.sigmaX, filter.sigmaY, filter.tileMode.index); } - void _initBlur(double sigmaX, double sigmaY, int tileMode) native 'ImageFilter_initBlur'; + + @FfiNative, Double, Double, Int32)>('ImageFilter::initBlur', isLeaf: true) + external void _initBlur(double sigmaX, double sigmaY, int tileMode); /// Creates an image filter that dilates each input pixel's channel values /// to the max value within the given radii along the x and y axes. @@ -3456,7 +3546,8 @@ class _ImageFilter extends NativeFieldWrapperClass1 { _constructor(); _initDilate(filter.radiusX, filter.radiusY); } - void _initDilate(double radiusX, double radiusY) native 'ImageFilter_initDilate'; + @FfiNative, Double, Double)>('ImageFilter::initDilate', isLeaf: true) + external void _initDilate(double radiusX, double radiusY); /// Create a filter that erodes each input pixel's channel values /// to the minimum channel value within the given radii along the x and y axes. @@ -3466,7 +3557,8 @@ class _ImageFilter extends NativeFieldWrapperClass1 { _constructor(); _initErode(filter.radiusX, filter.radiusY); } - void _initErode(double radiusX, double radiusY) native 'ImageFilter_initErode'; + @FfiNative, Double, Double)>('ImageFilter::initErode', isLeaf: true) + external void _initErode(double radiusX, double radiusY); /// Creates an image filter that applies a matrix transformation. /// @@ -3474,34 +3566,41 @@ class _ImageFilter extends NativeFieldWrapperClass1 { /// when used with [BackdropFilter] would magnify the background image. _ImageFilter.matrix(_MatrixImageFilter filter) : assert(filter != null), - creator = filter { // ignore: prefer_initializing_formals + creator = filter { // ignore: prefer_initializing_formals if (filter.data.length != 16) throw ArgumentError('"matrix4" must have 16 entries.'); _constructor(); _initMatrix(filter.data, filter.filterQuality.index); } - void _initMatrix(Float64List matrix4, int filterQuality) native 'ImageFilter_initMatrix'; + + @FfiNative, Handle, Int32)>('ImageFilter::initMatrix') + external void _initMatrix(Float64List matrix4, int filterQuality); /// Converts a color filter to an image filter. _ImageFilter.fromColorFilter(ColorFilter filter) : assert(filter != null), - creator = filter { // ignore: prefer_initializing_formals + creator = filter { // ignore: prefer_initializing_formals _constructor(); final _ColorFilter? nativeFilter = filter._toNativeColorFilter(); _initColorFilter(nativeFilter); } - void _initColorFilter(_ColorFilter? colorFilter) native 'ImageFilter_initColorFilter'; + + @FfiNative, Pointer)>('ImageFilter::initColorFilter') + external void _initColorFilter(_ColorFilter? colorFilter); /// Composes `_innerFilter` with `_outerFilter`. _ImageFilter.composed(_ComposeImageFilter filter) : assert(filter != null), - creator = filter { // ignore: prefer_initializing_formals + creator = filter { // ignore: prefer_initializing_formals _constructor(); final _ImageFilter nativeFilterInner = filter.innerFilter._toNativeImageFilter(); final _ImageFilter nativeFilterOuter = filter.outerFilter._toNativeImageFilter(); - _initComposed(nativeFilterOuter, nativeFilterInner); + _initComposed(nativeFilterOuter, nativeFilterInner); } - void _initComposed(_ImageFilter outerFilter, _ImageFilter innerFilter) native 'ImageFilter_initComposeFilter'; + + @FfiNative, Pointer, Pointer)>('ImageFilter::initComposeFilter') + external void _initComposed(_ImageFilter outerFilter, _ImageFilter innerFilter); + /// The original Dart object that created the native wrapper, which retains /// the values used for the filter. final ImageFilter creator; @@ -3650,8 +3749,8 @@ Float32List _encodeTwoPoints(Offset pointA, Offset pointB) { /// * [Gradient](https://api.flutter.dev/flutter/painting/Gradient-class.html), the class in the [painting] library. /// class Gradient extends Shader { - - void _constructor() native 'Gradient_constructor'; + @FfiNative('Gradient::Create') + external void _constructor(); /// Creates a linear gradient from `from` to `to`. /// @@ -3695,7 +3794,9 @@ class Gradient extends Shader { _constructor(); _initLinear(endPointsBuffer, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4); } - void _initLinear(Float32List endPoints, Int32List colors, Float32List? colorStops, int tileMode, Float64List? matrix4) native 'Gradient_initLinear'; + + @FfiNative, Handle, Handle, Handle, Int32, Handle)>('Gradient::initLinear') + external void _initLinear(Float32List endPoints, Int32List colors, Float32List? colorStops, int tileMode, Float64List? matrix4); /// Creates a radial gradient centered at `center` that ends at `radius` /// distance from the center. @@ -3756,8 +3857,30 @@ class Gradient extends Shader { _initConical(focal.dx, focal.dy, focalRadius, center.dx, center.dy, radius, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4); } } - void _initRadial(double centerX, double centerY, double radius, Int32List colors, Float32List? colorStops, int tileMode, Float64List? matrix4) native 'Gradient_initRadial'; - void _initConical(double startX, double startY, double startRadius, double endX, double endY, double endRadius, Int32List colors, Float32List? colorStops, int tileMode, Float64List? matrix4) native 'Gradient_initTwoPointConical'; + + @FfiNative, Double, Double, Double, Handle, Handle, Int32, Handle)>('Gradient::initRadial') + external void _initRadial( + double centerX, + double centerY, + double radius, + Int32List colors, + Float32List? colorStops, + int tileMode, + Float64List? matrix4); + + @FfiNative, Double, Double, Double, Double, Double, Double, Handle, Handle, Int32, Handle)>( + 'Gradient::initTwoPointConical') + external void _initConical( + double startX, + double startY, + double startRadius, + double endX, + double endY, + double endRadius, + Int32List colors, + Float32List? colorStops, + int tileMode, + Float64List? matrix4); /// Creates a sweep gradient centered at `center` that starts at `startAngle` /// and ends at `endAngle`. @@ -3808,9 +3931,20 @@ class Gradient extends Shader { _constructor(); _initSweep(center.dx, center.dy, colorsBuffer, colorStopsBuffer, tileMode.index, startAngle, endAngle, matrix4); } - void _initSweep(double centerX, double centerY, Int32List colors, Float32List? colorStops, int tileMode, double startAngle, double endAngle, Float64List? matrix) native 'Gradient_initSweep'; - static void _validateColorStops(List colors, List? colorStops) { + @FfiNative, Double, Double, Handle, Handle, Int32, Double, Double, Handle)>('Gradient::initSweep') + external void _initSweep( + double centerX, + double centerY, + Int32List colors, + Float32List? colorStops, + int tileMode, + double startAngle, + double endAngle, + Float64List? matrix); + + static void _validateColorStops( + List colors, List? colorStops) { if (colorStops == null) { if (colors.length != 2) throw ArgumentError('"colors" must have length 2 if "colorStops" is omitted.'); @@ -3844,8 +3978,12 @@ class ImageShader extends Shader { _constructor(); _initWithImage(image._image, tmx.index, tmy.index, filterQuality?.index ?? -1, matrix4); } - void _constructor() native 'ImageShader_constructor'; - void _initWithImage(_Image image, int tmx, int tmy, int filterQualityIndex, Float64List matrix4) native 'ImageShader_initWithImage'; + + @FfiNative('ImageShader::Create') + external void _constructor(); + + @FfiNative, Pointer, Int32, Int32, Int32, Handle)>('ImageShader::initWithImage') + external void _initWithImage(_Image image, int tmx, int tmy, int filterQualityIndex, Float64List matrix4); } /// An instance of [FragmentProgram] creates [Shader] objects (as used by [Paint.shader]) that run SPIR-V code. @@ -3890,8 +4028,11 @@ class FragmentProgram extends NativeFieldWrapperClass1 { late final int _uniformFloatCount; late final int _samplerCount; - void _constructor() native 'FragmentProgram_constructor'; - void _init(String sksl, bool debugPrint) native 'FragmentProgram_init'; + @FfiNative('FragmentProgram::Create') + external void _constructor(); + + @FfiNative, Handle, Bool)>('FragmentProgram::init') + external void _init(String sksl, bool debugPrint); /// Constructs a [Shader] object suitable for use by [Paint.shader] with /// the given uniforms. @@ -3967,11 +4108,8 @@ class FragmentProgram extends NativeFieldWrapperClass1 { return shader; } - void _shader( - _FragmentShader shader, - Float32List floatUniforms, - List samplerUniforms, - ) native 'FragmentProgram_shader'; + @FfiNative, Handle, Handle, Handle)>('FragmentProgram::shader') + external Handle _shader(_FragmentShader shader, Float32List floatUniforms, List samplerUniforms); } @pragma('vm:entry-point') @@ -4115,12 +4253,13 @@ class Vertices extends NativeFieldWrapperClass1 { throw ArgumentError('Invalid configuration for vertices.'); } - bool _init(Vertices outVertices, - int mode, - Float32List positions, - Float32List? textureCoordinates, - Int32List? colors, - Uint16List? indices) native 'Vertices_init'; + @FfiNative('Vertices::init') + external static bool _init(Vertices outVertices, + int mode, + Float32List positions, + Float32List? textureCoordinates, + Int32List? colors, + Uint16List? indices); } /// Defines how a list of points is interpreted when drawing a set of points. @@ -4205,11 +4344,9 @@ class Canvas extends NativeFieldWrapperClass1 { cullRect ??= Rect.largest; _constructor(recorder, cullRect.left, cullRect.top, cullRect.right, cullRect.bottom); } - void _constructor(PictureRecorder recorder, - double left, - double top, - double right, - double bottom) native 'Canvas_constructor'; + + @FfiNative, Double, Double, Double, Double)>('Canvas::Create') + external void _constructor(PictureRecorder recorder, double left, double top, double right, double bottom); // The underlying Skia SkCanvas is owned by the PictureRecorder used to create this Canvas. // The Canvas holds a reference to the PictureRecorder to prevent the recorder from being @@ -4224,7 +4361,8 @@ class Canvas extends NativeFieldWrapperClass1 { /// /// * [saveLayer], which does the same thing but additionally also groups the /// commands done until the matching [restore]. - void save() native 'Canvas_save'; + @FfiNative)>('Canvas::save', isLeaf: true) + external void save(); /// Saves a copy of the current transform and clip on the save stack, and then /// creates a new group which subsequent calls will become a part of. When the @@ -4341,18 +4479,15 @@ class Canvas extends NativeFieldWrapperClass1 { _saveLayerWithoutBounds(paint._objects, paint._data); } else { assert(_rectIsValid(bounds)); - _saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, - paint._objects, paint._data); + _saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint._objects, paint._data); } } - void _saveLayerWithoutBounds(List? paintObjects, ByteData paintData) - native 'Canvas_saveLayerWithoutBounds'; - void _saveLayer(double left, - double top, - double right, - double bottom, - List? paintObjects, - ByteData paintData) native 'Canvas_saveLayer'; + + @FfiNative, Handle, Handle)>('Canvas::saveLayerWithoutBounds') + external void _saveLayerWithoutBounds(List? paintObjects, ByteData paintData); + + @FfiNative, Double, Double, Double, Double, Handle, Handle)>('Canvas::saveLayer') + external void _saveLayer(double left, double top, double right, double bottom, List? paintObjects, ByteData paintData); /// Pops the current save stack, if there is anything to pop. /// Otherwise, does nothing. @@ -4361,7 +4496,8 @@ class Canvas extends NativeFieldWrapperClass1 { /// /// If the state was pushed with with [saveLayer], then this call will also /// cause the new layer to be composited into the previous layer. - void restore() native 'Canvas_restore'; + @FfiNative)>('Canvas::restore', isLeaf: true) + external void restore(); /// Returns the number of items on the save stack, including the /// initial state. This means it returns 1 for a clean canvas, and @@ -4369,11 +4505,13 @@ class Canvas extends NativeFieldWrapperClass1 { /// each matching call to [restore] decrements it. /// /// This number cannot go below 1. - int getSaveCount() native 'Canvas_getSaveCount'; + @FfiNative)>('Canvas::getSaveCount', isLeaf: true) + external int getSaveCount(); /// Add a translation to the current transform, shifting the coordinate space /// horizontally by the first argument and vertically by the second argument. - void translate(double dx, double dy) native 'Canvas_translate'; + @FfiNative, Double, Double)>('Canvas::translate', isLeaf: true) + external void translate(double dx, double dy); /// Add an axis-aligned scale to the current transform, scaling by the first /// argument in the horizontal direction and the second in the vertical @@ -4383,16 +4521,19 @@ class Canvas extends NativeFieldWrapperClass1 { /// directions. void scale(double sx, [double? sy]) => _scale(sx, sy ?? sx); - void _scale(double sx, double sy) native 'Canvas_scale'; + @FfiNative, Double, Double)>('Canvas::scale', isLeaf: true) + external void _scale(double sx, double sy); /// Add a rotation to the current transform. The argument is in radians clockwise. - void rotate(double radians) native 'Canvas_rotate'; + @FfiNative, Double)>('Canvas::rotate', isLeaf: true) + external void rotate(double radians); /// Add an axis-aligned skew to the current transform, with the first argument /// being the horizontal skew in rise over run units clockwise around the /// origin, and the second argument being the vertical skew in rise over run /// units clockwise around the origin. - void skew(double sx, double sy) native 'Canvas_skew'; + @FfiNative, Double, Double)>('Canvas::skew', isLeaf: true) + external void skew(double sx, double sy); /// Multiply the current transform by the specified 4⨉4 transformation matrix /// specified as a list of values in column-major order. @@ -4402,7 +4543,9 @@ class Canvas extends NativeFieldWrapperClass1 { throw ArgumentError('"matrix4" must have 16 entries.'); _transform(matrix4); } - void _transform(Float64List matrix4) native 'Canvas_transform'; + + @FfiNative, Handle)>('Canvas::transform') + external void _transform(Float64List matrix4); /// Reduces the clip region to the intersection of the current clip and the /// given rectangle. @@ -4421,12 +4564,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(doAntiAlias != null); _clipRect(rect.left, rect.top, rect.right, rect.bottom, clipOp.index, doAntiAlias); } - void _clipRect(double left, - double top, - double right, - double bottom, - int clipOp, - bool doAntiAlias) native 'Canvas_clipRect'; + + @FfiNative, Double, Double, Double, Double, Int32, Bool)>('Canvas::clipRect', isLeaf: true) + external void _clipRect(double left, double top, double right, double bottom, int clipOp, bool doAntiAlias); /// Reduces the clip region to the intersection of the current clip and the /// given rounded rectangle. @@ -4441,7 +4581,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(doAntiAlias != null); _clipRRect(rrect._getValue32(), doAntiAlias); } - void _clipRRect(Float32List rrect, bool doAntiAlias) native 'Canvas_clipRRect'; + + @FfiNative, Handle, Bool)>('Canvas::clipRRect') + external void _clipRRect(Float32List rrect, bool doAntiAlias); /// Reduces the clip region to the intersection of the current clip and the /// given [Path]. @@ -4456,7 +4598,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(doAntiAlias != null); _clipPath(path, doAntiAlias); } - void _clipPath(Path path, bool doAntiAlias) native 'Canvas_clipPath'; + + @FfiNative, Pointer, Bool)>('Canvas::clipPath') + external void _clipPath(Path path, bool doAntiAlias); /// Paints the given [Color] onto the canvas, applying the given /// [BlendMode], with the given color being the source and the background @@ -4466,7 +4610,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(blendMode != null); _drawColor(color.value, blendMode.index); } - void _drawColor(int color, int blendMode) native 'Canvas_drawColor'; + + @FfiNative, Uint32, Int32)>('Canvas::drawColor', isLeaf: true) + external void _drawColor(int color, int blendMode); /// Draws a line between the given points using the given paint. The line is /// stroked, the value of the [Paint.style] is ignored for this call. @@ -4478,12 +4624,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawLine(p1.dx, p1.dy, p2.dx, p2.dy, paint._objects, paint._data); } - void _drawLine(double x1, - double y1, - double x2, - double y2, - List? paintObjects, - ByteData paintData) native 'Canvas_drawLine'; + + @FfiNative, Double, Double, Double, Double, Handle, Handle)>('Canvas::drawLine') + external void _drawLine(double x1, double y1, double x2, double y2, List? paintObjects, ByteData paintData); /// Fills the canvas with the given [Paint]. /// @@ -4493,22 +4636,20 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawPaint(paint._objects, paint._data); } - void _drawPaint(List? paintObjects, ByteData paintData) native 'Canvas_drawPaint'; + + @FfiNative, Handle, Handle)>('Canvas::drawPaint') + external void _drawPaint(List? paintObjects, ByteData paintData); /// Draws a rectangle with the given [Paint]. Whether the rectangle is filled /// or stroked (or both) is controlled by [Paint.style]. void drawRect(Rect rect, Paint paint) { assert(_rectIsValid(rect)); assert(paint != null); - _drawRect(rect.left, rect.top, rect.right, rect.bottom, - paint._objects, paint._data); + _drawRect(rect.left, rect.top, rect.right, rect.bottom, paint._objects, paint._data); } - void _drawRect(double left, - double top, - double right, - double bottom, - List? paintObjects, - ByteData paintData) native 'Canvas_drawRect'; + + @FfiNative, Double, Double, Double, Double, Handle, Handle)>('Canvas::drawRect') + external void _drawRect(double left, double top, double right, double bottom, List? paintObjects, ByteData paintData); /// Draws a rounded rectangle with the given [Paint]. Whether the rectangle is /// filled or stroked (or both) is controlled by [Paint.style]. @@ -4517,9 +4658,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawRRect(rrect._getValue32(), paint._objects, paint._data); } - void _drawRRect(Float32List rrect, - List? paintObjects, - ByteData paintData) native 'Canvas_drawRRect'; + + @FfiNative, Handle, Handle, Handle)>('Canvas::drawRRect') + external void _drawRRect(Float32List rrect, List? paintObjects, ByteData paintData); /// Draws a shape consisting of the difference between two rounded rectangles /// with the given [Paint]. Whether this shape is filled or stroked (or both) @@ -4532,10 +4673,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawDRRect(outer._getValue32(), inner._getValue32(), paint._objects, paint._data); } - void _drawDRRect(Float32List outer, - Float32List inner, - List? paintObjects, - ByteData paintData) native 'Canvas_drawDRRect'; + + @FfiNative, Handle, Handle, Handle, Handle)>('Canvas::drawDRRect') + external void _drawDRRect(Float32List outer, Float32List inner, List? paintObjects, ByteData paintData); /// Draws an axis-aligned oval that fills the given axis-aligned rectangle /// with the given [Paint]. Whether the oval is filled or stroked (or both) is @@ -4543,15 +4683,11 @@ class Canvas extends NativeFieldWrapperClass1 { void drawOval(Rect rect, Paint paint) { assert(_rectIsValid(rect)); assert(paint != null); - _drawOval(rect.left, rect.top, rect.right, rect.bottom, - paint._objects, paint._data); + _drawOval(rect.left, rect.top, rect.right, rect.bottom, paint._objects, paint._data); } - void _drawOval(double left, - double top, - double right, - double bottom, - List? paintObjects, - ByteData paintData) native 'Canvas_drawOval'; + + @FfiNative, Double, Double, Double, Double, Handle, Handle)>('Canvas::drawOval') + external void _drawOval(double left, double top, double right, double bottom, List? paintObjects, ByteData paintData); /// Draws a circle centered at the point given by the first argument and /// that has the radius given by the second argument, with the [Paint] given in @@ -4562,11 +4698,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawCircle(c.dx, c.dy, radius, paint._objects, paint._data); } - void _drawCircle(double x, - double y, - double radius, - List? paintObjects, - ByteData paintData) native 'Canvas_drawCircle'; + + @FfiNative, Double, Double, Double, Handle, Handle)>('Canvas::drawCircle') + external void _drawCircle(double x, double y, double radius, List? paintObjects, ByteData paintData); /// Draw an arc scaled to fit inside the given rectangle. /// @@ -4582,18 +4716,20 @@ class Canvas extends NativeFieldWrapperClass1 { void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint) { assert(_rectIsValid(rect)); assert(paint != null); - _drawArc(rect.left, rect.top, rect.right, rect.bottom, startAngle, - sweepAngle, useCenter, paint._objects, paint._data); + _drawArc(rect.left, rect.top, rect.right, rect.bottom, startAngle, sweepAngle, useCenter, paint._objects, paint._data); } - void _drawArc(double left, - double top, - double right, - double bottom, - double startAngle, - double sweepAngle, - bool useCenter, - List? paintObjects, - ByteData paintData) native 'Canvas_drawArc'; + + @FfiNative, Double, Double, Double, Double, Double, Double, Bool, Handle, Handle)>('Canvas::drawArc') + external void _drawArc( + double left, + double top, + double right, + double bottom, + double startAngle, + double sweepAngle, + bool useCenter, + List? paintObjects, + ByteData paintData); /// Draws the given [Path] with the given [Paint]. /// @@ -4605,9 +4741,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawPath(path, paint._objects, paint._data); } - void _drawPath(Path path, - List? paintObjects, - ByteData paintData) native 'Canvas_drawPath'; + + @FfiNative, Pointer, Handle, Handle)>('Canvas::drawPath') + external void _drawPath(Path path, List? paintObjects, ByteData paintData); /// Draws the given [Image] into the canvas with its top-left corner at the /// given [Offset]. The image is composited into the canvas using the given [Paint]. @@ -4617,12 +4753,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(paint != null); _drawImage(image._image, offset.dx, offset.dy, paint._objects, paint._data, paint.filterQuality.index); } - void _drawImage(_Image image, - double x, - double y, - List? paintObjects, - ByteData paintData, - int filterQualityIndex) native 'Canvas_drawImage'; + + @FfiNative, Pointer, Double, Double, Handle, Handle, Int32)>('Canvas::drawImage') + external void _drawImage(_Image image, double x, double y, List? paintObjects, ByteData paintData, int filterQualityIndex); /// Draws the subset of the given image described by the `src` argument into /// the canvas in the axis-aligned rectangle given by the `dst` argument. @@ -4651,18 +4784,35 @@ class Canvas extends NativeFieldWrapperClass1 { paint._data, paint.filterQuality.index); } - void _drawImageRect(_Image image, - double srcLeft, - double srcTop, - double srcRight, - double srcBottom, - double dstLeft, - double dstTop, - double dstRight, - double dstBottom, - List? paintObjects, - ByteData paintData, - int filterQualityIndex) native 'Canvas_drawImageRect'; + + @FfiNative< + Void Function( + Pointer, + Pointer, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Handle, + Handle, + Int32)>('Canvas::drawImageRect') + external void _drawImageRect( + _Image image, + double srcLeft, + double srcTop, + double srcRight, + double srcBottom, + double dstLeft, + double dstTop, + double dstRight, + double dstBottom, + List? paintObjects, + ByteData paintData, + int filterQualityIndex); /// Draws the given [Image] into the canvas using the given [Paint]. /// @@ -4695,18 +4845,35 @@ class Canvas extends NativeFieldWrapperClass1 { paint._data, paint.filterQuality.index); } - void _drawImageNine(_Image image, - double centerLeft, - double centerTop, - double centerRight, - double centerBottom, - double dstLeft, - double dstTop, - double dstRight, - double dstBottom, - List? paintObjects, - ByteData paintData, - int filterQualityIndex) native 'Canvas_drawImageNine'; + + @FfiNative< + Void Function( + Pointer, + Pointer, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Handle, + Handle, + Int32)>('Canvas::drawImageNine') + external void _drawImageNine( + _Image image, + double centerLeft, + double centerTop, + double centerRight, + double centerBottom, + double dstLeft, + double dstTop, + double dstRight, + double dstBottom, + List? paintObjects, + ByteData paintData, + int filterQualityIndex); /// Draw the given picture onto the canvas. To create a picture, see /// [PictureRecorder]. @@ -4714,7 +4881,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(picture != null); // picture is checked on the engine side _drawPicture(picture); } - void _drawPicture(Picture picture) native 'Canvas_drawPicture'; + + @FfiNative, Pointer)>('Canvas::drawPicture') + external void _drawPicture(Picture picture); /// Draws the text in the given [Paragraph] into this canvas at the given /// [Offset]. @@ -4775,10 +4944,8 @@ class Canvas extends NativeFieldWrapperClass1 { _drawPoints(paint._objects, paint._data, pointMode.index, points); } - void _drawPoints(List? paintObjects, - ByteData paintData, - int pointMode, - Float32List points) native 'Canvas_drawPoints'; + @FfiNative, Handle, Handle, Int32, Handle)>('Canvas::drawPoints') + external void _drawPoints(List? paintObjects, ByteData paintData, int pointMode, Float32List points); /// Draws the set of [Vertices] onto the canvas. /// @@ -4807,10 +4974,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(blendMode != null); _drawVertices(vertices, blendMode.index, paint._objects, paint._data); } - void _drawVertices(Vertices vertices, - int blendMode, - List? paintObjects, - ByteData paintData) native 'Canvas_drawVertices'; + + @FfiNative, Pointer, Int32, Handle, Handle)>('Canvas::drawVertices') + external void _drawVertices(Vertices vertices, int blendMode, List? paintObjects, ByteData paintData); /// Draws many parts of an image - the [atlas] - onto the canvas. /// @@ -5158,15 +5324,18 @@ class Canvas extends NativeFieldWrapperClass1 { ); } - void _drawAtlas(List? paintObjects, - ByteData paintData, - int filterQualityIndex, - _Image atlas, - Float32List rstTransforms, - Float32List rects, - Int32List? colors, - int blendMode, - Float32List? cullRect) native 'Canvas_drawAtlas'; + @FfiNative, Handle, Handle, Int32, Pointer, Handle, Handle, Handle, Int32, Handle)>( + 'Canvas::drawAtlas') + external void _drawAtlas( + List? paintObjects, + ByteData paintData, + int filterQualityIndex, + _Image atlas, + Float32List rstTransforms, + Float32List rects, + Int32List? colors, + int blendMode, + Float32List? cullRect); /// Draws a shadow for a [Path] representing the given material elevation. /// @@ -5180,10 +5349,9 @@ class Canvas extends NativeFieldWrapperClass1 { assert(transparentOccluder != null); _drawShadow(path, color.value, elevation, transparentOccluder); } - void _drawShadow(Path path, - int color, - double elevation, - bool transparentOccluder) native 'Canvas_drawShadow'; + + @FfiNative, Pointer, Uint32, Double, Bool)>('Canvas::drawShadow') + external void _drawShadow(Path path, int color, double elevation, bool transparentOccluder); } /// An object representing a sequence of recorded graphical operations. @@ -5225,7 +5393,8 @@ class Picture extends NativeFieldWrapperClass1 { ); } - String? _toImage(int width, int height, _Callback<_Image?> callback) native 'Picture_toImage'; + @FfiNative, Uint32, Uint32, Handle)>('Picture::toImage') + external String? _toImage(int width, int height, void Function(_Image?) callback); /// Release the resources used by this object. The object is no longer usable /// after this method is called. @@ -5238,8 +5407,10 @@ class Picture extends NativeFieldWrapperClass1 { _dispose(); } - void _dispose() native 'Picture_dispose'; - + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('Picture::dispose') + external void _dispose(); bool _disposed = false; /// Whether this reference to the underlying picture is [dispose]d. @@ -5259,7 +5430,8 @@ class Picture extends NativeFieldWrapperClass1 { /// /// The actual size of this picture may be larger, particularly if it contains /// references to image or other large objects. - int get approximateBytesUsed native 'Picture_GetAllocationSize'; + @FfiNative)>('Picture::GetAllocationSize', isLeaf: true) + external int get approximateBytesUsed; } /// Records a [Picture] containing a sequence of graphical operations. @@ -5272,7 +5444,9 @@ class PictureRecorder extends NativeFieldWrapperClass1 { /// [Canvas] constructor. @pragma('vm:entry-point') PictureRecorder() { _constructor(); } - void _constructor() native 'PictureRecorder_constructor'; + + @FfiNative('PictureRecorder::Create') + external void _constructor(); /// Whether this object is currently recording commands. /// @@ -5298,7 +5472,8 @@ class PictureRecorder extends NativeFieldWrapperClass1 { return picture; } - void _endRecording(Picture outPicture) native 'PictureRecorder_endRecording'; + @FfiNative, Handle)>('PictureRecorder::endRecording') + external void _endRecording(Picture outPicture); Canvas? _canvas; } @@ -5518,10 +5693,12 @@ class ImmutableBuffer extends NativeFieldWrapperClass1 { static Future fromUint8List(Uint8List list) { final ImmutableBuffer instance = ImmutableBuffer._(list.length); return _futurize((_Callback callback) { - instance._init(list, callback); + return instance._init(list, callback); }).then((_) => instance); } - void _init(Uint8List list, _Callback callback) native 'ImmutableBuffer_init'; + + @FfiNative('ImmutableBuffer::init') + external String? _init(Uint8List list, _Callback callback); /// The length, in bytes, of the underlying data. final int length; @@ -5558,7 +5735,10 @@ class ImmutableBuffer extends NativeFieldWrapperClass1 { _dispose(); } - void _dispose() native 'ImmutableBuffer_dispose'; + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('ImmutableBuffer::dispose') + external void _dispose(); } /// A descriptor of data that can be turned into an [Image] via a [Codec]. @@ -5575,7 +5755,9 @@ class ImageDescriptor extends NativeFieldWrapperClass1 { return descriptor._initEncoded(buffer, callback); }).then((_) => descriptor); } - String? _initEncoded(ImmutableBuffer buffer, _Callback callback) native 'ImageDescriptor_initEncoded'; + + @FfiNative, Handle)>('ImageDescriptor::initEncoded') + external String? _initEncoded(ImmutableBuffer buffer, _Callback callback); /// Creates an image descriptor from raw image pixels. /// @@ -5599,24 +5781,35 @@ class ImageDescriptor extends NativeFieldWrapperClass1 { _bytesPerPixel = 4; _initRaw(this, buffer, width, height, rowBytes ?? -1, pixelFormat.index); } - void _initRaw(ImageDescriptor outDescriptor, ImmutableBuffer buffer, int width, int height, int rowBytes, int pixelFormat) native 'ImageDescriptor_initRaw'; + + @FfiNative('ImageDescriptor::initRaw') + external static void _initRaw(ImageDescriptor outDescriptor, ImmutableBuffer buffer, int width, int height, int rowBytes, int pixelFormat); int? _width; - int _getWidth() native 'ImageDescriptor_width'; + + @FfiNative)>('ImageDescriptor::width', isLeaf: true) + external int _getWidth(); + /// The width, in pixels, of the image. /// /// On the Web, this is only supported for [raw] images. int get width => _width ??= _getWidth(); int? _height; - int _getHeight() native 'ImageDescriptor_height'; + + @FfiNative)>('ImageDescriptor::height', isLeaf: true) + external int _getHeight(); + /// The height, in pixels, of the image. /// /// On the Web, this is only supported for [raw] images. int get height => _height ??= _getHeight(); int? _bytesPerPixel; - int _getBytesPerPixel() native 'ImageDescriptor_bytesPerPixel'; + + @FfiNative)>('ImageDescriptor::bytesPerPixel', isLeaf: true) + external int _getBytesPerPixel(); + /// The number of bytes per pixel in the image. /// /// On web, this is only supported for [raw] images. @@ -5624,7 +5817,11 @@ class ImageDescriptor extends NativeFieldWrapperClass1 { /// Release the resources used by this object. The object is no longer usable /// after this method is called. - void dispose() native 'ImageDescriptor_dispose'; + /// + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('ImageDescriptor::dispose') + external void dispose(); /// Creates a [Codec] object which is suitable for decoding the data in the /// buffer to an [Image]. @@ -5660,7 +5857,9 @@ class ImageDescriptor extends NativeFieldWrapperClass1 { _instantiateCodec(codec, targetWidth!, targetHeight!); return codec; } - void _instantiateCodec(Codec outCodec, int targetWidth, int targetHeight) native 'ImageDescriptor_instantiateCodec'; + + @FfiNative, Handle, Int32, Int32)>('ImageDescriptor::instantiateCodec') + external void _instantiateCodec(Codec outCodec, int targetWidth, int targetHeight); } /// Generic callback signature, used by [_futurize]. diff --git a/engine/src/flutter/lib/ui/painting/canvas.cc b/engine/src/flutter/lib/ui/painting/canvas.cc index ea5f583aaac..dacc6c4cae8 100644 --- a/engine/src/flutter/lib/ui/painting/canvas.cc +++ b/engine/src/flutter/lib/ui/painting/canvas.cc @@ -13,6 +13,7 @@ #include "flutter/flow/layers/physical_shape_layer.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/lib/ui/painting/matrix.h" +#include "flutter/lib/ui/painting/paint.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/lib/ui/window/window.h" @@ -28,62 +29,20 @@ using tonic::ToDart; namespace flutter { -static void Canvas_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&Canvas::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, Canvas); -#define FOR_EACH_BINDING(V) \ - V(Canvas, save) \ - V(Canvas, saveLayerWithoutBounds) \ - V(Canvas, saveLayer) \ - V(Canvas, restore) \ - V(Canvas, getSaveCount) \ - V(Canvas, translate) \ - V(Canvas, scale) \ - V(Canvas, rotate) \ - V(Canvas, skew) \ - V(Canvas, transform) \ - V(Canvas, clipRect) \ - V(Canvas, clipRRect) \ - V(Canvas, clipPath) \ - V(Canvas, drawColor) \ - V(Canvas, drawLine) \ - V(Canvas, drawPaint) \ - V(Canvas, drawRect) \ - V(Canvas, drawRRect) \ - V(Canvas, drawDRRect) \ - V(Canvas, drawOval) \ - V(Canvas, drawCircle) \ - V(Canvas, drawArc) \ - V(Canvas, drawPath) \ - V(Canvas, drawImage) \ - V(Canvas, drawImageRect) \ - V(Canvas, drawImageNine) \ - V(Canvas, drawPicture) \ - V(Canvas, drawPoints) \ - V(Canvas, drawVertices) \ - V(Canvas, drawAtlas) \ - V(Canvas, drawShadow) +void Canvas::Create(Dart_Handle wrapper, + PictureRecorder* recorder, + double left, + double top, + double right, + double bottom) { + UIDartState::ThrowIfUIOperationsProhibited(); -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void Canvas::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({{"Canvas_constructor", Canvas_constructor, 6, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr Canvas::Create(PictureRecorder* recorder, - double left, - double top, - double right, - double bottom) { if (!recorder) { Dart_ThrowException( ToDart("Canvas constructor called with non-genuine PictureRecorder.")); - return nullptr; + return; } // This call will implicitly initialize the |canvas_| field with an SkCanvas @@ -98,7 +57,7 @@ fml::RefPtr Canvas::Create(PictureRecorder* recorder, recorder->BeginRecording(SkRect::MakeLTRB(left, top, right, bottom))); recorder->set_canvas(canvas); canvas->display_list_recorder_ = recorder->display_list_recorder(); - return canvas; + canvas->AssociateWithDartWrapper(wrapper); } Canvas::Canvas(SkCanvas* canvas) : canvas_(canvas) {} @@ -113,8 +72,10 @@ void Canvas::save() { } } -void Canvas::saveLayerWithoutBounds(const Paint& paint, - const PaintData& paint_data) { +void Canvas::saveLayerWithoutBounds(Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { bool restore_with_paint = @@ -133,8 +94,10 @@ void Canvas::saveLayer(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom); if (display_list_recorder_) { @@ -267,8 +230,10 @@ void Canvas::drawLine(double x1, double y1, double x2, double y2, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawLineFlags); @@ -279,7 +244,9 @@ void Canvas::drawLine(double x1, } } -void Canvas::drawPaint(const Paint& paint, const PaintData& paint_data) { +void Canvas::drawPaint(Dart_Handle paint_objects, Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawPaintFlags); @@ -307,8 +274,10 @@ void Canvas::drawRect(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawRectFlags); @@ -321,8 +290,10 @@ void Canvas::drawRect(double left, } void Canvas::drawRRect(const RRect& rrect, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawRRectFlags); @@ -335,8 +306,10 @@ void Canvas::drawRRect(const RRect& rrect, void Canvas::drawDRRect(const RRect& outer, const RRect& inner, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawDRRectFlags); @@ -351,8 +324,10 @@ void Canvas::drawOval(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawOvalFlags); @@ -367,8 +342,10 @@ void Canvas::drawOval(double left, void Canvas::drawCircle(double x, double y, double radius, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), kDrawCircleFlags); @@ -386,8 +363,10 @@ void Canvas::drawArc(double left, double startAngle, double sweepAngle, bool useCenter, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (display_list_recorder_) { paint.sync_to(builder(), @@ -406,8 +385,10 @@ void Canvas::drawArc(double left, } void Canvas::drawPath(const CanvasPath* path, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (!path) { Dart_ThrowException( @@ -426,9 +407,11 @@ void Canvas::drawPath(const CanvasPath* path, void Canvas::drawImage(const CanvasImage* image, double x, double y, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (!image) { Dart_ThrowException( @@ -463,9 +446,11 @@ void Canvas::drawImageRect(const CanvasImage* image, double dst_top, double dst_right, double dst_bottom, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (!image) { Dart_ThrowException( @@ -505,9 +490,11 @@ void Canvas::drawImageNine(const CanvasImage* image, double dst_top, double dst_right, double dst_bottom, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int bitmapSamplingIndex) { + Paint paint(paint_objects, paint_data); + FML_DCHECK(paint.isNotNull()); if (!image) { Dart_ThrowException( @@ -563,10 +550,12 @@ void Canvas::drawPicture(Picture* picture) { } } -void Canvas::drawPoints(const Paint& paint, - const PaintData& paint_data, +void Canvas::drawPoints(Dart_Handle paint_objects, + Dart_Handle paint_data, SkCanvas::PointMode point_mode, const tonic::Float32List& points) { + Paint paint(paint_objects, paint_data); + static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint doesn't use floats."); @@ -597,8 +586,10 @@ void Canvas::drawPoints(const Paint& paint, void Canvas::drawVertices(const Vertices* vertices, DlBlendMode blend_mode, - const Paint& paint, - const PaintData& paint_data) { + Dart_Handle paint_objects, + Dart_Handle paint_data) { + Paint paint(paint_objects, paint_data); + if (!vertices) { Dart_ThrowException( ToDart("Canvas.drawVertices called with non-genuine Vertices.")); @@ -615,8 +606,8 @@ void Canvas::drawVertices(const Vertices* vertices, } } -void Canvas::drawAtlas(const Paint& paint, - const PaintData& paint_data, +void Canvas::drawAtlas(Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex, CanvasImage* atlas, const tonic::Float32List& transforms, @@ -624,6 +615,8 @@ void Canvas::drawAtlas(const Paint& paint, const tonic::Int32List& colors, DlBlendMode blend_mode, const tonic::Float32List& cull_rect) { + Paint paint(paint_objects, paint_data); + if (!atlas) { Dart_ThrowException( ToDart("Canvas.drawAtlas or Canvas.drawRawAtlas called with " diff --git a/engine/src/flutter/lib/ui/painting/canvas.h b/engine/src/flutter/lib/ui/painting/canvas.h index 1d3c4e3bce1..1f6ec255d3a 100644 --- a/engine/src/flutter/lib/ui/painting/canvas.h +++ b/engine/src/flutter/lib/ui/painting/canvas.h @@ -13,14 +13,11 @@ #include "flutter/lib/ui/painting/picture_recorder.h" #include "flutter/lib/ui/painting/rrect.h" #include "flutter/lib/ui/painting/vertices.h" +#include "flutter/lib/ui/ui_dart_state.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/utils/SkShadowUtils.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class CanvasImage; @@ -29,22 +26,26 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { FML_FRIEND_MAKE_REF_COUNTED(Canvas); public: - static fml::RefPtr Create(PictureRecorder* recorder, - double left, - double top, - double right, - double bottom); + static void Create(Dart_Handle wrapper, + PictureRecorder* recorder, + double left, + double top, + double right, + double bottom); ~Canvas() override; void save(); - void saveLayerWithoutBounds(const Paint& paint, const PaintData& paint_data); + void saveLayerWithoutBounds(Dart_Handle paint_objects, + Dart_Handle paint_data); + void saveLayer(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void restore(); int getSaveCount(); @@ -64,37 +65,45 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { void clipPath(const CanvasPath* path, bool doAntiAlias = true); void drawColor(SkColor color, DlBlendMode blend_mode); + void drawLine(double x1, double y1, double x2, double y2, - const Paint& paint, - const PaintData& paint_data); - void drawPaint(const Paint& paint, const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + + void drawPaint(Dart_Handle paint_objects, Dart_Handle paint_data); + void drawRect(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawRRect(const RRect& rrect, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawDRRect(const RRect& outer, const RRect& inner, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawOval(double left, double top, double right, double bottom, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawCircle(double x, double y, double radius, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawArc(double left, double top, double right, @@ -102,17 +111,20 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { double startAngle, double sweepAngle, bool useCenter, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawPath(const CanvasPath* path, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); + void drawImage(const CanvasImage* image, double x, double y, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex); + void drawImageRect(const CanvasImage* image, double src_left, double src_top, @@ -122,9 +134,10 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { double dst_top, double dst_right, double dst_bottom, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex); + void drawImageNine(const CanvasImage* image, double center_left, double center_top, @@ -134,9 +147,10 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { double dst_top, double dst_right, double dst_bottom, - const Paint& paint, - const PaintData& paint_data, + Dart_Handle paint_objects, + Dart_Handle paint_data, int bitmapSamplingIndex); + void drawPicture(Picture* picture); // The paint argument is first for the following functions because Paint @@ -144,18 +158,18 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { // Float32List, we cannot re-enter the VM to unwrap objects. That means we // either need to process the paint argument first. - void drawPoints(const Paint& paint, - const PaintData& paint_data, + void drawPoints(Dart_Handle paint_objects, + Dart_Handle paint_data, SkCanvas::PointMode point_mode, const tonic::Float32List& points); void drawVertices(const Vertices* vertices, DlBlendMode blend_mode, - const Paint& paint, - const PaintData& paint_data); + Dart_Handle paint_objects, + Dart_Handle paint_data); - void drawAtlas(const Paint& paint, - const PaintData& paint_data, + void drawAtlas(Dart_Handle paint_objects, + Dart_Handle paint_data, int filterQualityIndex, CanvasImage* atlas, const tonic::Float32List& transforms, @@ -172,8 +186,6 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { SkCanvas* canvas() const { return canvas_; } void Invalidate(); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: explicit Canvas(SkCanvas* canvas); diff --git a/engine/src/flutter/lib/ui/painting/codec.cc b/engine/src/flutter/lib/ui/painting/codec.cc index 0f8325c17d4..d27f999f1b8 100644 --- a/engine/src/flutter/lib/ui/painting/codec.cc +++ b/engine/src/flutter/lib/ui/painting/codec.cc @@ -10,28 +10,12 @@ #include "third_party/tonic/logging/dart_invoke.h" #include "third_party/tonic/typed_data/typed_list.h" -using tonic::DartInvoke; -using tonic::DartPersistentValue; -using tonic::ToDart; - namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Codec); -#define FOR_EACH_BINDING(V) \ - V(Codec, getNextFrame) \ - V(Codec, frameCount) \ - V(Codec, repetitionCount) \ - V(Codec, dispose) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - void Codec::dispose() { ClearDartWrapper(); } -void Codec::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - } // namespace flutter diff --git a/engine/src/flutter/lib/ui/painting/codec.h b/engine/src/flutter/lib/ui/painting/codec.h index 4740a3488d4..a41b31095b6 100644 --- a/engine/src/flutter/lib/ui/painting/codec.h +++ b/engine/src/flutter/lib/ui/painting/codec.h @@ -11,12 +11,6 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkImage.h" -using tonic::DartPersistentValue; - -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { // A handle to an SkCodec object. @@ -33,8 +27,6 @@ class Codec : public RefCountedDartWrappable { virtual Dart_Handle getNextFrame(Dart_Handle callback_handle) = 0; void dispose(); - - static void RegisterNatives(tonic::DartLibraryNatives* natives); }; } // namespace flutter diff --git a/engine/src/flutter/lib/ui/painting/color_filter.cc b/engine/src/flutter/lib/ui/painting/color_filter.cc index 2f8b6921a04..12b0db95892 100644 --- a/engine/src/flutter/lib/ui/painting/color_filter.cc +++ b/engine/src/flutter/lib/ui/painting/color_filter.cc @@ -14,29 +14,12 @@ namespace flutter { -static void ColorFilter_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&ColorFilter::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, ColorFilter); -#define FOR_EACH_BINDING(V) \ - V(ColorFilter, initMode) \ - V(ColorFilter, initMatrix) \ - V(ColorFilter, initSrgbToLinearGamma) \ - V(ColorFilter, initLinearToSrgbGamma) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void ColorFilter::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"ColorFilter_constructor", ColorFilter_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr ColorFilter::Create() { - return fml::MakeRefCounted(); +void ColorFilter::Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } void ColorFilter::initMode(int color, int blend_mode) { diff --git a/engine/src/flutter/lib/ui/painting/color_filter.h b/engine/src/flutter/lib/ui/painting/color_filter.h index 42b3f5aefa9..f80c48d96fe 100644 --- a/engine/src/flutter/lib/ui/painting/color_filter.h +++ b/engine/src/flutter/lib/ui/painting/color_filter.h @@ -11,10 +11,6 @@ using tonic::DartPersistentValue; -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { // A handle to an SkCodec object. @@ -25,7 +21,7 @@ class ColorFilter : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(ColorFilter); public: - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); void initMode(int color, int blend_mode); void initMatrix(const tonic::Float32List& color_matrix); @@ -39,8 +35,6 @@ class ColorFilter : public RefCountedDartWrappable { return (filter_ && filter_->skia_object()) ? filter_.get() : nullptr; } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: std::shared_ptr filter_; }; diff --git a/engine/src/flutter/lib/ui/painting/engine_layer.cc b/engine/src/flutter/lib/ui/painting/engine_layer.cc index 0f3e0b73787..d8e34f190e7 100644 --- a/engine/src/flutter/lib/ui/painting/engine_layer.cc +++ b/engine/src/flutter/lib/ui/painting/engine_layer.cc @@ -10,16 +10,10 @@ #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" -using tonic::ToDart; - namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, EngineLayer); -#define FOR_EACH_BINDING(V) V(EngineLayer, dispose) - -DART_BIND_ALL(EngineLayer, FOR_EACH_BINDING) - EngineLayer::EngineLayer(std::shared_ptr layer) : layer_(layer) {} diff --git a/engine/src/flutter/lib/ui/painting/engine_layer.h b/engine/src/flutter/lib/ui/painting/engine_layer.h index 87ae5ab173b..e13a7517183 100644 --- a/engine/src/flutter/lib/ui/painting/engine_layer.h +++ b/engine/src/flutter/lib/ui/painting/engine_layer.h @@ -8,10 +8,6 @@ #include "flutter/flow/layers/container_layer.h" #include "flutter/lib/ui/dart_wrapper.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class EngineLayer; @@ -28,8 +24,6 @@ class EngineLayer : public RefCountedDartWrappable { engine_layer->AssociateWithDartWrapper(dart_handle); } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - void dispose(); std::shared_ptr Layer() const { return layer_; } diff --git a/engine/src/flutter/lib/ui/painting/fragment_program.cc b/engine/src/flutter/lib/ui/painting/fragment_program.cc index 5e476bb85f4..47da184421f 100644 --- a/engine/src/flutter/lib/ui/painting/fragment_program.cc +++ b/engine/src/flutter/lib/ui/painting/fragment_program.cc @@ -15,28 +15,10 @@ #include "third_party/tonic/dart_library_natives.h" #include "third_party/tonic/typed_data/typed_list.h" -using tonic::ToDart; - namespace flutter { -static void FragmentProgram_constructor(Dart_NativeArguments args) { - DartCallConstructor(&FragmentProgram::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, FragmentProgram); -#define FOR_EACH_BINDING(V) \ - V(FragmentProgram, init) \ - V(FragmentProgram, shader) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void FragmentProgram::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"FragmentProgram_constructor", FragmentProgram_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - void FragmentProgram::init(std::string sksl, bool debugPrintSksl) { SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(SkString(sksl)); @@ -53,12 +35,12 @@ void FragmentProgram::init(std::string sksl, bool debugPrintSksl) { } } -fml::RefPtr FragmentProgram::shader( - Dart_Handle shader, - tonic::Float32List& uniforms, - Dart_Handle samplers) { +fml::RefPtr FragmentProgram::shader(Dart_Handle shader, + Dart_Handle uniforms_handle, + Dart_Handle samplers) { auto sampler_shaders = tonic::DartConverter>::FromDart(samplers); + tonic::Float32List uniforms(uniforms_handle); size_t uniform_count = uniforms.num_elements(); size_t uniform_data_size = (uniform_count + 2 * sampler_shaders.size()) * sizeof(float); @@ -86,8 +68,9 @@ fml::RefPtr FragmentProgram::shader( return FragmentShader::Create(shader, std::move(sk_shader)); } -fml::RefPtr FragmentProgram::Create() { - return fml::MakeRefCounted(); +void FragmentProgram::Create(Dart_Handle wrapper) { + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } FragmentProgram::FragmentProgram() = default; diff --git a/engine/src/flutter/lib/ui/painting/fragment_program.h b/engine/src/flutter/lib/ui/painting/fragment_program.h index a1b518a3b81..c53f4e3d817 100644 --- a/engine/src/flutter/lib/ui/painting/fragment_program.h +++ b/engine/src/flutter/lib/ui/painting/fragment_program.h @@ -14,10 +14,6 @@ #include #include -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class FragmentProgram : public RefCountedDartWrappable { @@ -26,16 +22,14 @@ class FragmentProgram : public RefCountedDartWrappable { public: ~FragmentProgram() override; - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); void init(std::string sksl, bool debugPrintSksl); fml::RefPtr shader(Dart_Handle shader, - tonic::Float32List& uniforms, + Dart_Handle uniforms_handle, Dart_Handle samplers); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: FragmentProgram(); sk_sp runtime_effect_; diff --git a/engine/src/flutter/lib/ui/painting/fragment_shader.cc b/engine/src/flutter/lib/ui/painting/fragment_shader.cc index f40ce89eefa..61a21c427f1 100644 --- a/engine/src/flutter/lib/ui/painting/fragment_shader.cc +++ b/engine/src/flutter/lib/ui/painting/fragment_shader.cc @@ -15,8 +15,6 @@ #include "third_party/tonic/dart_library_natives.h" #include "third_party/tonic/typed_data/typed_list.h" -using tonic::ToDart; - namespace flutter { // Since _FragmentShader is a private class, we can't use @@ -29,12 +27,8 @@ static const tonic::DartWrapperInfo kDartWrapperInfo_ui_FragmentShader = { const tonic::DartWrapperInfo& FragmentShader::dart_wrapper_info_ = kDartWrapperInfo_ui_FragmentShader; -void FragmentShader::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({}); -} - std::shared_ptr FragmentShader::shader( - SkSamplingOptions& sampling) { + const SkSamplingOptions& sampling) { // Sampling options are ignored, since sampling options don't make sense for // generative shaders. return source_; diff --git a/engine/src/flutter/lib/ui/painting/fragment_shader.h b/engine/src/flutter/lib/ui/painting/fragment_shader.h index c3ff8851256..6e9248bf114 100644 --- a/engine/src/flutter/lib/ui/painting/fragment_shader.h +++ b/engine/src/flutter/lib/ui/painting/fragment_shader.h @@ -17,10 +17,6 @@ #include #include -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class FragmentShader : public Shader { @@ -32,9 +28,7 @@ class FragmentShader : public Shader { static fml::RefPtr Create(Dart_Handle dart_handle, sk_sp shader); - std::shared_ptr shader(SkSamplingOptions&) override; - - static void RegisterNatives(tonic::DartLibraryNatives* natives); + std::shared_ptr shader(const SkSamplingOptions&) override; private: explicit FragmentShader(sk_sp shader); diff --git a/engine/src/flutter/lib/ui/painting/gradient.cc b/engine/src/flutter/lib/ui/painting/gradient.cc index 0a291fc35ab..9651982c183 100644 --- a/engine/src/flutter/lib/ui/painting/gradient.cc +++ b/engine/src/flutter/lib/ui/painting/gradient.cc @@ -14,28 +14,12 @@ namespace flutter { typedef CanvasGradient Gradient; // Because the C++ name doesn't match the Dart name. -static void Gradient_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&CanvasGradient::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, Gradient); -#define FOR_EACH_BINDING(V) \ - V(Gradient, initLinear) \ - V(Gradient, initRadial) \ - V(Gradient, initSweep) \ - V(Gradient, initTwoPointConical) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void CanvasGradient::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({{"Gradient_constructor", Gradient_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr CanvasGradient::Create() { - return fml::MakeRefCounted(); +void CanvasGradient::Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } void CanvasGradient::initLinear(const tonic::Float32List& end_points, diff --git a/engine/src/flutter/lib/ui/painting/gradient.h b/engine/src/flutter/lib/ui/painting/gradient.h index a50048d48e2..45d80483494 100644 --- a/engine/src/flutter/lib/ui/painting/gradient.h +++ b/engine/src/flutter/lib/ui/painting/gradient.h @@ -10,10 +10,6 @@ #include "flutter/lib/ui/painting/shader.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { // TODO: update this if/when Skia adds Decal mode skbug.com/7638 @@ -25,7 +21,7 @@ class CanvasGradient : public Shader { public: ~CanvasGradient() override; - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); void initLinear(const tonic::Float32List& end_points, const tonic::Int32List& colors, @@ -61,12 +57,11 @@ class CanvasGradient : public Shader { SkTileMode tile_mode, const tonic::Float64List& matrix4); - std::shared_ptr shader(SkSamplingOptions& sampling) override { + std::shared_ptr shader( + const SkSamplingOptions& sampling) override { return dl_shader_->with_sampling(sampling); } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: CanvasGradient(); std::shared_ptr dl_shader_; diff --git a/engine/src/flutter/lib/ui/painting/image.cc b/engine/src/flutter/lib/ui/painting/image.cc index 3e8865e5555..de81f36ebe4 100644 --- a/engine/src/flutter/lib/ui/painting/image.cc +++ b/engine/src/flutter/lib/ui/painting/image.cc @@ -23,18 +23,6 @@ static const tonic::DartWrapperInfo kDartWrapperInfo_ui_Image = { const tonic::DartWrapperInfo& Image::dart_wrapper_info_ = kDartWrapperInfo_ui_Image; -#define FOR_EACH_BINDING(V) \ - V(Image, width) \ - V(Image, height) \ - V(Image, toByteData) \ - V(Image, dispose) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void CanvasImage::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - CanvasImage::CanvasImage() = default; CanvasImage::~CanvasImage() = default; diff --git a/engine/src/flutter/lib/ui/painting/image.h b/engine/src/flutter/lib/ui/painting/image.h index d9466720768..d7a9bb3d9c5 100644 --- a/engine/src/flutter/lib/ui/painting/image.h +++ b/engine/src/flutter/lib/ui/painting/image.h @@ -12,10 +12,6 @@ #include "flutter/lib/ui/ui_dart_state.h" #include "third_party/skia/include/core/SkImage.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class CanvasImage final : public RefCountedDartWrappable { @@ -43,8 +39,6 @@ class CanvasImage final : public RefCountedDartWrappable { size_t GetAllocationSize() const override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: CanvasImage(); diff --git a/engine/src/flutter/lib/ui/painting/image_descriptor.cc b/engine/src/flutter/lib/ui/painting/image_descriptor.cc index 75f0ec1a93e..5c117008df1 100644 --- a/engine/src/flutter/lib/ui/painting/image_descriptor.cc +++ b/engine/src/flutter/lib/ui/painting/image_descriptor.cc @@ -17,22 +17,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, ImageDescriptor); -#define FOR_EACH_BINDING(V) \ - V(ImageDescriptor, initRaw) \ - V(ImageDescriptor, instantiateCodec) \ - V(ImageDescriptor, width) \ - V(ImageDescriptor, height) \ - V(ImageDescriptor, bytesPerPixel) \ - V(ImageDescriptor, dispose) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void ImageDescriptor::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"ImageDescriptor_initEncoded", ImageDescriptor::initEncoded, 3, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - const SkImageInfo ImageDescriptor::CreateImageInfo() const { FML_DCHECK(generator_); return generator_->GetInfo(); @@ -53,22 +37,15 @@ ImageDescriptor::ImageDescriptor(sk_sp buffer, image_info_(CreateImageInfo()), row_bytes_(std::nullopt) {} -void ImageDescriptor::initEncoded(Dart_NativeArguments args) { - Dart_Handle callback_handle = Dart_GetNativeArgument(args, 2); +Dart_Handle ImageDescriptor::initEncoded(Dart_Handle descriptor_handle, + ImmutableBuffer* immutable_buffer, + Dart_Handle callback_handle) { if (!Dart_IsClosure(callback_handle)) { - Dart_SetReturnValue(args, tonic::ToDart("Callback must be a function")); - return; + return tonic::ToDart("Callback must be a function"); } - Dart_Handle descriptor_handle = Dart_GetNativeArgument(args, 0); - ImmutableBuffer* immutable_buffer = - tonic::DartConverter::FromDart( - Dart_GetNativeArgument(args, 1)); - if (!immutable_buffer) { - Dart_SetReturnValue(args, - tonic::ToDart("Buffer parameter must not be null")); - return; + return tonic::ToDart("Buffer parameter must not be null"); } // This has to be valid because this method is called from Dart. @@ -76,11 +53,10 @@ void ImageDescriptor::initEncoded(Dart_NativeArguments args) { auto registry = dart_state->GetImageGeneratorRegistry(); if (!registry) { - Dart_SetReturnValue( - args, tonic::ToDart("Failed to access the internal image decoder " - "registry on this isolate. Please file a bug on " - "https://github.com/flutter/flutter/issues.")); - return; + return tonic::ToDart( + "Failed to access the internal image decoder " + "registry on this isolate. Please file a bug on " + "https://github.com/flutter/flutter/issues."); } auto generator = @@ -88,8 +64,7 @@ void ImageDescriptor::initEncoded(Dart_NativeArguments args) { if (!generator) { // No compatible image decoder was found. - Dart_SetReturnValue(args, tonic::ToDart("Invalid image data")); - return; + return tonic::ToDart("Invalid image data"); } auto descriptor = fml::MakeRefCounted( @@ -99,6 +74,8 @@ void ImageDescriptor::initEncoded(Dart_NativeArguments args) { descriptor->AssociateWithDartWrapper(descriptor_handle); tonic::DartInvoke(callback_handle, {Dart_TypeVoid()}); + + return Dart_Null(); } void ImageDescriptor::initRaw(Dart_Handle descriptor_handle, diff --git a/engine/src/flutter/lib/ui/painting/image_descriptor.h b/engine/src/flutter/lib/ui/painting/image_descriptor.h index 10e6c150137..271a60a4dd0 100644 --- a/engine/src/flutter/lib/ui/painting/image_descriptor.h +++ b/engine/src/flutter/lib/ui/painting/image_descriptor.h @@ -44,7 +44,9 @@ class ImageDescriptor : public RefCountedDartWrappable { /// an `ImageGenerator` and read EXIF corrected dimensions from the /// image data. /// @see `ImageGeneratorRegistry` - static void initEncoded(Dart_NativeArguments args); + static Dart_Handle initEncoded(Dart_Handle descriptor_handle, + ImmutableBuffer* immutable_buffer, + Dart_Handle callback_handle); /// @brief Synchronously initializes an `ImageDescriptor` for decompressed /// image data as specified by the `PixelFormat`. @@ -116,8 +118,6 @@ class ImageDescriptor : public RefCountedDartWrappable { return sizeof(ImageDescriptor) + sizeof(SkImageInfo) + buffer_->size(); } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: ImageDescriptor(sk_sp buffer, const SkImageInfo& image_info, diff --git a/engine/src/flutter/lib/ui/painting/image_filter.cc b/engine/src/flutter/lib/ui/painting/image_filter.cc index 47132fc1b53..a03711bf4ff 100644 --- a/engine/src/flutter/lib/ui/painting/image_filter.cc +++ b/engine/src/flutter/lib/ui/painting/image_filter.cc @@ -13,31 +13,12 @@ namespace flutter { -static void ImageFilter_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&ImageFilter::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, ImageFilter); -#define FOR_EACH_BINDING(V) \ - V(ImageFilter, initBlur) \ - V(ImageFilter, initDilate) \ - V(ImageFilter, initErode) \ - V(ImageFilter, initMatrix) \ - V(ImageFilter, initColorFilter) \ - V(ImageFilter, initComposeFilter) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void ImageFilter::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"ImageFilter_constructor", ImageFilter_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr ImageFilter::Create() { - return fml::MakeRefCounted(); +void ImageFilter::Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } static const std::array filter_qualities = { diff --git a/engine/src/flutter/lib/ui/painting/image_filter.h b/engine/src/flutter/lib/ui/painting/image_filter.h index 101162e779e..e3ebb5d8749 100644 --- a/engine/src/flutter/lib/ui/painting/image_filter.h +++ b/engine/src/flutter/lib/ui/painting/image_filter.h @@ -24,7 +24,7 @@ class ImageFilter : public RefCountedDartWrappable { public: ~ImageFilter() override; - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); static SkSamplingOptions SamplingFromIndex(int filterQualityIndex); static SkFilterMode FilterModeFromIndex(int index); diff --git a/engine/src/flutter/lib/ui/painting/image_shader.cc b/engine/src/flutter/lib/ui/painting/image_shader.cc index 634b0246918..b9aeb963761 100644 --- a/engine/src/flutter/lib/ui/painting/image_shader.cc +++ b/engine/src/flutter/lib/ui/painting/image_shader.cc @@ -15,24 +15,11 @@ using tonic::ToDart; namespace flutter { -static void ImageShader_constructor(Dart_NativeArguments args) { - DartCallConstructor(&ImageShader::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, ImageShader); -#define FOR_EACH_BINDING(V) V(ImageShader, initWithImage) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void ImageShader::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"ImageShader_constructor", ImageShader_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr ImageShader::Create() { - return fml::MakeRefCounted(); +void ImageShader::Create(Dart_Handle wrapper) { + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } void ImageShader::initWithImage(CanvasImage* image, @@ -62,9 +49,10 @@ void ImageShader::initWithImage(CanvasImage* image, } std::shared_ptr ImageShader::shader( - SkSamplingOptions& sampling) { + const SkSamplingOptions& sampling) { if (sampling_is_locked_) { - sampling = cached_shader_.skia_object()->sampling(); + return cached_shader_.skia_object()->with_sampling( + cached_shader_.skia_object()->sampling()); } // It might seem that if the sampling is locked we can just return the // cached version, but since we need to hold the cached shader in a diff --git a/engine/src/flutter/lib/ui/painting/image_shader.h b/engine/src/flutter/lib/ui/painting/image_shader.h index cc54419f4a3..5385e156bae 100644 --- a/engine/src/flutter/lib/ui/painting/image_shader.h +++ b/engine/src/flutter/lib/ui/painting/image_shader.h @@ -14,10 +14,6 @@ #include "third_party/skia/include/core/SkShader.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class ImageShader : public Shader { @@ -26,7 +22,7 @@ class ImageShader : public Shader { public: ~ImageShader() override; - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); void initWithImage(CanvasImage* image, SkTileMode tmx, @@ -34,9 +30,7 @@ class ImageShader : public Shader { int filter_quality_index, const tonic::Float64List& matrix4); - std::shared_ptr shader(SkSamplingOptions&) override; - - static void RegisterNatives(tonic::DartLibraryNatives* natives); + std::shared_ptr shader(const SkSamplingOptions&) override; int width(); int height(); diff --git a/engine/src/flutter/lib/ui/painting/immutable_buffer.cc b/engine/src/flutter/lib/ui/painting/immutable_buffer.cc index e4d3f630de7..b49990b61bb 100644 --- a/engine/src/flutter/lib/ui/painting/immutable_buffer.cc +++ b/engine/src/flutter/lib/ui/painting/immutable_buffer.cc @@ -19,34 +19,24 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, ImmutableBuffer); -#define FOR_EACH_BINDING(V) \ - V(ImmutableBuffer, dispose) \ - V(ImmutableBuffer, length) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - ImmutableBuffer::~ImmutableBuffer() {} -void ImmutableBuffer::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({{"ImmutableBuffer_init", ImmutableBuffer::init, 3, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -void ImmutableBuffer::init(Dart_NativeArguments args) { - Dart_Handle callback_handle = Dart_GetNativeArgument(args, 2); +Dart_Handle ImmutableBuffer::init(Dart_Handle buffer_handle, + Dart_Handle data, + Dart_Handle callback_handle) { if (!Dart_IsClosure(callback_handle)) { - Dart_SetReturnValue(args, tonic::ToDart("Callback must be a function")); - return; + return tonic::ToDart("Callback must be a function"); } - Dart_Handle buffer_handle = Dart_GetNativeArgument(args, 0); - tonic::Uint8List data = tonic::Uint8List(Dart_GetNativeArgument(args, 1)); + tonic::Uint8List dataList = tonic::Uint8List(data); - auto sk_data = MakeSkDataWithCopy(data.data(), data.num_elements()); - data.Release(); + auto sk_data = MakeSkDataWithCopy(dataList.data(), dataList.num_elements()); + dataList.Release(); auto buffer = fml::MakeRefCounted(sk_data); buffer->AssociateWithDartWrapper(buffer_handle); tonic::DartInvoke(callback_handle, {Dart_TypeVoid()}); + + return Dart_Null(); } size_t ImmutableBuffer::GetAllocationSize() const { diff --git a/engine/src/flutter/lib/ui/painting/immutable_buffer.h b/engine/src/flutter/lib/ui/painting/immutable_buffer.h index 6306dd99f0a..0697cd5f975 100644 --- a/engine/src/flutter/lib/ui/painting/immutable_buffer.h +++ b/engine/src/flutter/lib/ui/painting/immutable_buffer.h @@ -30,14 +30,16 @@ class ImmutableBuffer : public RefCountedDartWrappable { /// Initializes a new ImmutableData from a Dart Uint8List. /// - /// The zero indexed argument is the caller that will be registered as the - /// Dart peer of the native ImmutableBuffer object. + /// `buffer_handle` is the caller that will be registered as the Dart peer of + /// the native ImmutableBuffer object. /// - /// The first indexed argumented is a tonic::Uint8List of bytes to copy. + /// `data` is a tonic::Uint8List of bytes to copy. /// - /// The second indexed argument is expected to be a void callback to signal - /// when the copy has completed. - static void init(Dart_NativeArguments args); + /// `callback_handle` is expected to be a void callback to signal when the + /// copy has completed. + static Dart_Handle init(Dart_Handle buffer_handle, + Dart_Handle data, + Dart_Handle callback_handle); /// The length of the data in bytes. size_t length() const { @@ -60,8 +62,6 @@ class ImmutableBuffer : public RefCountedDartWrappable { size_t GetAllocationSize() const override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: explicit ImmutableBuffer(sk_sp data) : data_(std::move(data)) {} diff --git a/engine/src/flutter/lib/ui/painting/multi_frame_codec.h b/engine/src/flutter/lib/ui/painting/multi_frame_codec.h index 0072131ad42..ba394bb69a9 100644 --- a/engine/src/flutter/lib/ui/painting/multi_frame_codec.h +++ b/engine/src/flutter/lib/ui/painting/multi_frame_codec.h @@ -9,6 +9,8 @@ #include "flutter/lib/ui/painting/codec.h" #include "flutter/lib/ui/painting/image_generator.h" +using tonic::DartPersistentValue; + namespace flutter { class MultiFrameCodec : public Codec { diff --git a/engine/src/flutter/lib/ui/painting/path.cc b/engine/src/flutter/lib/ui/painting/path.cc index be9762dd7e4..938ecaa1413 100644 --- a/engine/src/flutter/lib/ui/painting/path.cc +++ b/engine/src/flutter/lib/ui/painting/path.cc @@ -19,54 +19,8 @@ namespace flutter { typedef CanvasPath Path; -static void Path_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&CanvasPath::CreateNew, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, Path); -#define FOR_EACH_BINDING(V) \ - V(Path, addArc) \ - V(Path, addOval) \ - V(Path, addPath) \ - V(Path, addPolygon) \ - V(Path, addRect) \ - V(Path, addRRect) \ - V(Path, arcTo) \ - V(Path, arcToPoint) \ - V(Path, close) \ - V(Path, conicTo) \ - V(Path, contains) \ - V(Path, cubicTo) \ - V(Path, extendWithPath) \ - V(Path, extendWithPathAndMatrix) \ - V(Path, getFillType) \ - V(Path, lineTo) \ - V(Path, moveTo) \ - V(Path, quadraticBezierTo) \ - V(Path, relativeArcToPoint) \ - V(Path, relativeConicTo) \ - V(Path, relativeCubicTo) \ - V(Path, relativeLineTo) \ - V(Path, relativeMoveTo) \ - V(Path, relativeQuadraticBezierTo) \ - V(Path, reset) \ - V(Path, setFillType) \ - V(Path, shift) \ - V(Path, transform) \ - V(Path, getBounds) \ - V(Path, addPathWithMatrix) \ - V(Path, op) \ - V(Path, clone) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void CanvasPath::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({{"Path_constructor", Path_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - CanvasPath::CanvasPath() : path_tracker_(UIDartState::Current()->GetVolatilePathTracker()), tracked_path_(std::make_shared()) { @@ -251,7 +205,9 @@ void CanvasPath::addPath(CanvasPath* path, double dx, double dy) { void CanvasPath::addPathWithMatrix(CanvasPath* path, double dx, double dy, - tonic::Float64List& matrix4) { + Dart_Handle matrix4_handle) { + tonic::Float64List matrix4(matrix4_handle); + if (!path) { matrix4.Release(); Dart_ThrowException( @@ -280,7 +236,9 @@ void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) { void CanvasPath::extendWithPathAndMatrix(CanvasPath* path, double dx, double dy, - tonic::Float64List& matrix4) { + Dart_Handle matrix4_handle) { + tonic::Float64List matrix4(matrix4_handle); + if (!path) { matrix4.Release(); Dart_ThrowException( @@ -311,17 +269,18 @@ bool CanvasPath::contains(double x, double y) { } void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) { - fml::RefPtr path = CanvasPath::Create(path_handle); + fml::RefPtr path = Create(path_handle); auto& other_mutable_path = path->mutable_path(); mutable_path().offset(dx, dy, &other_mutable_path); resetVolatility(); } void CanvasPath::transform(Dart_Handle path_handle, - tonic::Float64List& matrix4) { + Dart_Handle matrix4_handle) { + tonic::Float64List matrix4(matrix4_handle); auto sk_matrix = ToSkMatrix(matrix4); matrix4.Release(); - fml::RefPtr path = CanvasPath::Create(path_handle); + fml::RefPtr path = Create(path_handle); auto& other_mutable_path = path->mutable_path(); mutable_path().transform(sk_matrix, &other_mutable_path); } @@ -343,7 +302,7 @@ bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) { } void CanvasPath::clone(Dart_Handle path_handle) { - fml::RefPtr path = CanvasPath::Create(path_handle); + fml::RefPtr path = Create(path_handle); // per Skia docs, this will create a fast copy // data is shared until the source path or dest path are mutated path->mutable_path() = this->path(); diff --git a/engine/src/flutter/lib/ui/painting/path.h b/engine/src/flutter/lib/ui/painting/path.h index f4c53560b15..1361497e181 100644 --- a/engine/src/flutter/lib/ui/painting/path.h +++ b/engine/src/flutter/lib/ui/painting/path.h @@ -7,15 +7,12 @@ #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/painting/rrect.h" +#include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/volatile_path_tracker.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/pathops/SkPathOps.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class CanvasPath : public RefCountedDartWrappable { @@ -24,21 +21,18 @@ class CanvasPath : public RefCountedDartWrappable { public: ~CanvasPath() override; - static fml::RefPtr CreateNew() { - return fml::MakeRefCounted(); - } - static fml::RefPtr Create(Dart_Handle path_handle) { + static void CreateFrom(Dart_Handle path_handle, const SkPath& src) { auto path = fml::MakeRefCounted(); path->AssociateWithDartWrapper(path_handle); - return path; + path->tracked_path_->path = src; } - static fml::RefPtr CreateFrom(Dart_Handle path_handle, - const SkPath& src) { - fml::RefPtr path = CanvasPath::Create(path_handle); - path->tracked_path_->path = src; - return path; + static fml::RefPtr Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); + return res; } int getFillType(); @@ -91,20 +85,26 @@ class CanvasPath : public RefCountedDartWrappable { void addPolygon(const tonic::Float32List& points, bool close); void addRRect(const RRect& rrect); void addPath(CanvasPath* path, double dx, double dy); + void addPathWithMatrix(CanvasPath* path, double dx, double dy, - tonic::Float64List& matrix4); + Dart_Handle matrix4_handle); + void extendWithPath(CanvasPath* path, double dx, double dy); + void extendWithPathAndMatrix(CanvasPath* path, double dx, double dy, - tonic::Float64List& matrix4); + Dart_Handle matrix4_handle); + void close(); void reset(); bool contains(double x, double y); void shift(Dart_Handle path_handle, double dx, double dy); - void transform(Dart_Handle path_handle, tonic::Float64List& matrix4); + + void transform(Dart_Handle path_handle, Dart_Handle matrix4_handle); + tonic::Float32List getBounds(); bool op(CanvasPath* path1, CanvasPath* path2, int operation); void clone(Dart_Handle path_handle); @@ -113,8 +113,6 @@ class CanvasPath : public RefCountedDartWrappable { size_t GetAllocationSize() const override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: CanvasPath(); diff --git a/engine/src/flutter/lib/ui/painting/path_measure.cc b/engine/src/flutter/lib/ui/painting/path_measure.cc index af9e0e9837e..a620efda68b 100644 --- a/engine/src/flutter/lib/ui/painting/path_measure.cc +++ b/engine/src/flutter/lib/ui/painting/path_measure.cc @@ -13,37 +13,16 @@ #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" -using tonic::ToDart; - namespace flutter { typedef CanvasPathMeasure PathMeasure; -static void PathMeasure_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&CanvasPathMeasure::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, PathMeasure); -#define FOR_EACH_BINDING(V) \ - V(PathMeasure, setPath) \ - V(PathMeasure, getLength) \ - V(PathMeasure, getPosTan) \ - V(PathMeasure, getSegment) \ - V(PathMeasure, isClosed) \ - V(PathMeasure, nextContour) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void CanvasPathMeasure::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"PathMeasure_constructor", PathMeasure_constructor, 3, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr CanvasPathMeasure::Create(const CanvasPath* path, - bool forceClosed) { +void CanvasPathMeasure::Create(Dart_Handle wrapper, + const CanvasPath* path, + bool forceClosed) { + UIDartState::ThrowIfUIOperationsProhibited(); fml::RefPtr pathMeasure = fml::MakeRefCounted(); if (path) { @@ -54,7 +33,7 @@ fml::RefPtr CanvasPathMeasure::Create(const CanvasPath* path, } else { pathMeasure->path_measure_ = std::make_unique(); } - return pathMeasure; + pathMeasure->AssociateWithDartWrapper(wrapper); } CanvasPathMeasure::CanvasPathMeasure() {} diff --git a/engine/src/flutter/lib/ui/painting/path_measure.h b/engine/src/flutter/lib/ui/painting/path_measure.h index 85a967919ed..32ee021c05f 100644 --- a/engine/src/flutter/lib/ui/painting/path_measure.h +++ b/engine/src/flutter/lib/ui/painting/path_measure.h @@ -13,10 +13,6 @@ #include "third_party/skia/include/core/SkPath.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - // Be sure that the client doesn't modify a path on us before Skia finishes // See AOSP's reasoning in PathMeasure.cpp @@ -28,8 +24,9 @@ class CanvasPathMeasure : public RefCountedDartWrappable { public: ~CanvasPathMeasure() override; - static fml::RefPtr Create(const CanvasPath* path, - bool forceClosed); + static void Create(Dart_Handle wrapper, + const CanvasPath* path, + bool forceClosed); void setPath(const CanvasPath* path, bool isClosed); float getLength(int contour_index); @@ -42,8 +39,6 @@ class CanvasPathMeasure : public RefCountedDartWrappable { bool isClosed(int contour_index); bool nextContour(); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - const SkContourMeasureIter& pathMeasure() const { return *path_measure_; } private: diff --git a/engine/src/flutter/lib/ui/painting/picture.cc b/engine/src/flutter/lib/ui/painting/picture.cc index 6ba11849f20..dfd20b2b727 100644 --- a/engine/src/flutter/lib/ui/painting/picture.cc +++ b/engine/src/flutter/lib/ui/painting/picture.cc @@ -21,13 +21,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Picture); -#define FOR_EACH_BINDING(V) \ - V(Picture, toImage) \ - V(Picture, dispose) \ - V(Picture, GetAllocationSize) - -DART_BIND_ALL(Picture, FOR_EACH_BINDING) - fml::RefPtr Picture::Create( Dart_Handle dart_handle, flutter::SkiaGPUObject picture) { diff --git a/engine/src/flutter/lib/ui/painting/picture.h b/engine/src/flutter/lib/ui/painting/picture.h index 046168baac0..9f52f0a541a 100644 --- a/engine/src/flutter/lib/ui/painting/picture.h +++ b/engine/src/flutter/lib/ui/painting/picture.h @@ -12,10 +12,6 @@ #include "flutter/lib/ui/ui_dart_state.h" #include "third_party/skia/include/core/SkPicture.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Canvas; @@ -44,8 +40,6 @@ class Picture : public RefCountedDartWrappable { size_t GetAllocationSize() const override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - static Dart_Handle RasterizeToImage(sk_sp picture, uint32_t width, uint32_t height, diff --git a/engine/src/flutter/lib/ui/painting/picture_recorder.cc b/engine/src/flutter/lib/ui/painting/picture_recorder.cc index 32c888aef4d..69294d8c29f 100644 --- a/engine/src/flutter/lib/ui/painting/picture_recorder.cc +++ b/engine/src/flutter/lib/ui/painting/picture_recorder.cc @@ -14,25 +14,12 @@ namespace flutter { -static void PictureRecorder_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&PictureRecorder::Create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, PictureRecorder); -#define FOR_EACH_BINDING(V) V(PictureRecorder, endRecording) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void PictureRecorder::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"PictureRecorder_constructor", PictureRecorder_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr PictureRecorder::Create() { - return fml::MakeRefCounted(); +void PictureRecorder::Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } PictureRecorder::PictureRecorder() {} diff --git a/engine/src/flutter/lib/ui/painting/picture_recorder.h b/engine/src/flutter/lib/ui/painting/picture_recorder.h index f1c73f4d5a7..d3a8c35ab92 100644 --- a/engine/src/flutter/lib/ui/painting/picture_recorder.h +++ b/engine/src/flutter/lib/ui/painting/picture_recorder.h @@ -9,10 +9,6 @@ #include "flutter/lib/ui/dart_wrapper.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Canvas; class Picture; @@ -22,7 +18,7 @@ class PictureRecorder : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(PictureRecorder); public: - static fml::RefPtr Create(); + static void Create(Dart_Handle wrapper); ~PictureRecorder() override; @@ -35,8 +31,6 @@ class PictureRecorder : public RefCountedDartWrappable { void set_canvas(fml::RefPtr canvas) { canvas_ = std::move(canvas); } - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: PictureRecorder(); diff --git a/engine/src/flutter/lib/ui/painting/shader.h b/engine/src/flutter/lib/ui/painting/shader.h index 8fefefbedc9..9e3f5f5b9e2 100644 --- a/engine/src/flutter/lib/ui/painting/shader.h +++ b/engine/src/flutter/lib/ui/painting/shader.h @@ -17,7 +17,7 @@ class Shader : public RefCountedDartWrappable { public: ~Shader() override; - virtual std::shared_ptr shader(SkSamplingOptions&) = 0; + virtual std::shared_ptr shader(const SkSamplingOptions&) = 0; protected: Shader() {} diff --git a/engine/src/flutter/lib/ui/painting/single_frame_codec.h b/engine/src/flutter/lib/ui/painting/single_frame_codec.h index 9685c047e3e..7e4ac13402a 100644 --- a/engine/src/flutter/lib/ui/painting/single_frame_codec.h +++ b/engine/src/flutter/lib/ui/painting/single_frame_codec.h @@ -11,6 +11,8 @@ #include "flutter/lib/ui/painting/image_decoder.h" #include "flutter/lib/ui/painting/image_descriptor.h" +using tonic::DartPersistentValue; + namespace flutter { class SingleFrameCodec : public Codec { diff --git a/engine/src/flutter/lib/ui/painting/vertices.cc b/engine/src/flutter/lib/ui/painting/vertices.cc index 96c8b83e589..e7680d115bf 100644 --- a/engine/src/flutter/lib/ui/painting/vertices.cc +++ b/engine/src/flutter/lib/ui/painting/vertices.cc @@ -14,26 +14,23 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Vertices); -#define FOR_EACH_BINDING(V) V(Vertices, init) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - Vertices::Vertices() {} Vertices::~Vertices() {} -void Vertices::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - bool Vertices::init(Dart_Handle vertices_handle, DlVertexMode vertex_mode, - tonic::Float32List& positions, - tonic::Float32List& texture_coordinates, - tonic::Int32List& colors, - tonic::Uint16List& indices) { + Dart_Handle positions_handle, + Dart_Handle texture_coordinates_handle, + Dart_Handle colors_handle, + Dart_Handle indices_handle) { UIDartState::ThrowIfUIOperationsProhibited(); + tonic::Float32List positions(positions_handle); + tonic::Float32List texture_coordinates(texture_coordinates_handle); + tonic::Int32List colors(colors_handle); + tonic::Uint16List indices(indices_handle); + if (!positions.data()) { return false; } diff --git a/engine/src/flutter/lib/ui/painting/vertices.h b/engine/src/flutter/lib/ui/painting/vertices.h index d327178c9bb..717562c80a9 100644 --- a/engine/src/flutter/lib/ui/painting/vertices.h +++ b/engine/src/flutter/lib/ui/painting/vertices.h @@ -10,10 +10,6 @@ #include "third_party/skia/include/core/SkVertices.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Vertices : public RefCountedDartWrappable { @@ -23,14 +19,12 @@ class Vertices : public RefCountedDartWrappable { public: ~Vertices() override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - static bool init(Dart_Handle vertices_handle, DlVertexMode vertex_mode, - tonic::Float32List& positions, - tonic::Float32List& texture_coordinates, - tonic::Int32List& colors, - tonic::Uint16List& indices); + Dart_Handle positions_handle, + Dart_Handle texture_coordinates_handle, + Dart_Handle colors_handle, + Dart_Handle indices_handle); const DlVertices* vertices() const { return vertices_.get(); } diff --git a/engine/src/flutter/lib/ui/platform_dispatcher.dart b/engine/src/flutter/lib/ui/platform_dispatcher.dart index 0ae3d6ae498..f7b769b50ea 100644 --- a/engine/src/flutter/lib/ui/platform_dispatcher.dart +++ b/engine/src/flutter/lib/ui/platform_dispatcher.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Signature of callbacks that have no arguments and return no data. @@ -255,7 +255,7 @@ class PlatformDispatcher { assert(bounds.length / 4 == type.length, 'Bounds are rectangles, requiring 4 measurements each'); assert(type.length == state.length); final List result = []; - for(int i = 0; i < type.length; i++){ + for(int i = 0; i < type.length; i++) { final int rectOffset = i * 4; result.add(DisplayFeature( bounds: Rect.fromLTRB( @@ -497,8 +497,11 @@ class PlatformDispatcher { } late _SetNeedsReportTimingsFunc _setNeedsReportTimings; - void _nativeSetNeedsReportTimings(bool value) - native 'PlatformConfiguration_setNeedsReportTimings'; + + void _nativeSetNeedsReportTimings(bool value) => __nativeSetNeedsReportTimings(value); + + @FfiNative('PlatformConfigurationNativeApi::SetNeedsReportTimings') + external static void __nativeSetNeedsReportTimings(bool value); // Called from the engine, via hooks.dart void _reportTimings(List timings) { @@ -526,8 +529,11 @@ class PlatformDispatcher { throw Exception(error); } - String? _sendPlatformMessage(String name, PlatformMessageResponseCallback? callback, ByteData? data) - native 'PlatformConfiguration_sendPlatformMessage'; + String? _sendPlatformMessage(String name,PlatformMessageResponseCallback? callback, ByteData? data) => + __sendPlatformMessage(name, callback, data); + + @FfiNative('PlatformConfigurationNativeApi::SendPlatformMessage') + external static String? __sendPlatformMessage(String name, PlatformMessageResponseCallback? callback, ByteData? data); /// Called whenever this platform dispatcher receives a message from a /// platform-specific plugin. @@ -553,8 +559,10 @@ class PlatformDispatcher { } /// Called by [_dispatchPlatformMessage]. - void _respondToPlatformMessage(int responseId, ByteData? data) - native 'PlatformConfiguration_respondToPlatformMessage'; + void _respondToPlatformMessage(int responseId, ByteData? data) => __respondToPlatformMessage(responseId, data); + + @FfiNative('PlatformConfigurationNativeApi::RespondToPlatformMessage') + external static void __respondToPlatformMessage(int responseId, ByteData? data); /// Wraps the given [callback] in another callback that ensures that the /// original callback is called in the zone it was registered in. @@ -611,7 +619,10 @@ class PlatformDispatcher { /// This can be combined with flutter tools `--isolate-filter` flag to debug /// specific root isolates. For example: `flutter attach --isolate-filter=[name]`. /// Note that this does not rename any child isolates of the root. - void setIsolateDebugName(String name) native 'PlatformConfiguration_setIsolateDebugName'; + void setIsolateDebugName(String name) => _setIsolateDebugName(name); + + @FfiNative('PlatformConfigurationNativeApi::SetIsolateDebugName') + external static void _setIsolateDebugName(String name); /// The embedder can specify data that the isolate can request synchronously /// on launch. This accessor fetches that data. @@ -622,7 +633,10 @@ class PlatformDispatcher { /// /// For asynchronous communication between the embedder and isolate, a /// platform channel may be used. - ByteData? getPersistentIsolateData() native 'PlatformConfiguration_getPersistentIsolateData'; + ByteData? getPersistentIsolateData() => _getPersistentIsolateData(); + + @FfiNative('PlatformConfigurationNativeApi::GetPersistentIsolateData') + external static ByteData? _getPersistentIsolateData(); /// Requests that, at the next appropriate opportunity, the [onBeginFrame] and /// [onDrawFrame] callbacks be invoked. @@ -631,7 +645,10 @@ class PlatformDispatcher { /// /// * [SchedulerBinding], the Flutter framework class which manages the /// scheduling of frames. - void scheduleFrame() native 'PlatformConfiguration_scheduleFrame'; + void scheduleFrame() => _scheduleFrame(); + + @FfiNative('PlatformConfigurationNativeApi::ScheduleFrame') + external static void _scheduleFrame(); /// Additional accessibility features that may be enabled by the platform. AccessibilityFeatures get accessibilityFeatures => configuration.accessibilityFeatures; @@ -671,7 +688,10 @@ class PlatformDispatcher { /// /// In either case, this function disposes the given update, which means the /// semantics update cannot be used further. - void updateSemantics(SemanticsUpdate update) native 'PlatformConfiguration_updateSemantics'; + void updateSemantics(SemanticsUpdate update) => _updateSemantics(update); + + @FfiNative)>('PlatformConfigurationNativeApi::UpdateSemantics') + external static void _updateSemantics(SemanticsUpdate update); /// The system-reported default locale of the device. /// @@ -729,7 +749,11 @@ class PlatformDispatcher { } return null; } - List _computePlatformResolvedLocale(List supportedLocalesData) native 'PlatformConfiguration_computePlatformResolvedLocale'; + + List _computePlatformResolvedLocale(List supportedLocalesData) => __computePlatformResolvedLocale(supportedLocalesData); + + @FfiNative('PlatformConfigurationNativeApi::ComputePlatformResolvedLocale') + external static List __computePlatformResolvedLocale(List supportedLocalesData); /// A callback that is invoked whenever [locale] changes value. /// @@ -912,8 +936,7 @@ class PlatformDispatcher { data['platformBrightness']! as String == 'dark' ? Brightness.dark : Brightness.light; final String? systemFontFamily = data['systemFontFamily'] as String?; final PlatformConfiguration previousConfiguration = configuration; - final bool platformBrightnessChanged = - previousConfiguration.platformBrightness != platformBrightness; + final bool platformBrightnessChanged = previousConfiguration.platformBrightness != platformBrightness; final bool textScaleFactorChanged = previousConfiguration.textScaleFactor != textScaleFactor; final bool alwaysUse24HourFormatChanged = previousConfiguration.alwaysUse24HourFormat != alwaysUse24HourFormat; @@ -1097,7 +1120,9 @@ class PlatformDispatcher { /// * [SystemChannels.navigation], which handles subsequent navigation /// requests from the embedder. String get defaultRouteName => _defaultRouteName(); - String _defaultRouteName() native 'PlatformConfiguration_defaultRouteName'; + + @FfiNative('PlatformConfigurationNativeApi::DefaultRouteName') + external static String _defaultRouteName(); } /// Configuration of the platform. @@ -1505,7 +1530,7 @@ class FrameTiming { /// The frame key associated with this frame measurement. int get frameNumber => _data.last; - final List _data; // some elements in microseconds, some in bytes, some are counts + final List _data; // some elements in microseconds, some in bytes, some are counts String _formatMS(Duration duration) => '${duration.inMicroseconds * 0.001}ms'; @@ -1670,8 +1695,10 @@ class DisplayFeature { return true; if (other.runtimeType != runtimeType) return false; - return other is DisplayFeature && bounds == other.bounds && - type == other.type && state == other.state; + return other is DisplayFeature + && bounds == other.bounds + && type == other.type + && state == other.state; } @override diff --git a/engine/src/flutter/lib/ui/plugins.dart b/engine/src/flutter/lib/ui/plugins.dart index e21e1bdcb8c..ff91f74db98 100644 --- a/engine/src/flutter/lib/ui/plugins.dart +++ b/engine/src/flutter/lib/ui/plugins.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// A wrapper for a raw callback handle. diff --git a/engine/src/flutter/lib/ui/pointer.dart b/engine/src/flutter/lib/ui/pointer.dart index 083c9f7ae79..5532914d900 100644 --- a/engine/src/flutter/lib/ui/pointer.dart +++ b/engine/src/flutter/lib/ui/pointer.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// How the pointer has changed since the last report. diff --git a/engine/src/flutter/lib/ui/semantics.dart b/engine/src/flutter/lib/ui/semantics.dart index 301b920c62c..2df1d521d71 100644 --- a/engine/src/flutter/lib/ui/semantics.dart +++ b/engine/src/flutter/lib/ui/semantics.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// The possible actions that can be conveyed from the operating system @@ -694,11 +694,8 @@ class SpellOutStringAttribute extends StringAttribute { _initSpellOutStringAttribute(this, range.start, range.end); } - void _initSpellOutStringAttribute( - SpellOutStringAttribute instance, - int start, - int end, - ) native 'NativeStringAttribute_initSpellOutStringAttribute'; + @FfiNative('NativeStringAttribute::initSpellOutStringAttribute') + external static void _initSpellOutStringAttribute(SpellOutStringAttribute instance, int start, int end); @override StringAttribute copy({required TextRange range}) { @@ -733,12 +730,8 @@ class LocaleStringAttribute extends StringAttribute { /// The lanuage of this attribute. final Locale locale; - void _initLocaleStringAttribute( - LocaleStringAttribute instance, - int start, - int end, - String locale, - ) native 'NativeStringAttribute_initLocaleStringAttribute'; + @FfiNative('NativeStringAttribute::initLocaleStringAttribute') + external static void _initLocaleStringAttribute(LocaleStringAttribute instance, int start, int end, String locale); @override StringAttribute copy({required TextRange range}) { @@ -761,7 +754,9 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass1 { /// Creates an empty [SemanticsUpdateBuilder] object. @pragma('vm:entry-point') SemanticsUpdateBuilder() { _constructor(); } - void _constructor() native 'SemanticsUpdateBuilder_constructor'; + + @FfiNative('SemanticsUpdateBuilder::Create') + external void _constructor(); /// Update the information associated with the node with the given `id`. /// @@ -921,43 +916,80 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass1 { additionalActions, ); } - void _updateNode( - int id, - int flags, - int actions, - int maxValueLength, - int currentValueLength, - int textSelectionBase, - int textSelectionExtent, - int platformViewId, - int scrollChildren, - int scrollIndex, - double scrollPosition, - double scrollExtentMax, - double scrollExtentMin, - double left, - double top, - double right, - double bottom, - double elevation, - double thickness, - String label, - List labelAttributes, - String value, - List valueAttributes, - String increasedValue, - List increasedValueAttributes, - String decreasedValue, - List decreasedValueAttributes, - String hint, - List hintAttributes, - String? tooltip, - int textDirection, - Float64List transform, - Int32List childrenInTraversalOrder, - Int32List childrenInHitTestOrder, - Int32List additionalActions, - ) native 'SemanticsUpdateBuilder_updateNode'; + @FfiNative< + Void Function( + Pointer, + Int32, + Int32, + Int32, + Int32, + Int32, + Int32, + Int32, + Int32, + Int32, + Int32, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Double, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Int32, + Handle, + Handle, + Handle, + Handle)>('SemanticsUpdateBuilder::updateNode') + external void _updateNode( + int id, + int flags, + int actions, + int maxValueLength, + int currentValueLength, + int textSelectionBase, + int textSelectionExtent, + int platformViewId, + int scrollChildren, + int scrollIndex, + double scrollPosition, + double scrollExtentMax, + double scrollExtentMin, + double left, + double top, + double right, + double bottom, + double elevation, + double thickness, + String label, + List labelAttributes, + String value, + List valueAttributes, + String increasedValue, + List increasedValueAttributes, + String decreasedValue, + List decreasedValueAttributes, + String hint, + List hintAttributes, + String? tooltip, + int textDirection, + Float64List transform, + Int32List childrenInTraversalOrder, + Int32List childrenInHitTestOrder, + Int32List additionalActions); /// Update the custom semantics action associated with the given `id`. /// @@ -979,11 +1011,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass1 { assert(overrideId != null); _updateCustomAction(id, label, hint, overrideId); } - void _updateCustomAction( - int id, - String? label, - String? hint, - int overrideId) native 'SemanticsUpdateBuilder_updateCustomAction'; + @FfiNative, Int32, Handle, Handle, Int32)>('SemanticsUpdateBuilder::updateCustomAction') + external void _updateCustomAction(int id, String? label, String? hint, int overrideId); /// Creates a [SemanticsUpdate] object that encapsulates the updates recorded /// by this object. @@ -995,7 +1024,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass1 { _build(semanticsUpdate); return semanticsUpdate; } - void _build(SemanticsUpdate outSemanticsUpdate) native 'SemanticsUpdateBuilder_build'; + @FfiNative, Handle)>('SemanticsUpdateBuilder::build') + external void _build(SemanticsUpdate outSemanticsUpdate); } /// An opaque object representing a batch of semantics updates. @@ -1017,5 +1047,9 @@ class SemanticsUpdate extends NativeFieldWrapperClass1 { /// /// After calling this function, the semantics update is cannot be used /// further. - void dispose() native 'SemanticsUpdate_dispose'; + /// + /// This can't be a leaf call because the native function calls Dart API + /// (Dart_SetNativeInstanceField). + @FfiNative)>('SemanticsUpdate::dispose') + external void dispose(); } diff --git a/engine/src/flutter/lib/ui/semantics/semantics_update.cc b/engine/src/flutter/lib/ui/semantics/semantics_update.cc index f72e8ad80b3..9faf38c672f 100644 --- a/engine/src/flutter/lib/ui/semantics/semantics_update.cc +++ b/engine/src/flutter/lib/ui/semantics/semantics_update.cc @@ -18,10 +18,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, SemanticsUpdate); -#define FOR_EACH_BINDING(V) V(SemanticsUpdate, dispose) - -DART_BIND_ALL(SemanticsUpdate, FOR_EACH_BINDING) - void SemanticsUpdate::create(Dart_Handle semantics_update_handle, SemanticsNodeUpdates nodes, CustomAccessibilityActionUpdates actions) { diff --git a/engine/src/flutter/lib/ui/semantics/semantics_update.h b/engine/src/flutter/lib/ui/semantics/semantics_update.h index c3411bb43bf..5ecbee00a1d 100644 --- a/engine/src/flutter/lib/ui/semantics/semantics_update.h +++ b/engine/src/flutter/lib/ui/semantics/semantics_update.h @@ -9,10 +9,6 @@ #include "flutter/lib/ui/semantics/custom_accessibility_action.h" #include "flutter/lib/ui/semantics/semantics_node.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class SemanticsUpdate : public RefCountedDartWrappable { @@ -31,8 +27,6 @@ class SemanticsUpdate : public RefCountedDartWrappable { void dispose(); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: explicit SemanticsUpdate(SemanticsNodeUpdates nodes, CustomAccessibilityActionUpdates updates); diff --git a/engine/src/flutter/lib/ui/semantics/semantics_update_builder.cc b/engine/src/flutter/lib/ui/semantics/semantics_update_builder.cc index e1b1a6adad5..90e35df3335 100644 --- a/engine/src/flutter/lib/ui/semantics/semantics_update_builder.cc +++ b/engine/src/flutter/lib/ui/semantics/semantics_update_builder.cc @@ -21,27 +21,8 @@ void pushStringAttributes( } } -static void SemanticsUpdateBuilder_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&SemanticsUpdateBuilder::create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, SemanticsUpdateBuilder); -#define FOR_EACH_BINDING(V) \ - V(SemanticsUpdateBuilder, updateNode) \ - V(SemanticsUpdateBuilder, updateCustomAction) \ - V(SemanticsUpdateBuilder, build) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void SemanticsUpdateBuilder::RegisterNatives( - tonic::DartLibraryNatives* natives) { - natives->Register({{"SemanticsUpdateBuilder_constructor", - SemanticsUpdateBuilder_constructor, 1, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - SemanticsUpdateBuilder::SemanticsUpdateBuilder() = default; SemanticsUpdateBuilder::~SemanticsUpdateBuilder() = default; diff --git a/engine/src/flutter/lib/ui/semantics/semantics_update_builder.h b/engine/src/flutter/lib/ui/semantics/semantics_update_builder.h index 6f83e471d2c..b69a7351405 100644 --- a/engine/src/flutter/lib/ui/semantics/semantics_update_builder.h +++ b/engine/src/flutter/lib/ui/semantics/semantics_update_builder.h @@ -10,6 +10,7 @@ #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/semantics/semantics_update.h" +#include "flutter/lib/ui/ui_dart_state.h" #include "third_party/tonic/typed_data/typed_list.h" namespace flutter { @@ -20,8 +21,10 @@ class SemanticsUpdateBuilder FML_FRIEND_MAKE_REF_COUNTED(SemanticsUpdateBuilder); public: - static fml::RefPtr create() { - return fml::MakeRefCounted(); + static void Create(Dart_Handle wrapper) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted(); + res->AssociateWithDartWrapper(wrapper); } ~SemanticsUpdateBuilder() override; @@ -69,8 +72,6 @@ class SemanticsUpdateBuilder void build(Dart_Handle semantics_update_handle); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: explicit SemanticsUpdateBuilder(); SemanticsNodeUpdates nodes_; diff --git a/engine/src/flutter/lib/ui/semantics/string_attribute.cc b/engine/src/flutter/lib/ui/semantics/string_attribute.cc index f1eac9c998b..3434f6888aa 100644 --- a/engine/src/flutter/lib/ui/semantics/string_attribute.cc +++ b/engine/src/flutter/lib/ui/semantics/string_attribute.cc @@ -15,17 +15,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, NativeStringAttribute); -#define FOR_EACH_BINDING(V) \ - V(NativeStringAttribute, initLocaleStringAttribute) \ - V(NativeStringAttribute, initSpellOutStringAttribute) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void NativeStringAttribute::RegisterNatives( - tonic::DartLibraryNatives* natives) { - natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - NativeStringAttribute::NativeStringAttribute() {} NativeStringAttribute::~NativeStringAttribute() {} diff --git a/engine/src/flutter/lib/ui/semantics/string_attribute.h b/engine/src/flutter/lib/ui/semantics/string_attribute.h index e0d51509318..b9ee3bc958a 100644 --- a/engine/src/flutter/lib/ui/semantics/string_attribute.h +++ b/engine/src/flutter/lib/ui/semantics/string_attribute.h @@ -77,8 +77,6 @@ class NativeStringAttribute /// Returns the c++ representataion of StringAttribute. const StringAttributePtr GetAttribute() const; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: NativeStringAttribute(); StringAttributePtr attribute_; diff --git a/engine/src/flutter/lib/ui/text.dart b/engine/src/flutter/lib/ui/text.dart index 86ca83f7894..4d0eb61f67f 100644 --- a/engine/src/flutter/lib/ui/text.dart +++ b/engine/src/flutter/lib/ui/text.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// Whether to slant the glyphs in the font @@ -1670,7 +1670,7 @@ class ParagraphStyle { /// paragraph. If the last line is ellipsized (see `ellipsis` below), the /// alignment is applied to that line after it has been truncated but before /// the ellipsis has been added. - // See: https://github.com/flutter/flutter/issues/9819 + /// See: https://github.com/flutter/flutter/issues/9819 /// /// * `textDirection`: The directionality of the text, left-to-right (e.g. /// Norwegian) or right-to-left (e.g. Hebrew). This controls the overall @@ -1849,7 +1849,7 @@ ByteData _encodeStrut( data.setInt8(byteCount, fontStyle.index); byteCount += 1; } - if (fontFamily != null || (fontFamilyFallback != null && fontFamilyFallback.isNotEmpty)){ + if (fontFamily != null || (fontFamilyFallback != null && fontFamilyFallback.isNotEmpty)) { bitmask |= 1 << 2; // passed separately to native } @@ -1865,7 +1865,6 @@ ByteData _encodeStrut( bitmask |= 1 << 5; data.setFloat32(byteCount, height, _kFakeHostEndian); byteCount += 4; - } if (leading != null) { bitmask |= 1 << 6; @@ -1880,7 +1879,7 @@ ByteData _encodeStrut( assert(byteCount <= 16); assert(bitmask >> 8 == 0, 'strut bitmask overflow: $bitmask'); - return ByteData.view(data.buffer, 0, byteCount); + return ByteData.view(data.buffer, 0, byteCount); } /// See also: @@ -1980,7 +1979,6 @@ class StrutStyle { @override int get hashCode => hashValues(hashList(_encoded.buffer.asInt8List()), _fontFamily, _leadingDistribution); - } /// A direction in which text flows. @@ -2276,7 +2274,7 @@ class TextRange { required this.start, required this.end, }) : assert(start != null && start >= -1), - assert(end != null && end >= -1); + assert(end != null && end >= -1); /// A text range that starts and ends at offset. /// @@ -2656,38 +2654,45 @@ class Paragraph extends NativeFieldWrapperClass1 { /// The amount of horizontal space this paragraph occupies. /// /// Valid only after [layout] has been called. - double get width native 'Paragraph_width'; + @FfiNative)>('Paragraph::width', isLeaf: true) + external double get width; /// The amount of vertical space this paragraph occupies. /// /// Valid only after [layout] has been called. - double get height native 'Paragraph_height'; + @FfiNative)>('Paragraph::height', isLeaf: true) + external double get height; /// The distance from the left edge of the leftmost glyph to the right edge of /// the rightmost glyph in the paragraph. /// /// Valid only after [layout] has been called. - double get longestLine native 'Paragraph_longestLine'; + @FfiNative)>('Paragraph::longestLine', isLeaf: true) + external double get longestLine; /// The minimum width that this paragraph could be without failing to paint /// its contents within itself. /// /// Valid only after [layout] has been called. - double get minIntrinsicWidth native 'Paragraph_minIntrinsicWidth'; + @FfiNative)>('Paragraph::minIntrinsicWidth', isLeaf: true) + external double get minIntrinsicWidth; /// Returns the smallest width beyond which increasing the width never /// decreases the height. /// /// Valid only after [layout] has been called. - double get maxIntrinsicWidth native 'Paragraph_maxIntrinsicWidth'; + @FfiNative)>('Paragraph::maxIntrinsicWidth', isLeaf: true) + external double get maxIntrinsicWidth; /// The distance from the top of the paragraph to the alphabetic /// baseline of the first line, in logical pixels. - double get alphabeticBaseline native 'Paragraph_alphabeticBaseline'; + @FfiNative)>('Paragraph::alphabeticBaseline', isLeaf: true) + external double get alphabeticBaseline; /// The distance from the top of the paragraph to the ideographic /// baseline of the first line, in logical pixels. - double get ideographicBaseline native 'Paragraph_ideographicBaseline'; + @FfiNative)>('Paragraph::ideographicBaseline', isLeaf: true) + external double get ideographicBaseline; /// True if there is more vertical content, but the text was truncated, either /// because we reached `maxLines` lines of text or because the `maxLines` was @@ -2696,13 +2701,15 @@ class Paragraph extends NativeFieldWrapperClass1 { /// /// See the discussion of the `maxLines` and `ellipsis` arguments at /// [new ParagraphStyle]. - bool get didExceedMaxLines native 'Paragraph_didExceedMaxLines'; + @FfiNative)>('Paragraph::didExceedMaxLines', isLeaf: true) + external bool get didExceedMaxLines; /// Computes the size and position of each glyph in the paragraph. /// /// The [ParagraphConstraints] control how wide the text is allowed to be. void layout(ParagraphConstraints constraints) => _layout(constraints.width); - void _layout(double width) native 'Paragraph_layout'; + @FfiNative, Double)>('Paragraph::layout', isLeaf: true) + external void _layout(double width); List _decodeTextBoxes(Float32List encoded) { final int count = encoded.length ~/ 5; @@ -2738,8 +2745,10 @@ class Paragraph extends NativeFieldWrapperClass1 { assert(boxWidthStyle != null); return _decodeTextBoxes(_getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index)); } + // See paragraph.cc for the layout of this return value. - Float32List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle) native 'Paragraph_getRectsForRange'; + @FfiNative, Uint32, Uint32, Uint32, Uint32)>('Paragraph::getRectsForRange') + external Float32List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle); /// Returns a list of text boxes that enclose all placeholders in the paragraph. /// @@ -2751,14 +2760,18 @@ class Paragraph extends NativeFieldWrapperClass1 { List getBoxesForPlaceholders() { return _decodeTextBoxes(_getBoxesForPlaceholders()); } - Float32List _getBoxesForPlaceholders() native 'Paragraph_getRectsForPlaceholders'; + + @FfiNative)>('Paragraph::getRectsForPlaceholders') + external Float32List _getBoxesForPlaceholders(); /// Returns the text position closest to the given offset. TextPosition getPositionForOffset(Offset offset) { final List encoded = _getPositionForOffset(offset.dx, offset.dy); return TextPosition(offset: encoded[0], affinity: TextAffinity.values[encoded[1]]); } - List _getPositionForOffset(double dx, double dy) native 'Paragraph_getPositionForOffset'; + + @FfiNative, Double, Double)>('Paragraph::getPositionForOffset') + external List _getPositionForOffset(double dx, double dy); /// Returns the [TextRange] of the word at the given [TextPosition]. /// @@ -2770,7 +2783,9 @@ class Paragraph extends NativeFieldWrapperClass1 { final List boundary = _getWordBoundary(position.offset); return TextRange(start: boundary[0], end: boundary[1]); } - List _getWordBoundary(int offset) native 'Paragraph_getWordBoundary'; + + @FfiNative, Uint32)>('Paragraph::getWordBoundary') + external List _getWordBoundary(int offset); /// Returns the [TextRange] of the line at the given [TextPosition]. /// @@ -2802,12 +2817,15 @@ class Paragraph extends NativeFieldWrapperClass1 { } return line; } - List _getLineBoundary(int offset) native 'Paragraph_getLineBoundary'; + + @FfiNative, Uint32)>('Paragraph::getLineBoundary') + external List _getLineBoundary(int offset); // Redirecting the paint function in this way solves some dependency problems // in the C++ code. If we straighten out the C++ dependencies, we can remove // this indirection. - void _paint(Canvas canvas, double x, double y) native 'Paragraph_paint'; + @FfiNative, Pointer, Double, Double)>('Paragraph::paint') + external void _paint(Canvas canvas, double x, double y); /// Returns the full list of [LineMetrics] that describe in detail the various /// metrics of each laid out line. @@ -2836,7 +2854,9 @@ class Paragraph extends NativeFieldWrapperClass1 { ]; return metrics; } - Float64List _computeLineMetrics() native 'Paragraph_computeLineMetrics'; + + @FfiNative)>('Paragraph::computeLineMetrics') + external Float64List _computeLineMetrics(); } /// Builds a [Paragraph] containing text with the given styling information. @@ -2881,27 +2901,26 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { encodedStrutStyle = null; } _constructor( - style._encoded, - encodedStrutStyle, - style._fontFamily, - strutFontFamilies, - style._fontSize, - style._height, - style._ellipsis, - _encodeLocale(style._locale) - ); + style._encoded, + encodedStrutStyle, + style._fontFamily, + strutFontFamilies, + style._fontSize ?? 0, + style._height ?? 0, + style._ellipsis, + _encodeLocale(style._locale)); } - void _constructor( - Int32List encoded, - ByteData? strutData, - String? fontFamily, - List? strutFontFamily, - double? fontSize, - double? height, - String? ellipsis, - String locale - ) native 'ParagraphBuilder_constructor'; + @FfiNative('ParagraphBuilder::Create') + external void _constructor( + Int32List encoded, + ByteData? strutData, + String? fontFamily, + List? strutFontFamily, + double fontSize, + double height, + String? ellipsis, + String locale); /// The number of placeholders currently in the paragraph. int get placeholderCount => _placeholderCount; @@ -2955,11 +2974,11 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { _pushStyle( encoded, fullFontFamilies, - style._fontSize, - style._letterSpacing, - style._wordSpacing, - style._height, - style._decorationThickness, + style._fontSize ?? 0, + style._letterSpacing ?? 0, + style._wordSpacing ?? 0, + style._height ?? 0, + style._decorationThickness ?? 0, _encodeLocale(style._locale), style._background?._objects, style._background?._data, @@ -2971,14 +2990,32 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { ); } - void _pushStyle( + @FfiNative< + Void Function( + Pointer, + Handle, + Handle, + Double, + Double, + Double, + Double, + Double, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle, + Handle)>('ParagraphBuilder::pushStyle') + external void _pushStyle( Int32List encoded, List fontFamilies, - double? fontSize, - double? letterSpacing, - double? wordSpacing, - double? height, - double? decorationThickness, + double fontSize, + double letterSpacing, + double wordSpacing, + double height, + double decorationThickness, String locale, List? backgroundObjects, ByteData? backgroundData, @@ -2987,7 +3024,7 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { ByteData shadowsData, ByteData? fontFeaturesData, ByteData? fontVariationsData, - ) native 'ParagraphBuilder_pushStyle'; + ); static String _encodeLocale(Locale? locale) => locale?.toString() ?? ''; @@ -2997,7 +3034,8 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { /// added to the paragraph is affected by all the styles in the stack. Calling /// [pop] removes the topmost style in the stack, leaving the remaining styles /// in effect. - void pop() native 'ParagraphBuilder_pop'; + @FfiNative)>('ParagraphBuilder::pop', isLeaf: true) + external void pop(); /// Adds the given text to the paragraph. /// @@ -3007,7 +3045,9 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { if (error != null) throw ArgumentError(error); } - String? _addText(String text) native 'ParagraphBuilder_addText'; + + @FfiNative, Handle)>('ParagraphBuilder::addText') + external String? _addText(String text); /// Adds an inline placeholder space to the paragraph. /// @@ -3068,11 +3108,13 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { // Default the baselineOffset to height if null. This will place the placeholder // fully above the baseline, similar to [PlaceholderAlignment.aboveBaseline]. baselineOffset = baselineOffset ?? height; - _addPlaceholder(width * scale, height * scale, alignment.index, baselineOffset * scale, baseline?.index); + _addPlaceholder(width * scale, height * scale, alignment.index, baselineOffset * scale, baseline?.index ?? 0); _placeholderCount++; _placeholderScales.add(scale); } - String? _addPlaceholder(double width, double height, int alignment, double baselineOffset, int? baseline) native 'ParagraphBuilder_addPlaceholder'; + + @FfiNative, Double, Double, Uint32, Double, Uint32)>('ParagraphBuilder::addPlaceholder') + external String? _addPlaceholder(double width, double height, int alignment, double baselineOffset, int baseline); /// Applies the given paragraph style and returns a [Paragraph] containing the /// added text and associated styling. @@ -3084,7 +3126,9 @@ class ParagraphBuilder extends NativeFieldWrapperClass1 { _build(paragraph); return paragraph; } - void _build(Paragraph outParagraph) native 'ParagraphBuilder_build'; + + @FfiNative, Handle)>('ParagraphBuilder::build') + external void _build(Paragraph outParagraph); } /// Loads a font from a buffer and makes it available for rendering text. @@ -3119,4 +3163,5 @@ FutureOr _sendFontChangeMessage() async { } } -void _loadFontFromList(Uint8List list, _Callback callback, String? fontFamily) native 'loadFontFromList'; +@FfiNative('FontCollection::LoadFontFromList') +external void _loadFontFromList(Uint8List list, _Callback callback, String? fontFamily); diff --git a/engine/src/flutter/lib/ui/text/font_collection.cc b/engine/src/flutter/lib/ui/text/font_collection.cc index ed9c3cc1058..3ca89d964df 100644 --- a/engine/src/flutter/lib/ui/text/font_collection.cc +++ b/engine/src/flutter/lib/ui/text/font_collection.cc @@ -25,28 +25,6 @@ namespace flutter { -namespace { - -void LoadFontFromList(tonic::Uint8List& font_data, // NOLINT - Dart_Handle callback, - std::string family_name) { - FontCollection& font_collection = UIDartState::Current() - ->platform_configuration() - ->client() - ->GetFontCollection(); - font_collection.LoadFontFromList(font_data.data(), font_data.num_elements(), - family_name); - font_data.Release(); - tonic::DartInvoke(callback, {tonic::ToDart(0)}); -} - -void _LoadFontFromList(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - tonic::DartCallStatic(LoadFontFromList, args); -} - -} // namespace - FontCollection::FontCollection() : collection_(std::make_shared()) { dynamic_font_manager_ = sk_make_sp(); @@ -58,12 +36,6 @@ FontCollection::~FontCollection() { SkGraphics::PurgeFontCache(); } -void FontCollection::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({ - {"loadFontFromList", _LoadFontFromList, 3, true}, - }); -} - std::shared_ptr FontCollection::GetFontCollection() const { return collection_; } @@ -157,21 +129,31 @@ void FontCollection::RegisterTestFonts() { collection_->DisableFontFallback(); } -void FontCollection::LoadFontFromList(const uint8_t* font_data, - int length, +void FontCollection::LoadFontFromList(Dart_Handle font_data_handle, + Dart_Handle callback, std::string family_name) { - std::unique_ptr font_stream = - std::make_unique(font_data, length, true); + tonic::Uint8List font_data(font_data_handle); + UIDartState::ThrowIfUIOperationsProhibited(); + FontCollection& font_collection = UIDartState::Current() + ->platform_configuration() + ->client() + ->GetFontCollection(); + + std::unique_ptr font_stream = std::make_unique( + font_data.data(), font_data.num_elements(), true); sk_sp typeface = SkTypeface::MakeFromStream(std::move(font_stream)); txt::TypefaceFontAssetProvider& font_provider = - dynamic_font_manager_->font_provider(); + font_collection.dynamic_font_manager_->font_provider(); if (family_name.empty()) { font_provider.RegisterTypeface(typeface); } else { font_provider.RegisterTypeface(typeface, family_name); } - collection_->ClearFontFamilyCache(); + font_collection.collection_->ClearFontFamilyCache(); + + font_data.Release(); + tonic::DartInvoke(callback, {tonic::ToDart(0)}); } } // namespace flutter diff --git a/engine/src/flutter/lib/ui/text/font_collection.h b/engine/src/flutter/lib/ui/text/font_collection.h index d30c809f553..c13f6c65f90 100644 --- a/engine/src/flutter/lib/ui/text/font_collection.h +++ b/engine/src/flutter/lib/ui/text/font_collection.h @@ -11,12 +11,9 @@ #include "flutter/assets/asset_manager.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_ptr.h" +#include "third_party/tonic/typed_data/typed_list.h" #include "txt/font_collection.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class FontCollection { @@ -25,8 +22,6 @@ class FontCollection { ~FontCollection(); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - std::shared_ptr GetFontCollection() const; void SetupDefaultFontManager(uint32_t font_initialization_data); @@ -35,9 +30,9 @@ class FontCollection { void RegisterTestFonts(); - void LoadFontFromList(const uint8_t* font_data, - int length, - std::string family_name); + static void LoadFontFromList(Dart_Handle font_data_handle, + Dart_Handle callback, + std::string family_name); private: std::shared_ptr collection_; diff --git a/engine/src/flutter/lib/ui/text/paragraph.cc b/engine/src/flutter/lib/ui/text/paragraph.cc index e8186be6c40..f38f4196cc9 100644 --- a/engine/src/flutter/lib/ui/text/paragraph.cc +++ b/engine/src/flutter/lib/ui/text/paragraph.cc @@ -13,32 +13,10 @@ #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" -using tonic::ToDart; - namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph); -#define FOR_EACH_BINDING(V) \ - V(Paragraph, width) \ - V(Paragraph, height) \ - V(Paragraph, longestLine) \ - V(Paragraph, minIntrinsicWidth) \ - V(Paragraph, maxIntrinsicWidth) \ - V(Paragraph, alphabeticBaseline) \ - V(Paragraph, ideographicBaseline) \ - V(Paragraph, didExceedMaxLines) \ - V(Paragraph, layout) \ - V(Paragraph, paint) \ - V(Paragraph, getWordBoundary) \ - V(Paragraph, getLineBoundary) \ - V(Paragraph, getRectsForRange) \ - V(Paragraph, getRectsForPlaceholders) \ - V(Paragraph, getPositionForOffset) \ - V(Paragraph, computeLineMetrics) - -DART_BIND_ALL(Paragraph, FOR_EACH_BINDING) - Paragraph::Paragraph(std::unique_ptr paragraph) : m_paragraph(std::move(paragraph)) {} diff --git a/engine/src/flutter/lib/ui/text/paragraph.h b/engine/src/flutter/lib/ui/text/paragraph.h index a422d847b40..66aaa75ddae 100644 --- a/engine/src/flutter/lib/ui/text/paragraph.h +++ b/engine/src/flutter/lib/ui/text/paragraph.h @@ -12,10 +12,6 @@ #include "flutter/lib/ui/text/text_box.h" #include "flutter/third_party/txt/src/txt/paragraph.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Paragraph : public RefCountedDartWrappable { @@ -55,8 +51,6 @@ class Paragraph : public RefCountedDartWrappable { size_t GetAllocationSize() const override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: std::unique_ptr m_paragraph; diff --git a/engine/src/flutter/lib/ui/text/paragraph_builder.cc b/engine/src/flutter/lib/ui/text/paragraph_builder.cc index d4cd88bb576..c92cceadb8e 100644 --- a/engine/src/flutter/lib/ui/text/paragraph_builder.cc +++ b/engine/src/flutter/lib/ui/text/paragraph_builder.cc @@ -141,40 +141,22 @@ const int sForceStrutHeightMask = 1 << sForceStrutHeightIndex; } // namespace -static void ParagraphBuilder_constructor(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - DartCallConstructor(&ParagraphBuilder::create, args); -} - IMPLEMENT_WRAPPERTYPEINFO(ui, ParagraphBuilder); -#define FOR_EACH_BINDING(V) \ - V(ParagraphBuilder, pushStyle) \ - V(ParagraphBuilder, pop) \ - V(ParagraphBuilder, addText) \ - V(ParagraphBuilder, addPlaceholder) \ - V(ParagraphBuilder, build) - -FOR_EACH_BINDING(DART_NATIVE_CALLBACK) - -void ParagraphBuilder::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register( - {{"ParagraphBuilder_constructor", ParagraphBuilder_constructor, 9, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); -} - -fml::RefPtr ParagraphBuilder::create( - tonic::Int32List& encoded, - Dart_Handle strutData, - const std::string& fontFamily, - const std::vector& strutFontFamilies, - double fontSize, - double height, - const std::u16string& ellipsis, - const std::string& locale) { - return fml::MakeRefCounted(encoded, strutData, fontFamily, - strutFontFamilies, fontSize, - height, ellipsis, locale); +void ParagraphBuilder::Create(Dart_Handle wrapper, + Dart_Handle encoded_handle, + Dart_Handle strutData, + const std::string& fontFamily, + const std::vector& strutFontFamilies, + double fontSize, + double height, + const std::u16string& ellipsis, + const std::string& locale) { + UIDartState::ThrowIfUIOperationsProhibited(); + auto res = fml::MakeRefCounted( + encoded_handle, strutData, fontFamily, strutFontFamilies, fontSize, + height, ellipsis, locale); + res->AssociateWithDartWrapper(wrapper); } // returns true if there is a font family defined. Font family is the only @@ -241,7 +223,7 @@ void decodeStrut(Dart_Handle strut_data, } ParagraphBuilder::ParagraphBuilder( - tonic::Int32List& encoded, + Dart_Handle encoded_data, Dart_Handle strutData, const std::string& fontFamily, const std::vector& strutFontFamilies, @@ -249,51 +231,56 @@ ParagraphBuilder::ParagraphBuilder( double height, const std::u16string& ellipsis, const std::string& locale) { - int32_t mask = encoded[0]; + int32_t mask = 0; txt::ParagraphStyle style; + { + tonic::Int32List encoded(encoded_data); - if (mask & psTextAlignMask) { - style.text_align = txt::TextAlign(encoded[psTextAlignIndex]); - } + mask = encoded[0]; - if (mask & psTextDirectionMask) { - style.text_direction = txt::TextDirection(encoded[psTextDirectionIndex]); - } + if (mask & psTextAlignMask) { + style.text_align = txt::TextAlign(encoded[psTextAlignIndex]); + } - if (mask & psFontWeightMask) { - style.font_weight = - static_cast(encoded[psFontWeightIndex]); - } + if (mask & psTextDirectionMask) { + style.text_direction = txt::TextDirection(encoded[psTextDirectionIndex]); + } - if (mask & psFontStyleMask) { - style.font_style = static_cast(encoded[psFontStyleIndex]); - } + if (mask & psFontWeightMask) { + style.font_weight = + static_cast(encoded[psFontWeightIndex]); + } - if (mask & psFontFamilyMask) { - style.font_family = fontFamily; - } + if (mask & psFontStyleMask) { + style.font_style = static_cast(encoded[psFontStyleIndex]); + } - if (mask & psFontSizeMask) { - style.font_size = fontSize; - } + if (mask & psFontFamilyMask) { + style.font_family = fontFamily; + } - if (mask & psHeightMask) { - style.height = height; - style.has_height_override = true; - } + if (mask & psFontSizeMask) { + style.font_size = fontSize; + } - if (mask & psTextHeightBehaviorMask) { - style.text_height_behavior = encoded[psTextHeightBehaviorIndex]; + if (mask & psHeightMask) { + style.height = height; + style.has_height_override = true; + } + + if (mask & psTextHeightBehaviorMask) { + style.text_height_behavior = encoded[psTextHeightBehaviorIndex]; + } + + if (mask & psMaxLinesMask) { + style.max_lines = encoded[psMaxLinesIndex]; + } } if (mask & psStrutStyleMask) { decodeStrut(strutData, strutFontFamilies, style); } - if (mask & psMaxLinesMask) { - style.max_lines = encoded[psMaxLinesIndex]; - } - if (mask & psEllipsisMask) { style.ellipsis = ellipsis; } @@ -389,7 +376,7 @@ void decodeFontVariations(Dart_Handle font_variations_data, } } -void ParagraphBuilder::pushStyle(tonic::Int32List& encoded, +void ParagraphBuilder::pushStyle(const tonic::Int32List& encoded, const std::vector& fontFamilies, double fontSize, double letterSpacing, diff --git a/engine/src/flutter/lib/ui/text/paragraph_builder.h b/engine/src/flutter/lib/ui/text/paragraph_builder.h index c372a3c354a..19fd5f435d7 100644 --- a/engine/src/flutter/lib/ui/text/paragraph_builder.h +++ b/engine/src/flutter/lib/ui/text/paragraph_builder.h @@ -13,10 +13,6 @@ #include "flutter/third_party/txt/src/txt/paragraph_builder.h" #include "third_party/tonic/typed_data/typed_list.h" -namespace tonic { -class DartLibraryNatives; -} // namespace tonic - namespace flutter { class Paragraph; @@ -26,19 +22,19 @@ class ParagraphBuilder : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(ParagraphBuilder); public: - static fml::RefPtr create( - tonic::Int32List& encoded, - Dart_Handle strutData, - const std::string& fontFamily, - const std::vector& strutFontFamilies, - double fontSize, - double height, - const std::u16string& ellipsis, - const std::string& locale); + static void Create(Dart_Handle wrapper, + Dart_Handle encoded_handle, + Dart_Handle strutData, + const std::string& fontFamily, + const std::vector& strutFontFamilies, + double fontSize, + double height, + const std::u16string& ellipsis, + const std::string& locale); ~ParagraphBuilder() override; - void pushStyle(tonic::Int32List& encoded, + void pushStyle(const tonic::Int32List& encoded, const std::vector& fontFamilies, double fontSize, double letterSpacing, @@ -72,10 +68,8 @@ class ParagraphBuilder : public RefCountedDartWrappable { void build(Dart_Handle paragraph_handle); - static void RegisterNatives(tonic::DartLibraryNatives* natives); - private: - explicit ParagraphBuilder(tonic::Int32List& encoded, + explicit ParagraphBuilder(Dart_Handle encoded, Dart_Handle strutData, const std::string& fontFamily, const std::vector& strutFontFamilies, diff --git a/engine/src/flutter/lib/ui/ui.dart b/engine/src/flutter/lib/ui/ui.dart index 743c2310650..c008aa12e27 100644 --- a/engine/src/flutter/lib/ui/ui.dart +++ b/engine/src/flutter/lib/ui/ui.dart @@ -9,7 +9,7 @@ /// This library exposes the lowest-level services that Flutter frameworks use /// to bootstrap applications, such as classes for driving the input, graphics /// text, layout, and rendering subsystems. -// @dart = 2.12 +// @dart = 2.14 library dart.ui; import 'dart:_spirv' as spv; @@ -17,6 +17,7 @@ import 'dart:async'; import 'dart:collection' as collection; import 'dart:convert'; import 'dart:developer' as developer; +import 'dart:ffi'; import 'dart:io'; // ignore: unused_import import 'dart:isolate' show SendPort; import 'dart:math' as math; diff --git a/engine/src/flutter/lib/ui/window.dart b/engine/src/flutter/lib/ui/window.dart index 0d9249144e0..e773e6504f7 100644 --- a/engine/src/flutter/lib/ui/window.dart +++ b/engine/src/flutter/lib/ui/window.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.12 +// @dart = 2.14 part of dart.ui; /// A view into which a Flutter [Scene] is drawn. @@ -264,8 +264,10 @@ abstract class FlutterView { /// scheduling of frames. /// * [RendererBinding], the Flutter framework class which manages layout and /// painting. - void render(Scene scene) => _render(scene, this); - void _render(Scene scene, FlutterView view) native 'PlatformConfiguration_render'; + void render(Scene scene) => _render(scene); + + @FfiNative)>('PlatformConfigurationNativeApi::Render') + external static void _render(Scene scene); } /// A top-level platform window displaying a Flutter layer tree drawn from a diff --git a/engine/src/flutter/lib/ui/window/platform_configuration.cc b/engine/src/flutter/lib/ui/window/platform_configuration.cc index 3914578bc28..001b99df7ef 100644 --- a/engine/src/flutter/lib/ui/window/platform_configuration.cc +++ b/engine/src/flutter/lib/ui/window/platform_configuration.cc @@ -21,143 +21,6 @@ namespace flutter { namespace { -void DefaultRouteName(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - std::string routeName = UIDartState::Current() - ->platform_configuration() - ->client() - ->DefaultRouteName(); - Dart_SetReturnValue(args, tonic::StdStringToDart(routeName)); -} - -void ScheduleFrame(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - UIDartState::Current()->platform_configuration()->client()->ScheduleFrame(); -} - -void Render(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle exception = nullptr; - Scene* scene = - tonic::DartConverter::FromArguments(args, 1, exception); - if (exception) { - Dart_ThrowException(exception); - return; - } - UIDartState::Current()->platform_configuration()->client()->Render(scene); -} - -void UpdateSemantics(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle exception = nullptr; - SemanticsUpdate* update = - tonic::DartConverter::FromArguments(args, 1, exception); - if (exception) { - Dart_ThrowException(exception); - return; - } - UIDartState::Current()->platform_configuration()->client()->UpdateSemantics( - update); -} - -void SetIsolateDebugName(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle exception = nullptr; - const std::string name = - tonic::DartConverter::FromArguments(args, 1, exception); - if (exception) { - Dart_ThrowException(exception); - return; - } - UIDartState::Current()->SetDebugName(name); -} - -void SetNeedsReportTimings(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle exception = nullptr; - bool value = tonic::DartConverter::FromArguments(args, 1, exception); - UIDartState::Current() - ->platform_configuration() - ->client() - ->SetNeedsReportTimings(value); -} - -Dart_Handle SendPlatformMessage(Dart_Handle window, - const std::string& name, - Dart_Handle callback, - Dart_Handle data_handle) { - UIDartState* dart_state = UIDartState::Current(); - - if (!dart_state->platform_configuration()) { - return tonic::ToDart( - "Platform messages can only be sent from the main isolate"); - } - - fml::RefPtr response; - if (!Dart_IsNull(callback)) { - response = fml::MakeRefCounted( - tonic::DartPersistentValue(dart_state, callback), - dart_state->GetTaskRunners().GetUITaskRunner()); - } - if (Dart_IsNull(data_handle)) { - dart_state->platform_configuration()->client()->HandlePlatformMessage( - std::make_unique(name, response)); - } else { - tonic::DartByteData data(data_handle); - const uint8_t* buffer = static_cast(data.data()); - dart_state->platform_configuration()->client()->HandlePlatformMessage( - std::make_unique( - name, fml::MallocMapping::Copy(buffer, data.length_in_bytes()), - response)); - } - - return Dart_Null(); -} - -void _SendPlatformMessage(Dart_NativeArguments args) { - tonic::DartCallStatic(&SendPlatformMessage, args); -} - -void RespondToPlatformMessage(Dart_Handle window, - int response_id, - const tonic::DartByteData& data) { - if (Dart_IsNull(data.dart_handle())) { - UIDartState::Current() - ->platform_configuration() - ->CompletePlatformMessageEmptyResponse(response_id); - } else { - // TODO(engine): Avoid this copy. - const uint8_t* buffer = static_cast(data.data()); - UIDartState::Current() - ->platform_configuration() - ->CompletePlatformMessageResponse( - response_id, - std::vector(buffer, buffer + data.length_in_bytes())); - } -} - -void _RespondToPlatformMessage(Dart_NativeArguments args) { - tonic::DartCallStatic(&RespondToPlatformMessage, args); -} - -void GetPersistentIsolateData(Dart_NativeArguments args) { - UIDartState::ThrowIfUIOperationsProhibited(); - - auto persistent_isolate_data = UIDartState::Current() - ->platform_configuration() - ->client() - ->GetPersistentIsolateData(); - - if (!persistent_isolate_data) { - Dart_SetReturnValue(args, Dart_Null()); - return; - } - - Dart_SetReturnValue( - args, tonic::DartByteData::Create(persistent_isolate_data->GetMapping(), - persistent_isolate_data->GetSize())); -} - Dart_Handle ToByteData(const fml::Mapping& buffer) { return tonic::DartByteData::Create(buffer.GetMapping(), buffer.GetSize()); } @@ -408,7 +271,105 @@ void PlatformConfiguration::CompletePlatformMessageResponse( response->Complete(std::make_unique(std::move(data))); } -Dart_Handle ComputePlatformResolvedLocale(Dart_Handle supportedLocalesHandle) { +void PlatformConfigurationNativeApi::Render(Scene* scene) { + UIDartState::ThrowIfUIOperationsProhibited(); + UIDartState::Current()->platform_configuration()->client()->Render(scene); +} + +void PlatformConfigurationNativeApi::SetNeedsReportTimings(bool value) { + UIDartState::ThrowIfUIOperationsProhibited(); + UIDartState::Current() + ->platform_configuration() + ->client() + ->SetNeedsReportTimings(value); +} + +Dart_Handle PlatformConfigurationNativeApi::SendPlatformMessage( + const std::string& name, + Dart_Handle callback, + Dart_Handle data_handle) { + UIDartState* dart_state = UIDartState::Current(); + + if (!dart_state->platform_configuration()) { + return tonic::ToDart( + "Platform messages can only be sent from the main isolate"); + } + + fml::RefPtr response; + if (!Dart_IsNull(callback)) { + response = fml::MakeRefCounted( + tonic::DartPersistentValue(dart_state, callback), + dart_state->GetTaskRunners().GetUITaskRunner()); + } + if (Dart_IsNull(data_handle)) { + dart_state->platform_configuration()->client()->HandlePlatformMessage( + std::make_unique(name, response)); + } else { + tonic::DartByteData data(data_handle); + const uint8_t* buffer = static_cast(data.data()); + dart_state->platform_configuration()->client()->HandlePlatformMessage( + std::make_unique( + name, fml::MallocMapping::Copy(buffer, data.length_in_bytes()), + response)); + } + + return Dart_Null(); +} + +void PlatformConfigurationNativeApi::RespondToPlatformMessage( + int response_id, + const tonic::DartByteData& data) { + if (Dart_IsNull(data.dart_handle())) { + UIDartState::Current() + ->platform_configuration() + ->CompletePlatformMessageEmptyResponse(response_id); + } else { + // TODO(engine): Avoid this copy. + const uint8_t* buffer = static_cast(data.data()); + UIDartState::Current() + ->platform_configuration() + ->CompletePlatformMessageResponse( + response_id, + std::vector(buffer, buffer + data.length_in_bytes())); + } +} + +void PlatformConfigurationNativeApi::SetIsolateDebugName( + const std::string name) { + UIDartState::ThrowIfUIOperationsProhibited(); + UIDartState::Current()->SetDebugName(name); +} + +Dart_Handle PlatformConfigurationNativeApi::GetPersistentIsolateData() { + UIDartState::ThrowIfUIOperationsProhibited(); + + auto persistent_isolate_data = UIDartState::Current() + ->platform_configuration() + ->client() + ->GetPersistentIsolateData(); + + if (!persistent_isolate_data) { + return Dart_Null(); + } + + return tonic::DartByteData::Create(persistent_isolate_data->GetMapping(), + persistent_isolate_data->GetSize()); +} + +void PlatformConfigurationNativeApi::ScheduleFrame() { + UIDartState::ThrowIfUIOperationsProhibited(); + UIDartState::Current()->platform_configuration()->client()->ScheduleFrame(); +} + +void PlatformConfigurationNativeApi::UpdateSemantics(SemanticsUpdate* update) { + UIDartState::ThrowIfUIOperationsProhibited(); + UIDartState::Current()->platform_configuration()->client()->UpdateSemantics( + update); +} + +Dart_Handle PlatformConfigurationNativeApi::ComputePlatformResolvedLocale( + Dart_Handle supportedLocalesHandle) { + UIDartState::ThrowIfUIOperationsProhibited(); std::vector supportedLocales = tonic::DartConverter>::FromDart( supportedLocalesHandle); @@ -422,33 +383,12 @@ Dart_Handle ComputePlatformResolvedLocale(Dart_Handle supportedLocalesHandle) { return tonic::DartConverter>::ToDart(results); } -static void _ComputePlatformResolvedLocale(Dart_NativeArguments args) { +std::string PlatformConfigurationNativeApi::DefaultRouteName() { UIDartState::ThrowIfUIOperationsProhibited(); - Dart_Handle result = - ComputePlatformResolvedLocale(Dart_GetNativeArgument(args, 1)); - Dart_SetReturnValue(args, result); -} - -void PlatformConfiguration::RegisterNatives( - tonic::DartLibraryNatives* natives) { - natives->Register({ - {"PlatformConfiguration_defaultRouteName", DefaultRouteName, 1, true}, - {"PlatformConfiguration_scheduleFrame", ScheduleFrame, 1, true}, - {"PlatformConfiguration_sendPlatformMessage", _SendPlatformMessage, 4, - true}, - {"PlatformConfiguration_respondToPlatformMessage", - _RespondToPlatformMessage, 3, true}, - {"PlatformConfiguration_render", Render, 3, true}, - {"PlatformConfiguration_updateSemantics", UpdateSemantics, 2, true}, - {"PlatformConfiguration_setIsolateDebugName", SetIsolateDebugName, 2, - true}, - {"PlatformConfiguration_setNeedsReportTimings", SetNeedsReportTimings, 2, - true}, - {"PlatformConfiguration_getPersistentIsolateData", - GetPersistentIsolateData, 1, true}, - {"PlatformConfiguration_computePlatformResolvedLocale", - _ComputePlatformResolvedLocale, 2, true}, - }); + return UIDartState::Current() + ->platform_configuration() + ->client() + ->DefaultRouteName(); } } // namespace flutter diff --git a/engine/src/flutter/lib/ui/window/platform_configuration.h b/engine/src/flutter/lib/ui/window/platform_configuration.h index a8f3cf4ab3a..46b2b49097e 100644 --- a/engine/src/flutter/lib/ui/window/platform_configuration.h +++ b/engine/src/flutter/lib/ui/window/platform_configuration.h @@ -17,6 +17,7 @@ #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/lib/ui/window/window.h" #include "third_party/tonic/dart_persistent_value.h" +#include "third_party/tonic/typed_data/dart_byte_data.h" namespace flutter { class FontCollection; @@ -381,15 +382,6 @@ class PlatformConfiguration final { /// void ReportTimings(std::vector timings); - //---------------------------------------------------------------------------- - /// @brief Registers the native handlers for Dart functions that this - /// class handles. - /// - /// @param[in] natives The natives registry that the functions will be - /// registered with. - /// - static void RegisterNatives(tonic::DartLibraryNatives* natives); - //---------------------------------------------------------------------------- /// @brief Retrieves the Window with the given ID managed by the /// `PlatformConfiguration`. @@ -444,6 +436,43 @@ class PlatformConfiguration final { pending_responses_; }; +//---------------------------------------------------------------------------- +// API exposed as FFI calls in Dart. +// +// These are probably not supposed to be called directly, and should instead +// be called through their sibling API in `PlatformConfiguration` or +// `PlatformConfigurationClient`. +// +// These are intentionally undocumented. Refer instead to the sibling methods +// above. +//---------------------------------------------------------------------------- +class PlatformConfigurationNativeApi { + public: + static std::string DefaultRouteName(); + + static void ScheduleFrame(); + + static void Render(Scene* scene); + + static void UpdateSemantics(SemanticsUpdate* update); + + static void SetNeedsReportTimings(bool value); + + static Dart_Handle GetPersistentIsolateData(); + + static Dart_Handle ComputePlatformResolvedLocale( + Dart_Handle supportedLocalesHandle); + + static void SetIsolateDebugName(const std::string name); + + static Dart_Handle SendPlatformMessage(const std::string& name, + Dart_Handle callback, + Dart_Handle data_handle); + + static void RespondToPlatformMessage(int response_id, + const tonic::DartByteData& data); +}; + } // namespace flutter #endif // FLUTTER_LIB_UI_WINDOW_PLATFORM_CONFIGURATION_H_ diff --git a/engine/src/flutter/runtime/dart_vm.cc b/engine/src/flutter/runtime/dart_vm.cc index 872726acaee..4ec4d1d998a 100644 --- a/engine/src/flutter/runtime/dart_vm.cc +++ b/engine/src/flutter/runtime/dart_vm.cc @@ -434,8 +434,6 @@ DartVM::DartVM(std::shared_ptr vm_data, ::free(flags_error); } - DartUI::InitForGlobal(); - { TRACE_EVENT0("flutter", "Dart_Initialize"); Dart_InitializeParams params = {}; diff --git a/engine/src/flutter/third_party/tonic/converter/dart_converter.h b/engine/src/flutter/third_party/tonic/converter/dart_converter.h index 0c103611c02..7e8df56fdd6 100644 --- a/engine/src/flutter/third_party/tonic/converter/dart_converter.h +++ b/engine/src/flutter/third_party/tonic/converter/dart_converter.h @@ -309,6 +309,9 @@ struct DartConverter { } static NativeType FromDart(Dart_Handle handle) { + if (Dart_IsNull(handle)) { + return std::string(); + } uint8_t* data = nullptr; intptr_t length = 0; if (Dart_IsError(Dart_StringToUTF8(handle, &data, &length))) @@ -347,6 +350,9 @@ struct DartConverter { } static NativeType FromDart(Dart_Handle handle) { + if (Dart_IsNull(handle)) { + return std::u16string(); + } intptr_t length = 0; Dart_StringLength(handle, &length); std::vector data(length); @@ -378,6 +384,9 @@ struct DartConverter { } static const char* FromDart(Dart_Handle handle) { + if (Dart_IsNull(handle)) { + return nullptr; + } const char* result = nullptr; Dart_StringToCString(handle, &result); return result; diff --git a/engine/src/flutter/third_party/tonic/dart_wrappable.cc b/engine/src/flutter/third_party/tonic/dart_wrappable.cc index 69cc7a533f6..630d6121d04 100644 --- a/engine/src/flutter/third_party/tonic/dart_wrappable.cc +++ b/engine/src/flutter/third_party/tonic/dart_wrappable.cc @@ -89,6 +89,9 @@ Dart_PersistentHandle DartWrappable::GetTypeForWrapper( } DartWrappable* DartConverterWrappable::FromDart(Dart_Handle handle) { + if (Dart_IsNull(handle)) { + return nullptr; + } intptr_t peer = 0; Dart_Handle result = Dart_GetNativeInstanceField(handle, DartWrappable::kPeerIndex, &peer); diff --git a/engine/src/flutter/third_party/tonic/typed_data/dart_byte_data.h b/engine/src/flutter/third_party/tonic/typed_data/dart_byte_data.h index bad96446de6..9e14bc969fb 100644 --- a/engine/src/flutter/third_party/tonic/typed_data/dart_byte_data.h +++ b/engine/src/flutter/third_party/tonic/typed_data/dart_byte_data.h @@ -42,10 +42,15 @@ class DartByteData { template <> struct DartConverter { + using FfiType = Dart_Handle; + static void SetReturnValue(Dart_NativeArguments args, DartByteData val); static DartByteData FromArguments(Dart_NativeArguments args, int index, Dart_Handle& exception); + + static DartByteData FromFfi(FfiType val) { return DartByteData(val); } + static FfiType ToFfi(DartByteData val) { return val.dart_handle(); } }; } // namespace tonic