| 1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "flutter/lib/ui/dart_ui.h" |
| 6 | |
| 7 | #include <mutex> |
| 8 | #include <string_view> |
| 9 | |
| 10 | #include "flutter/common/settings.h" |
| 11 | #include "flutter/fml/build_config.h" |
| 12 | #include "flutter/lib/ui/compositing/scene.h" |
| 13 | #include "flutter/lib/ui/compositing/scene_builder.h" |
| 14 | #include "flutter/lib/ui/dart_runtime_hooks.h" |
| 15 | #include "flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h" |
| 16 | #include "flutter/lib/ui/painting/canvas.h" |
| 17 | #include "flutter/lib/ui/painting/codec.h" |
| 18 | #include "flutter/lib/ui/painting/color_filter.h" |
| 19 | #include "flutter/lib/ui/painting/engine_layer.h" |
| 20 | #include "flutter/lib/ui/painting/fragment_program.h" |
| 21 | #include "flutter/lib/ui/painting/fragment_shader.h" |
| 22 | #include "flutter/lib/ui/painting/gradient.h" |
| 23 | #include "flutter/lib/ui/painting/image.h" |
| 24 | #include "flutter/lib/ui/painting/image_descriptor.h" |
| 25 | #include "flutter/lib/ui/painting/image_filter.h" |
| 26 | #include "flutter/lib/ui/painting/image_shader.h" |
| 27 | #include "flutter/lib/ui/painting/immutable_buffer.h" |
| 28 | #include "flutter/lib/ui/painting/path.h" |
| 29 | #include "flutter/lib/ui/painting/path_measure.h" |
| 30 | #include "flutter/lib/ui/painting/picture.h" |
| 31 | #include "flutter/lib/ui/painting/picture_recorder.h" |
| 32 | #include "flutter/lib/ui/painting/vertices.h" |
| 33 | #include "flutter/lib/ui/semantics/semantics_update.h" |
| 34 | #include "flutter/lib/ui/semantics/semantics_update_builder.h" |
| 35 | #include "flutter/lib/ui/semantics/string_attribute.h" |
| 36 | #include "flutter/lib/ui/text/font_collection.h" |
| 37 | #include "flutter/lib/ui/text/paragraph.h" |
| 38 | #include "flutter/lib/ui/text/paragraph_builder.h" |
| 39 | #include "flutter/lib/ui/window/platform_configuration.h" |
| 40 | #include "third_party/tonic/converter/dart_converter.h" |
| 41 | #include "third_party/tonic/dart_args.h" |
| 42 | #include "third_party/tonic/logging/dart_error.h" |
| 43 | |
| 44 | #ifdef IMPELLER_ENABLE_3D |
| 45 | #include "flutter/lib/ui/painting/scene/scene_node.h" |
| 46 | #include "flutter/lib/ui/painting/scene/scene_shader.h" |
| 47 | #endif // IMPELLER_ENABLE_3D |
| 48 | |
| 49 | using tonic::ToDart; |
| 50 | |
| 51 | namespace flutter { |
| 52 | |
| 53 | typedef CanvasImage Image; |
| 54 | typedef CanvasPathMeasure PathMeasure; |
| 55 | typedef CanvasGradient Gradient; |
| 56 | typedef CanvasPath Path; |
| 57 | |
| 58 | // List of native static functions used as @Native functions. |
| 59 | // Items are tuples of ('function_name', 'parameter_count'), where: |
| 60 | // 'function_name' is the fully qualified name of the native function. |
| 61 | // 'parameter_count' is the number of parameters the function has. |
| 62 | // |
| 63 | // These are used to: |
| 64 | // - Instantiate FfiDispatcher templates to automatically create FFI Native |
| 65 | // bindings. |
| 66 | // If the name does not match a native function, the template will fail to |
| 67 | // instatiate, resulting in a compile time error. |
| 68 | // - Resolve the native function pointer associated with an @Native function. |
| 69 | // If there is a mismatch between name or parameter count an @Native is |
| 70 | // trying to resolve, an exception will be thrown. |
| 71 | #define FFI_FUNCTION_LIST(V) \ |
| 72 | /* Constructors */ \ |
| 73 | V(Canvas::Create, 6) \ |
| 74 | V(ColorFilter::Create, 1) \ |
| 75 | V(FragmentProgram::Create, 1) \ |
| 76 | V(ReusableFragmentShader::Create, 4) \ |
| 77 | V(Gradient::Create, 1) \ |
| 78 | V(ImageFilter::Create, 1) \ |
| 79 | V(ImageShader::Create, 1) \ |
| 80 | V(ParagraphBuilder::Create, 10) \ |
| 81 | V(PathMeasure::Create, 3) \ |
| 82 | V(Path::Create, 1) \ |
| 83 | V(PictureRecorder::Create, 1) \ |
| 84 | V(SceneBuilder::Create, 1) \ |
| 85 | V(SemanticsUpdateBuilder::Create, 1) \ |
| 86 | /* Other */ \ |
| 87 | V(FontCollection::LoadFontFromList, 3) \ |
| 88 | V(ImageDescriptor::initEncoded, 3) \ |
| 89 | V(ImmutableBuffer::init, 3) \ |
| 90 | V(ImmutableBuffer::initFromAsset, 3) \ |
| 91 | V(ImmutableBuffer::initFromFile, 3) \ |
| 92 | V(ImageDescriptor::initRaw, 6) \ |
| 93 | V(IsolateNameServerNatives::LookupPortByName, 1) \ |
| 94 | V(IsolateNameServerNatives::RegisterPortWithName, 2) \ |
| 95 | V(IsolateNameServerNatives::RemovePortNameMapping, 1) \ |
| 96 | V(NativeStringAttribute::initLocaleStringAttribute, 4) \ |
| 97 | V(NativeStringAttribute::initSpellOutStringAttribute, 3) \ |
| 98 | V(PlatformConfigurationNativeApi::ImplicitViewEnabled, 0) \ |
| 99 | V(PlatformConfigurationNativeApi::DefaultRouteName, 0) \ |
| 100 | V(PlatformConfigurationNativeApi::ScheduleFrame, 0) \ |
| 101 | V(PlatformConfigurationNativeApi::Render, 1) \ |
| 102 | V(PlatformConfigurationNativeApi::UpdateSemantics, 1) \ |
| 103 | V(PlatformConfigurationNativeApi::SetNeedsReportTimings, 1) \ |
| 104 | V(PlatformConfigurationNativeApi::SetIsolateDebugName, 1) \ |
| 105 | V(PlatformConfigurationNativeApi::RequestDartPerformanceMode, 1) \ |
| 106 | V(PlatformConfigurationNativeApi::GetPersistentIsolateData, 0) \ |
| 107 | V(PlatformConfigurationNativeApi::ComputePlatformResolvedLocale, 1) \ |
| 108 | V(PlatformConfigurationNativeApi::SendPlatformMessage, 3) \ |
| 109 | V(PlatformConfigurationNativeApi::RespondToPlatformMessage, 2) \ |
| 110 | V(PlatformConfigurationNativeApi::GetRootIsolateToken, 0) \ |
| 111 | V(PlatformConfigurationNativeApi::RegisterBackgroundIsolate, 1) \ |
| 112 | V(PlatformConfigurationNativeApi::SendPortPlatformMessage, 4) \ |
| 113 | V(DartRuntimeHooks::Logger_PrintDebugString, 1) \ |
| 114 | V(DartRuntimeHooks::Logger_PrintString, 1) \ |
| 115 | V(DartRuntimeHooks::ScheduleMicrotask, 1) \ |
| 116 | V(DartRuntimeHooks::GetCallbackHandle, 1) \ |
| 117 | V(DartRuntimeHooks::GetCallbackFromHandle, 1) \ |
| 118 | V(DartPluginRegistrant_EnsureInitialized, 0) \ |
| 119 | V(Vertices::init, 6) |
| 120 | |
| 121 | // List of native instance methods used as @Native functions. |
| 122 | // Items are tuples of ('class_name', 'method_name', 'parameter_count'), where: |
| 123 | // 'class_name' is the name of the class containing the method. |
| 124 | // 'method_name' is the name of the method. |
| 125 | // 'parameter_count' is the number of parameters the method has including the |
| 126 | // implicit `this` parameter. |
| 127 | // |
| 128 | // These are used to: |
| 129 | // - Instantiate FfiDispatcher templates to automatically create FFI Native |
| 130 | // bindings. |
| 131 | // If the name does not match a native function, the template will fail to |
| 132 | // instatiate, resulting in a compile time error. |
| 133 | // - Resolve the native function pointer associated with an @Native function. |
| 134 | // If there is a mismatch between names or parameter count an @Native is |
| 135 | // trying to resolve, an exception will be thrown. |
| 136 | #define FFI_METHOD_LIST(V) \ |
| 137 | V(Canvas, clipPath, 3) \ |
| 138 | V(Canvas, clipRect, 7) \ |
| 139 | V(Canvas, clipRRect, 3) \ |
| 140 | V(Canvas, drawArc, 10) \ |
| 141 | V(Canvas, drawAtlas, 10) \ |
| 142 | V(Canvas, drawCircle, 6) \ |
| 143 | V(Canvas, drawColor, 3) \ |
| 144 | V(Canvas, drawDRRect, 5) \ |
| 145 | V(Canvas, drawImage, 7) \ |
| 146 | V(Canvas, drawImageNine, 13) \ |
| 147 | V(Canvas, drawImageRect, 13) \ |
| 148 | V(Canvas, drawLine, 7) \ |
| 149 | V(Canvas, drawOval, 7) \ |
| 150 | V(Canvas, drawPaint, 3) \ |
| 151 | V(Canvas, drawPath, 4) \ |
| 152 | V(Canvas, drawPicture, 2) \ |
| 153 | V(Canvas, drawPoints, 5) \ |
| 154 | V(Canvas, drawRRect, 4) \ |
| 155 | V(Canvas, drawRect, 7) \ |
| 156 | V(Canvas, drawShadow, 5) \ |
| 157 | V(Canvas, drawVertices, 5) \ |
| 158 | V(Canvas, getDestinationClipBounds, 2) \ |
| 159 | V(Canvas, getLocalClipBounds, 2) \ |
| 160 | V(Canvas, getSaveCount, 1) \ |
| 161 | V(Canvas, getTransform, 2) \ |
| 162 | V(Canvas, restore, 1) \ |
| 163 | V(Canvas, restoreToCount, 2) \ |
| 164 | V(Canvas, rotate, 2) \ |
| 165 | V(Canvas, save, 1) \ |
| 166 | V(Canvas, saveLayer, 7) \ |
| 167 | V(Canvas, saveLayerWithoutBounds, 3) \ |
| 168 | V(Canvas, scale, 3) \ |
| 169 | V(Canvas, skew, 3) \ |
| 170 | V(Canvas, transform, 2) \ |
| 171 | V(Canvas, translate, 3) \ |
| 172 | V(Codec, dispose, 1) \ |
| 173 | V(Codec, frameCount, 1) \ |
| 174 | V(Codec, getNextFrame, 2) \ |
| 175 | V(Codec, repetitionCount, 1) \ |
| 176 | V(ColorFilter, initLinearToSrgbGamma, 1) \ |
| 177 | V(ColorFilter, initMatrix, 2) \ |
| 178 | V(ColorFilter, initMode, 3) \ |
| 179 | V(ColorFilter, initSrgbToLinearGamma, 1) \ |
| 180 | V(EngineLayer, dispose, 1) \ |
| 181 | V(FragmentProgram, initFromAsset, 2) \ |
| 182 | V(ReusableFragmentShader, Dispose, 1) \ |
| 183 | V(ReusableFragmentShader, SetImageSampler, 3) \ |
| 184 | V(ReusableFragmentShader, ValidateSamplers, 1) \ |
| 185 | V(Gradient, initLinear, 6) \ |
| 186 | V(Gradient, initRadial, 8) \ |
| 187 | V(Gradient, initSweep, 9) \ |
| 188 | V(Gradient, initTwoPointConical, 11) \ |
| 189 | V(Image, dispose, 1) \ |
| 190 | V(Image, width, 1) \ |
| 191 | V(Image, height, 1) \ |
| 192 | V(Image, toByteData, 3) \ |
| 193 | V(Image, colorSpace, 1) \ |
| 194 | V(ImageDescriptor, bytesPerPixel, 1) \ |
| 195 | V(ImageDescriptor, dispose, 1) \ |
| 196 | V(ImageDescriptor, height, 1) \ |
| 197 | V(ImageDescriptor, instantiateCodec, 4) \ |
| 198 | V(ImageDescriptor, width, 1) \ |
| 199 | V(ImageFilter, initBlur, 4) \ |
| 200 | V(ImageFilter, initDilate, 3) \ |
| 201 | V(ImageFilter, initErode, 3) \ |
| 202 | V(ImageFilter, initColorFilter, 2) \ |
| 203 | V(ImageFilter, initComposeFilter, 3) \ |
| 204 | V(ImageFilter, initMatrix, 3) \ |
| 205 | V(ImageShader, dispose, 1) \ |
| 206 | V(ImageShader, initWithImage, 6) \ |
| 207 | V(ImmutableBuffer, dispose, 1) \ |
| 208 | V(ImmutableBuffer, length, 1) \ |
| 209 | V(ParagraphBuilder, addPlaceholder, 6) \ |
| 210 | V(ParagraphBuilder, addText, 2) \ |
| 211 | V(ParagraphBuilder, build, 2) \ |
| 212 | V(ParagraphBuilder, pop, 1) \ |
| 213 | V(ParagraphBuilder, pushStyle, 16) \ |
| 214 | V(Paragraph, alphabeticBaseline, 1) \ |
| 215 | V(Paragraph, computeLineMetrics, 1) \ |
| 216 | V(Paragraph, didExceedMaxLines, 1) \ |
| 217 | V(Paragraph, dispose, 1) \ |
| 218 | V(Paragraph, getLineBoundary, 2) \ |
| 219 | V(Paragraph, getPositionForOffset, 3) \ |
| 220 | V(Paragraph, getRectsForPlaceholders, 1) \ |
| 221 | V(Paragraph, getRectsForRange, 5) \ |
| 222 | V(Paragraph, getWordBoundary, 2) \ |
| 223 | V(Paragraph, height, 1) \ |
| 224 | V(Paragraph, ideographicBaseline, 1) \ |
| 225 | V(Paragraph, layout, 2) \ |
| 226 | V(Paragraph, longestLine, 1) \ |
| 227 | V(Paragraph, maxIntrinsicWidth, 1) \ |
| 228 | V(Paragraph, minIntrinsicWidth, 1) \ |
| 229 | V(Paragraph, paint, 4) \ |
| 230 | V(Paragraph, width, 1) \ |
| 231 | V(PathMeasure, setPath, 3) \ |
| 232 | V(PathMeasure, getLength, 2) \ |
| 233 | V(PathMeasure, getPosTan, 3) \ |
| 234 | V(PathMeasure, getSegment, 6) \ |
| 235 | V(PathMeasure, isClosed, 2) \ |
| 236 | V(PathMeasure, nextContour, 1) \ |
| 237 | V(Path, addArc, 7) \ |
| 238 | V(Path, addOval, 5) \ |
| 239 | V(Path, addPath, 4) \ |
| 240 | V(Path, addPathWithMatrix, 5) \ |
| 241 | V(Path, addPolygon, 3) \ |
| 242 | V(Path, addRRect, 2) \ |
| 243 | V(Path, addRect, 5) \ |
| 244 | V(Path, arcTo, 8) \ |
| 245 | V(Path, arcToPoint, 8) \ |
| 246 | V(Path, clone, 2) \ |
| 247 | V(Path, close, 1) \ |
| 248 | V(Path, conicTo, 6) \ |
| 249 | V(Path, contains, 3) \ |
| 250 | V(Path, cubicTo, 7) \ |
| 251 | V(Path, extendWithPath, 4) \ |
| 252 | V(Path, extendWithPathAndMatrix, 5) \ |
| 253 | V(Path, getBounds, 1) \ |
| 254 | V(Path, getFillType, 1) \ |
| 255 | V(Path, lineTo, 3) \ |
| 256 | V(Path, moveTo, 3) \ |
| 257 | V(Path, op, 4) \ |
| 258 | V(Path, quadraticBezierTo, 5) \ |
| 259 | V(Path, relativeArcToPoint, 8) \ |
| 260 | V(Path, relativeConicTo, 6) \ |
| 261 | V(Path, relativeCubicTo, 7) \ |
| 262 | V(Path, relativeLineTo, 3) \ |
| 263 | V(Path, relativeMoveTo, 3) \ |
| 264 | V(Path, relativeQuadraticBezierTo, 5) \ |
| 265 | V(Path, reset, 1) \ |
| 266 | V(Path, setFillType, 2) \ |
| 267 | V(Path, shift, 4) \ |
| 268 | V(Path, transform, 3) \ |
| 269 | V(PictureRecorder, endRecording, 2) \ |
| 270 | V(Picture, GetAllocationSize, 1) \ |
| 271 | V(Picture, dispose, 1) \ |
| 272 | V(Picture, toImage, 4) \ |
| 273 | V(Picture, toImageSync, 4) \ |
| 274 | V(SceneBuilder, addPerformanceOverlay, 6) \ |
| 275 | V(SceneBuilder, addPicture, 5) \ |
| 276 | V(SceneBuilder, addPlatformView, 6) \ |
| 277 | V(SceneBuilder, addRetained, 2) \ |
| 278 | V(SceneBuilder, addTexture, 8) \ |
| 279 | V(SceneBuilder, build, 2) \ |
| 280 | V(SceneBuilder, pop, 1) \ |
| 281 | V(SceneBuilder, pushBackdropFilter, 5) \ |
| 282 | V(SceneBuilder, pushClipPath, 5) \ |
| 283 | V(SceneBuilder, pushClipRRect, 5) \ |
| 284 | V(SceneBuilder, pushClipRect, 8) \ |
| 285 | V(SceneBuilder, pushColorFilter, 4) \ |
| 286 | V(SceneBuilder, pushImageFilter, 4) \ |
| 287 | V(SceneBuilder, pushOffset, 5) \ |
| 288 | V(SceneBuilder, pushOpacity, 6) \ |
| 289 | V(SceneBuilder, pushShaderMask, 10) \ |
| 290 | V(SceneBuilder, pushTransformHandle, 4) \ |
| 291 | V(SceneBuilder, setCheckerboardOffscreenLayers, 2) \ |
| 292 | V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ |
| 293 | V(SceneBuilder, setRasterizerTracingThreshold, 2) \ |
| 294 | V(Scene, dispose, 1) \ |
| 295 | V(Scene, toImage, 4) \ |
| 296 | V(Scene, toImageSync, 4) \ |
| 297 | V(SemanticsUpdateBuilder, build, 2) \ |
| 298 | V(SemanticsUpdateBuilder, updateCustomAction, 5) \ |
| 299 | V(SemanticsUpdateBuilder, updateNode, 36) \ |
| 300 | V(SemanticsUpdate, dispose, 1) \ |
| 301 | V(Vertices, dispose, 1) |
| 302 | |
| 303 | #ifdef IMPELLER_ENABLE_3D |
| 304 | |
| 305 | #define FFI_FUNCTION_LIST_3D(V) \ |
| 306 | V(SceneNode::Create, 1) V(SceneShader::Create, 2) |
| 307 | |
| 308 | #define FFI_METHOD_LIST_3D(V) \ |
| 309 | V(SceneNode, initFromAsset, 3) \ |
| 310 | V(SceneNode, initFromTransform, 2) \ |
| 311 | V(SceneNode, AddChild, 2) \ |
| 312 | V(SceneNode, SetTransform, 2) \ |
| 313 | V(SceneNode, SetAnimationState, 5) \ |
| 314 | V(SceneNode, SeekAnimation, 3) \ |
| 315 | V(SceneShader, SetCameraTransform, 2) \ |
| 316 | V(SceneShader, Dispose, 1) |
| 317 | |
| 318 | #endif // IMPELLER_ENABLE_3D |
| 319 | |
| 320 | #define FFI_FUNCTION_INSERT(FUNCTION, ARGS) \ |
| 321 | g_function_dispatchers.insert(std::make_pair( \ |
| 322 | std::string_view(#FUNCTION), \ |
| 323 | reinterpret_cast<void*>( \ |
| 324 | tonic::FfiDispatcher<void, decltype(&FUNCTION), &FUNCTION>::Call))); |
| 325 | |
| 326 | #define FFI_METHOD_INSERT(CLASS, METHOD, ARGS) \ |
| 327 | g_function_dispatchers.insert( \ |
| 328 | std::make_pair(std::string_view(#CLASS "::" #METHOD), \ |
| 329 | reinterpret_cast<void*>( \ |
| 330 | tonic::FfiDispatcher<CLASS, decltype(&CLASS::METHOD), \ |
| 331 | &CLASS::METHOD>::Call))); |
| 332 | |
| 333 | namespace { |
| 334 | |
| 335 | std::once_flag g_dispatchers_init_flag; |
| 336 | std::unordered_map<std::string_view, void*> g_function_dispatchers; |
| 337 | |
| 338 | void* ResolveFfiNativeFunction(const char* name, uintptr_t args) { |
| 339 | auto it = g_function_dispatchers.find(k: name); |
| 340 | return (it != g_function_dispatchers.end()) ? it->second : nullptr; |
| 341 | } |
| 342 | |
| 343 | void InitDispatcherMap() { |
| 344 | FFI_FUNCTION_LIST(FFI_FUNCTION_INSERT) |
| 345 | FFI_METHOD_LIST(FFI_METHOD_INSERT) |
| 346 | |
| 347 | #ifdef IMPELLER_ENABLE_3D |
| 348 | FFI_FUNCTION_LIST_3D(FFI_FUNCTION_INSERT) |
| 349 | FFI_METHOD_LIST_3D(FFI_METHOD_INSERT) |
| 350 | #endif // IMPELLER_ENABLE_3D |
| 351 | } |
| 352 | |
| 353 | } // anonymous namespace |
| 354 | |
| 355 | void DartUI::InitForIsolate(const Settings& settings) { |
| 356 | std::call_once(flag&: g_dispatchers_init_flag, func&: InitDispatcherMap); |
| 357 | |
| 358 | auto dart_ui = Dart_LookupLibrary(url: ToDart(val: "dart:ui" )); |
| 359 | if (Dart_IsError(handle: dart_ui)) { |
| 360 | Dart_PropagateError(handle: dart_ui); |
| 361 | } |
| 362 | |
| 363 | // Set up FFI Native resolver for dart:ui. |
| 364 | Dart_Handle result = |
| 365 | Dart_SetFfiNativeResolver(library: dart_ui, resolver: ResolveFfiNativeFunction); |
| 366 | if (Dart_IsError(handle: result)) { |
| 367 | Dart_PropagateError(handle: result); |
| 368 | } |
| 369 | |
| 370 | if (settings.enable_impeller) { |
| 371 | result = Dart_SetField(container: dart_ui, name: ToDart(val: "_impellerEnabled" ), value: Dart_True()); |
| 372 | if (Dart_IsError(handle: result)) { |
| 373 | Dart_PropagateError(handle: result); |
| 374 | } |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | } // namespace flutter |
| 379 | |