From 25e5809a96b72d52f7321108a68dc1d9ba68af98 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 13:59:20 -0800 Subject: [PATCH 1/8] ++ --- impeller/tools/impeller.gni | 3 + lib/snapshot/BUILD.gn | 7 +- lib/snapshot/libraries_experimental.json | 17 + lib/ui/BUILD.gn | 3 + lib/ui/compositing/scene_builder.cc | 11 + lib/ui/compositing/scene_builder.h | 9 + lib/ui/dart_ui.cc | 7 + lib/ui/dart_ui.gni | 74 +- lib/ui/experiments/compositing_3d.dart | 884 +++++++++++++++++++++++ lib/ui/experiments/ui.dart | 42 ++ tools/gn | 10 + 11 files changed, 1043 insertions(+), 24 deletions(-) create mode 100644 lib/snapshot/libraries_experimental.json create mode 100644 lib/ui/experiments/compositing_3d.dart create mode 100644 lib/ui/experiments/ui.dart diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index aeb3f162a172d..eb673525db2fd 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -30,6 +30,9 @@ declare_args() { # Call glGetError after each OpenGL call and log failures. impeller_error_check_all_gl_calls = is_debug + + # Eperimentally enable 3d code paths. + impeller_enable_3d = false } declare_args() { diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index d8176bdf5151d..8a195add5bebe 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -315,8 +315,11 @@ source_set("snapshot") { compile_platform("strong_platform") { single_root_scheme = "org-dartlang-sdk" single_root_base = rebase_path("../../../") - libraries_specification_uri = - "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" + if (impeller_enable_3d) { + libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries_experimental.json" + } else { + libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" + } outputs = [ "$root_out_dir/flutter_patched_sdk/platform_strong.dill", diff --git a/lib/snapshot/libraries_experimental.json b/lib/snapshot/libraries_experimental.json new file mode 100644 index 0000000000000..08577acb38ace --- /dev/null +++ b/lib/snapshot/libraries_experimental.json @@ -0,0 +1,17 @@ +{ + "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.", + "comment:1": "Instead modify 'flutter/lib/snapshot/libraries.yaml' and follow the instructions therein.", + "flutter": { + "include": [ + { + "path": "../../../third_party/dart/sdk/lib/libraries.json", + "target": "vm_common" + } + ], + "libraries": { + "ui": { + "uri": "../../lib/ui/experiments/ui.dart" + } + } + } + } \ No newline at end of file diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index a63414838b5ed..44646ca09bb31 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -185,6 +185,9 @@ source_set("ui") { # Required for M_PI and others. defines += [ "_USE_MATH_DEFINES" ] } + if (impeller_enable_3d) { + defines += [ "IMPELLER_ENABLE_3D" ] + } } if (enable_unittests) { diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 6f1c718fa1b5f..9c9aebf35c53d 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -262,6 +262,17 @@ void SceneBuilder::addTexture(double dx, AddLayer(std::move(layer)); } +#ifdef IMPELLER_ENABLE_3D +void SceneBuilder::addModelLayer(double dx, + double dy, + double width, + double height, + int64_t viewId) { + // NO-OP. +} + +#endif // IMPELLER_ENABLE_3D + void SceneBuilder::addPlatformView(double dx, double dy, double width, diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h index f2de29c4802d2..02953e02b9159 100644 --- a/lib/ui/compositing/scene_builder.h +++ b/lib/ui/compositing/scene_builder.h @@ -118,6 +118,15 @@ class SceneBuilder : public RefCountedDartWrappable { bool freeze, int filterQuality); +#ifdef IMPELLER_ENABLE_3D + void addModelLayer(double dx, + double dy, + double width, + double height, + int64_t viewId); + +#endif // IMPELLER_ENABLE_3D + void addPlatformView(double dx, double dy, double width, diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 0410926e68334..d2b6860048bbf 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -294,6 +294,10 @@ typedef CanvasPath Path; V(SemanticsUpdate, dispose, 1) \ V(Vertices, dispose, 1) +#ifdef IMPELLER_ENABLE_3D +#define FFI_METHOD_LIST_3D(V)V(SceneBuilder, addModelLayer, 6) +#endif // IMPELLER_ENABLE_3D + #define FFI_FUNCTION_INSERT(FUNCTION, ARGS) \ g_function_dispatchers.insert(std::make_pair( \ std::string_view(#FUNCTION), \ @@ -320,6 +324,9 @@ void* ResolveFfiNativeFunction(const char* name, uintptr_t args) { void InitDispatcherMap() { FFI_FUNCTION_LIST(FFI_FUNCTION_INSERT) FFI_METHOD_LIST(FFI_METHOD_INSERT) +#ifdef IMPELLER_ENABLE_3D + FFI_METHOD_LIST_3D(FFI_METHOD_INSERT) +#endif // IMPELLER_ENABLE_3D } } // anonymous namespace diff --git a/lib/ui/dart_ui.gni b/lib/ui/dart_ui.gni index 7059f7ab2ae08..af83a3ebf745e 100644 --- a/lib/ui/dart_ui.gni +++ b/lib/ui/dart_ui.gni @@ -2,26 +2,56 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -dart_ui_files = [ - "//flutter/lib/ui/annotations.dart", - "//flutter/lib/ui/channel_buffers.dart", - "//flutter/lib/ui/compositing.dart", - "//flutter/lib/ui/geometry.dart", - "//flutter/lib/ui/hash_codes.dart", - "//flutter/lib/ui/hooks.dart", - "//flutter/lib/ui/isolate_name_server.dart", - "//flutter/lib/ui/key.dart", - "//flutter/lib/ui/lerp.dart", - "//flutter/lib/ui/math.dart", - "//flutter/lib/ui/natives.dart", - "//flutter/lib/ui/painting.dart", - "//flutter/lib/ui/platform_dispatcher.dart", - "//flutter/lib/ui/plugins.dart", - "//flutter/lib/ui/pointer.dart", - "//flutter/lib/ui/semantics.dart", - "//flutter/lib/ui/text.dart", - "//flutter/lib/ui/ui.dart", - "//flutter/lib/ui/window.dart", -] +import("//flutter/impeller/tools/impeller.gni") -dart_ui_path = "//flutter/lib/ui/ui.dart" +if (!impeller_enable_3d) { + dart_ui_files = [ + "//flutter/lib/ui/annotations.dart", + "//flutter/lib/ui/channel_buffers.dart", + "//flutter/lib/ui/compositing.dart", + "//flutter/lib/ui/geometry.dart", + "//flutter/lib/ui/hash_codes.dart", + "//flutter/lib/ui/hooks.dart", + "//flutter/lib/ui/isolate_name_server.dart", + "//flutter/lib/ui/key.dart", + "//flutter/lib/ui/lerp.dart", + "//flutter/lib/ui/math.dart", + "//flutter/lib/ui/natives.dart", + "//flutter/lib/ui/painting.dart", + "//flutter/lib/ui/platform_dispatcher.dart", + "//flutter/lib/ui/plugins.dart", + "//flutter/lib/ui/pointer.dart", + "//flutter/lib/ui/semantics.dart", + "//flutter/lib/ui/text.dart", + "//flutter/lib/ui/ui.dart", + "//flutter/lib/ui/window.dart", + ] + + dart_ui_path = "//flutter/lib/ui/ui.dart" + +} else { + dart_ui_files = [ + "//flutter/lib/ui/annotations.dart", + "//flutter/lib/ui/channel_buffers.dart", + "//flutter/lib/ui/compositing.dart", + "//flutter/lib/ui/geometry.dart", + "//flutter/lib/ui/hash_codes.dart", + "//flutter/lib/ui/hooks.dart", + "//flutter/lib/ui/isolate_name_server.dart", + "//flutter/lib/ui/key.dart", + "//flutter/lib/ui/lerp.dart", + "//flutter/lib/ui/math.dart", + "//flutter/lib/ui/natives.dart", + "//flutter/lib/ui/painting.dart", + "//flutter/lib/ui/platform_dispatcher.dart", + "//flutter/lib/ui/plugins.dart", + "//flutter/lib/ui/pointer.dart", + "//flutter/lib/ui/semantics.dart", + "//flutter/lib/ui/text.dart", + "//flutter/lib/ui/window.dart", + "//flutter/lib/ui/experiments/ui.dart", + "//flutter/lib/ui/experiments/compositing_3d.dart", + ] + + dart_ui_path = "//flutter/lib/ui/experiments/ui.dart" +} diff --git a/lib/ui/experiments/compositing_3d.dart b/lib/ui/experiments/compositing_3d.dart new file mode 100644 index 0000000000000..52ee6c0f033e5 --- /dev/null +++ b/lib/ui/experiments/compositing_3d.dart @@ -0,0 +1,884 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +part of dart.ui; + +/// An opaque object representing a composited scene. +/// +/// To create a Scene object, use a [SceneBuilder]. +/// +/// Scene objects can be displayed on the screen using the [FlutterView.render] +/// method. +@pragma('vm:entry-point') +class Scene extends NativeFieldWrapperClass1 { + /// This class is created by the engine, and should not be instantiated + /// or extended directly. + /// + /// To create a Scene object, use a [SceneBuilder]. + @pragma('vm:entry-point') + Scene._(); + + /// Synchronously creates a handle to an image from this scene. + /// + /// {@macro dart.ui.painting.Picture.toImageSync} + Image toImageSync(int width, int height) { + if (width <= 0 || height <= 0) { + throw Exception('Invalid image dimensions.'); + } + + final _Image image = _Image._(); + final String? result = _toImageSync(width, height, image); + if (result != null) { + throw PictureRasterizationException._(result); + } + return Image._(image, image.width, image.height); + } + + @FfiNative, Uint32, Uint32, Handle)>('Scene::toImageSync') + external String? _toImageSync(int width, int height, _Image outImage); + + /// Creates a raster image representation of the current state of the scene. + /// + /// This is a slow operation that is performed on a background thread. + /// + /// Callers must dispose the [Image] when they are done with it. If the result + /// will be shared with other methods or classes, [Image.clone] should be used + /// and each handle created must be disposed. + Future toImage(int width, int height) { + if (width <= 0 || height <= 0) { + throw Exception('Invalid image dimensions.'); + } + return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { + if (image == null) { + callback(null); + } else { + callback(Image._(image, image.width, image.height)); + } + }), + ); + } + + @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. + /// + /// 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. +// +// This is used to provide a typed API for engine layers to prevent +// incompatible layers from being passed to [SceneBuilder]'s push methods. +// For example, this prevents a layer returned from `pushOpacity` from being +// passed as `oldLayer` to `pushTransform`. This is achieved by having one +// concrete subclass of this class per push method. +abstract class _EngineLayerWrapper implements EngineLayer { + _EngineLayerWrapper._(EngineLayer nativeLayer) : _nativeLayer = nativeLayer; + + EngineLayer? _nativeLayer; + + @override + void dispose() { + assert(_nativeLayer != null, 'Object disposed'); + _nativeLayer!.dispose(); + assert(() { + _nativeLayer = null; + return true; + }()); + } + + // Children of this layer. + // + // Null if this layer has no children. This field is populated only in debug + // mode. + List<_EngineLayerWrapper>? _debugChildren; + + // Whether this layer was used as `oldLayer` in a past frame. + // + // It is illegal to use a layer object again after it is passed as an + // `oldLayer` argument. + bool _debugWasUsedAsOldLayer = false; + + bool _debugCheckNotUsedAsOldLayer() { + // The hashCode formatting should match shortHash in the framework + assert( + !_debugWasUsedAsOldLayer, + 'Layer $runtimeType#${hashCode.toUnsigned(20).toRadixString(16).padLeft(5, '0')} was previously used as oldLayer.\n' + 'Once a layer is used as oldLayer, it may not be used again. Instead, ' + 'after calling one of the SceneBuilder.push* methods and passing an oldLayer ' + 'to it, use the layer returned by the method as oldLayer in subsequent ' + 'frames.'); + return true; + } +} + +/// An opaque handle to a transform engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushTransform]. +/// +/// {@template dart.ui.sceneBuilder.oldLayerCompatibility} +/// `oldLayer` parameter in [SceneBuilder] methods only accepts objects created +/// by the engine. [SceneBuilder] will throw an [AssertionError] if you pass it +/// a custom implementation of this class. +/// {@endtemplate} +class TransformEngineLayer extends _EngineLayerWrapper { + TransformEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to an offset engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushOffset]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class OffsetEngineLayer extends _EngineLayerWrapper { + OffsetEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a clip rect engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushClipRect]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ClipRectEngineLayer extends _EngineLayerWrapper { + ClipRectEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a clip rounded rect engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushClipRRect]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ClipRRectEngineLayer extends _EngineLayerWrapper { + ClipRRectEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a clip path engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushClipPath]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ClipPathEngineLayer extends _EngineLayerWrapper { + ClipPathEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to an opacity engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushOpacity]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class OpacityEngineLayer extends _EngineLayerWrapper { + OpacityEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a color filter engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushColorFilter]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ColorFilterEngineLayer extends _EngineLayerWrapper { + ColorFilterEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to an image filter engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushImageFilter]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ImageFilterEngineLayer extends _EngineLayerWrapper { + ImageFilterEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a backdrop filter engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushBackdropFilter]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class BackdropFilterEngineLayer extends _EngineLayerWrapper { + BackdropFilterEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a shader mask engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushShaderMask]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class ShaderMaskEngineLayer extends _EngineLayerWrapper { + ShaderMaskEngineLayer._(super.nativeLayer) : super._(); +} + +/// An opaque handle to a physical shape engine layer. +/// +/// Instances of this class are created by [SceneBuilder.pushPhysicalShape]. +/// +/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} +class PhysicalShapeEngineLayer extends _EngineLayerWrapper { + PhysicalShapeEngineLayer._(super.nativeLayer) : super._(); +} + +/// Builds a [Scene] containing the given visuals. +/// +/// A [Scene] can then be rendered using [FlutterView.render]. +/// +/// To draw graphical operations onto a [Scene], first create a +/// [Picture] using a [PictureRecorder] and a [Canvas], and then add +/// it to the scene using [addPicture]. +class SceneBuilder extends NativeFieldWrapperClass1 { + /// Creates an empty [SceneBuilder] object. + @pragma('vm:entry-point') + SceneBuilder() { + _constructor(); + } + + @FfiNative('SceneBuilder::Create') + external void _constructor(); + + // Layers used in this scene. + // + // The key is the layer used. The value is the description of what the layer + // is used for, e.g. "pushOpacity" or "addRetained". + final Map _usedLayers = {}; + + // In debug mode checks that the `layer` is only used once in a given scene. + bool _debugCheckUsedOnce(EngineLayer layer, String usage) { + assert(() { + assert( + !_usedLayers.containsKey(layer), + 'Layer ${layer.runtimeType} already used.\n' + 'The layer is already being used as ${_usedLayers[layer]} in this scene.\n' + 'A layer may only be used once in a given scene.'); + + _usedLayers[layer] = usage; + return true; + }()); + + return true; + } + + bool _debugCheckCanBeUsedAsOldLayer(_EngineLayerWrapper? layer, String methodName) { + assert(() { + if (layer == null) { + return true; + } + assert(layer._nativeLayer != null, 'Object disposed'); + layer._debugCheckNotUsedAsOldLayer(); + assert(_debugCheckUsedOnce(layer, 'oldLayer in $methodName')); + layer._debugWasUsedAsOldLayer = true; + return true; + }()); + return true; + } + + final List<_EngineLayerWrapper> _layerStack = <_EngineLayerWrapper>[]; + + // Pushes the `newLayer` onto the `_layerStack` and adds it to the + // `_debugChildren` of the current layer in the stack, if any. + bool _debugPushLayer(_EngineLayerWrapper newLayer) { + assert(() { + if (_layerStack.isNotEmpty) { + final _EngineLayerWrapper currentLayer = _layerStack.last; + currentLayer._debugChildren ??= <_EngineLayerWrapper>[]; + currentLayer._debugChildren!.add(newLayer); + } + _layerStack.add(newLayer); + return true; + }()); + return true; + } + + /// Pushes a transform operation onto the operation stack. + /// + /// The objects are transformed by the given matrix before rasterization. + /// + /// {@template dart.ui.sceneBuilder.oldLayer} + /// If `oldLayer` is not null the engine will attempt to reuse the resources + /// allocated for the old layer when rendering the new layer. This is purely + /// an optimization. It has no effect on the correctness of rendering. + /// {@endtemplate} + /// + /// {@template dart.ui.sceneBuilder.oldLayerVsRetained} + /// Passing a layer to [addRetained] or as `oldLayer` argument to a push + /// method counts as _usage_. A layer can be used no more than once in a scene. + /// For example, it may not be passed simultaneously to two push methods, or + /// to a push method and to `addRetained`. + /// + /// When a layer is passed to [addRetained] all descendant layers are also + /// considered as used in this scene. The same single-usage restriction + /// applies to descendants. + /// + /// When a layer is passed as an `oldLayer` argument to a push method, it may + /// no longer be used in subsequent frames. If you would like to continue + /// reusing the resources associated with the layer, store the layer object + /// returned by the push method and use that in the next frame instead of the + /// original object. + /// {@endtemplate} + /// + /// See [pop] for details about the operation stack. + TransformEngineLayer pushTransform( + Float64List matrix4, { + TransformEngineLayer? oldLayer, + }) { + assert(_matrix4IsValid(matrix4)); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushTransform')); + final EngineLayer engineLayer = EngineLayer._(); + _pushTransform(engineLayer, matrix4, oldLayer?._nativeLayer); + final TransformEngineLayer layer = TransformEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @FfiNative, Handle, Handle, Handle)>('SceneBuilder::pushTransformHandle') + external void _pushTransform(EngineLayer layer, Float64List matrix4, EngineLayer? oldLayer); + + /// Pushes an offset operation onto the operation stack. + /// + /// This is equivalent to [pushTransform] with a matrix with only translation. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + OffsetEngineLayer pushOffset( + double dx, + double dy, { + OffsetEngineLayer? oldLayer, + }) { + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushOffset')); + final EngineLayer engineLayer = EngineLayer._(); + _pushOffset(engineLayer, dx, dy, oldLayer?._nativeLayer); + final OffsetEngineLayer layer = OffsetEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// Rasterization outside the given rectangle is discarded. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack, and [Clip] for different clip modes. + /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). + ClipRectEngineLayer pushClipRect( + Rect rect, { + Clip clipBehavior = Clip.antiAlias, + ClipRectEngineLayer? oldLayer, + }) { + assert(clipBehavior != null); + assert(clipBehavior != Clip.none); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipRect')); + final EngineLayer engineLayer = EngineLayer._(); + _pushClipRect(engineLayer, rect.left, rect.right, rect.top, rect.bottom, clipBehavior.index, + oldLayer?._nativeLayer); + final ClipRectEngineLayer layer = ClipRectEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// Rasterization outside the given rounded rectangle is discarded. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack, and [Clip] for different clip modes. + /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). + ClipRRectEngineLayer pushClipRRect( + RRect rrect, { + Clip clipBehavior = Clip.antiAlias, + ClipRRectEngineLayer? oldLayer, + }) { + assert(clipBehavior != null); + assert(clipBehavior != Clip.none); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipRRect')); + final EngineLayer engineLayer = EngineLayer._(); + _pushClipRRect(engineLayer, rrect._getValue32(), clipBehavior.index, oldLayer?._nativeLayer); + final ClipRRectEngineLayer layer = ClipRRectEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// Rasterization outside the given path is discarded. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. See [Clip] for different clip modes. + /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). + ClipPathEngineLayer pushClipPath( + Path path, { + Clip clipBehavior = Clip.antiAlias, + ClipPathEngineLayer? oldLayer, + }) { + assert(clipBehavior != null); + assert(clipBehavior != Clip.none); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipPath')); + final EngineLayer engineLayer = EngineLayer._(); + _pushClipPath(engineLayer, path, clipBehavior.index, oldLayer?._nativeLayer); + final ClipPathEngineLayer layer = ClipPathEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// The given alpha value is blended into the alpha value of the objects' + /// rasterization. An alpha value of 0 makes the objects entirely invisible. + /// An alpha value of 255 has no effect (i.e., the objects retain the current + /// opacity). + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + OpacityEngineLayer pushOpacity( + int alpha, { + Offset? offset = Offset.zero, + OpacityEngineLayer? oldLayer, + }) { + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushOpacity')); + final EngineLayer engineLayer = EngineLayer._(); + _pushOpacity(engineLayer, alpha, offset!.dx, offset.dy, oldLayer?._nativeLayer); + final OpacityEngineLayer layer = OpacityEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// The given color is applied to the objects' rasterization using the given + /// blend mode. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + ColorFilterEngineLayer pushColorFilter( + ColorFilter filter, { + ColorFilterEngineLayer? oldLayer, + }) { + assert(filter != null); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushColorFilter')); + final _ColorFilter nativeFilter = filter._toNativeColorFilter()!; + assert(nativeFilter != null); + final EngineLayer engineLayer = EngineLayer._(); + _pushColorFilter(engineLayer, nativeFilter, oldLayer?._nativeLayer); + final ColorFilterEngineLayer layer = ColorFilterEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @FfiNative, Handle, Pointer, Handle)>('SceneBuilder::pushColorFilter') + external void _pushColorFilter(EngineLayer layer, _ColorFilter filter, EngineLayer? oldLayer); + + /// Pushes an image filter operation onto the operation stack. + /// + /// The given filter is applied to the children's rasterization before compositing them into + /// the scene. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + ImageFilterEngineLayer pushImageFilter( + ImageFilter filter, { + Offset offset = Offset.zero, + ImageFilterEngineLayer? oldLayer, + }) { + assert(filter != null); + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushImageFilter')); + final _ImageFilter nativeFilter = filter._toNativeImageFilter(); + assert(nativeFilter != null); + final EngineLayer engineLayer = EngineLayer._(); + _pushImageFilter(engineLayer, nativeFilter, offset.dx, offset.dy, oldLayer?._nativeLayer); + final ImageFilterEngineLayer layer = ImageFilterEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @FfiNative, Handle, Pointer, Double, Double, Handle)>('SceneBuilder::pushImageFilter') + external void _pushImageFilter(EngineLayer outEngineLayer, _ImageFilter filter, double dx, double dy, EngineLayer? oldLayer); + + /// Pushes a backdrop filter operation onto the operation stack. + /// + /// The given filter is applied to the current contents of the scene as far back as + /// the most recent save layer and rendered back to the scene using the indicated + /// [blendMode] prior to rasterizing the child layers. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + BackdropFilterEngineLayer pushBackdropFilter( + ImageFilter filter, { + BlendMode blendMode = BlendMode.srcOver, + BackdropFilterEngineLayer? oldLayer, + }) { + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushBackdropFilter')); + final EngineLayer engineLayer = EngineLayer._(); + _pushBackdropFilter(engineLayer, filter._toNativeImageFilter(), blendMode.index, oldLayer?._nativeLayer); + final BackdropFilterEngineLayer layer = BackdropFilterEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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. + /// + /// The given shader is applied to the object's rasterization in the given + /// rectangle using the given blend mode. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack. + ShaderMaskEngineLayer pushShaderMask( + Shader shader, + Rect maskRect, + BlendMode blendMode, { + ShaderMaskEngineLayer? oldLayer, + FilterQuality filterQuality = FilterQuality.low, + }) { + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushShaderMask')); + final EngineLayer engineLayer = EngineLayer._(); + _pushShaderMask( + engineLayer, + shader, + maskRect.left, + maskRect.right, + maskRect.top, + maskRect.bottom, + blendMode.index, + filterQuality.index, + oldLayer?._nativeLayer, + ); + final ShaderMaskEngineLayer layer = ShaderMaskEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @FfiNative, Handle, Pointer, Double, Double, Double, Double, Int32, Int32, Handle)>( + 'SceneBuilder::pushShaderMask') + external void _pushShaderMask( + EngineLayer engineLayer, + Shader shader, + double maskRectLeft, + double maskRectRight, + double maskRectTop, + double maskRectBottom, + int blendMode, + int filterQualityIndex, + EngineLayer? oldLayer); + + /// Pushes a physical layer operation for an arbitrary shape onto the + /// operation stack. + /// + /// By default, the layer's content will not be clipped (clip = [Clip.none]). + /// If clip equals [Clip.hardEdge], [Clip.antiAlias], or [Clip.antiAliasWithSaveLayer], + /// then the content is clipped to the given shape defined by [path]. + /// + /// If [elevation] is greater than 0.0, then a shadow is drawn around the layer. + /// [shadowColor] defines the color of the shadow if present and [color] defines the + /// color of the layer background. + /// + /// {@macro dart.ui.sceneBuilder.oldLayer} + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + /// + /// See [pop] for details about the operation stack, and [Clip] for different clip modes. + @Deprecated( + 'Use a clip and canvas operations directly (See RenderPhysicalModel). ' + 'This feature was deprecated after v3.1.0-0.0.pre.', + ) + PhysicalShapeEngineLayer pushPhysicalShape({ + required Path path, + required double elevation, + required Color color, + Color? shadowColor, + Clip clipBehavior = Clip.none, + PhysicalShapeEngineLayer? oldLayer, + }) { + assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushPhysicalShape')); + final EngineLayer engineLayer = EngineLayer._(); + _pushPhysicalShape(engineLayer, path, elevation, color.value, shadowColor?.value ?? 0xFF000000, + clipBehavior.index, oldLayer?._nativeLayer); + final PhysicalShapeEngineLayer layer = PhysicalShapeEngineLayer._(engineLayer); + assert(_debugPushLayer(layer)); + return layer; + } + + @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); + + /// Ends the effect of the most recently pushed operation. + /// + /// Internally the scene builder maintains a stack of operations. Each of the + /// operations in the stack applies to each of the objects added to the scene. + /// Calling this function removes the most recently added operation from the + /// stack. + void pop() { + if (_layerStack.isNotEmpty) { + _layerStack.removeLast(); + } + _pop(); + } + + @FfiNative)>('SceneBuilder::pop', isLeaf: true) + external void _pop(); + + /// Add a retained engine layer subtree from previous frames. + /// + /// All the engine layers that are in the subtree of the retained layer will + /// be automatically appended to the current engine layer tree. + /// + /// Therefore, when implementing a subclass of the [Layer] concept defined in + /// the rendering layer of Flutter's framework, once this is called, there's + /// no need to call [Layer.addToScene] for its children layers. + /// + /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} + void addRetained(EngineLayer retainedLayer) { + assert(retainedLayer is _EngineLayerWrapper); + assert(() { + final _EngineLayerWrapper layer = retainedLayer as _EngineLayerWrapper; + + assert(layer._nativeLayer != null); + + void recursivelyCheckChildrenUsedOnce(_EngineLayerWrapper parentLayer) { + _debugCheckUsedOnce(parentLayer, 'retained layer'); + parentLayer._debugCheckNotUsedAsOldLayer(); + + final List<_EngineLayerWrapper>? children = parentLayer._debugChildren; + if (children == null || children.isEmpty) { + return; + } + children.forEach(recursivelyCheckChildrenUsedOnce); + } + + recursivelyCheckChildrenUsedOnce(layer); + + return true; + }()); + + final _EngineLayerWrapper wrapper = retainedLayer as _EngineLayerWrapper; + _addRetained(wrapper._nativeLayer!); + } + + @FfiNative, Handle)>('SceneBuilder::addRetained') + external void _addRetained(EngineLayer retainedLayer); + + /// Adds an object to the scene that displays performance statistics. + /// + /// Useful during development to assess the performance of the application. + /// The enabledOptions controls which statistics are displayed. The bounds + /// controls where the statistics are displayed. + /// + /// enabledOptions is a bit field with the following bits defined: + /// - 0x01: displayRasterizerStatistics - show raster thread frame time + /// - 0x02: visualizeRasterizerStatistics - graph raster thread frame times + /// - 0x04: displayEngineStatistics - show UI thread frame time + /// - 0x08: visualizeEngineStatistics - graph UI thread frame times + /// Set enabledOptions to 0x0F to enable all the currently defined features. + /// + /// The "UI thread" is the thread that includes all the execution of the main + /// Dart isolate (the isolate that can call [FlutterView.render]). The UI + /// thread frame time is the total time spent executing the + /// [PlatformDispatcher.onBeginFrame] callback. The "raster thread" is the + /// thread (running on the CPU) that subsequently processes the [Scene] + /// provided by the Dart code to turn it into GPU commands and send it to the + /// GPU. + /// + /// See also the [PerformanceOverlayOption] enum in the rendering library. + /// for more details. + // Values above must match constants in //engine/src/sky/compositor/performance_overlay_layer.h + void addPerformanceOverlay(int enabledOptions, Rect bounds) { + _addPerformanceOverlay(enabledOptions, bounds.left, bounds.right, bounds.top, bounds.bottom); + } + + @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. + /// + /// The picture is rasterized at the given offset. + void addPicture( + Offset offset, + Picture picture, { + bool isComplexHint = false, + bool willChangeHint = false, + }) { + assert(!picture.debugDisposed); + final int hints = (isComplexHint ? 1 : 0) | (willChangeHint ? 2 : 0); + _addPicture(offset.dx, offset.dy, picture, hints); + } + + @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. + /// + /// The texture is scaled to the given size and rasterized at the given offset. + /// + /// If `freeze` is true the texture that is added to the scene will not + /// be updated with new frames. `freeze` is used when resizing an embedded + /// Android view: When resizing an Android view there is a short period during + /// which the framework cannot tell if the newest texture frame has the + /// previous or new size, to workaround this the framework "freezes" the + /// texture just before resizing the Android view and un-freezes it when it is + /// certain that a frame with the new size is ready. + void addTexture( + int textureId, { + Offset offset = Offset.zero, + double width = 0.0, + double height = 0.0, + bool freeze = false, + FilterQuality filterQuality = FilterQuality.low, + }) { + assert(offset != null, 'Offset argument was null'); + _addTexture(offset.dx, offset.dy, width, height, textureId, freeze, filterQuality.index); + } + + @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. + /// + /// On iOS this layer splits the current output surface into two surfaces, one for the scene nodes + /// preceding the platform view, and one for the scene nodes following the platform view. + /// + /// ## Performance impact + /// + /// Adding an additional surface doubles the amount of graphics memory directly used by Flutter + /// for output buffers. Quartz might allocated extra buffers for compositing the Flutter surfaces + /// and the platform view. + /// + /// With a platform view in the scene, Quartz has to composite the two Flutter surfaces and the + /// embedded UIView. In addition to that, on iOS versions greater than 9, the Flutter frames are + /// synchronized with the UIView frames adding additional performance overhead. + /// + /// The `offset` argument is not used for iOS and Android. + void addPlatformView( + int viewId, { + Offset offset = Offset.zero, + double width = 0.0, + double height = 0.0, + }) { + assert(offset != null, 'Offset argument was null'); + _addPlatformView(offset.dx, offset.dy, width, height, viewId); + } + + @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addPlatformView', isLeaf: true) + external void _addPlatformView(double dx, double dy, double width, double height, int viewId); + + void addModelLayer( + int viewId, { + Offset offset = Offset.zero, + double width = 0.0, + double height = 0.0, + }) { + assert(offset != null, 'Offset argument was null'); + _addModelLayer(offset.dx, offset.dy, width, height, viewId); + } + + @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addModelLayer', isLeaf: true) + external void _addModelLayer(double dx, double dy, double width, double height, int viewId); + + /// Sets a threshold after which additional debugging information should be recorded. + /// + /// 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). + /// We'll hopefully be able to figure out how to make this feature more useful + /// to you. + @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. + /// + /// The compositor can sometimes decide to cache certain portions of the + /// widget hierarchy. Such portions typically don't change often from frame to + /// frame and are expensive to render. This can speed up overall rendering. However, + /// there is certain upfront cost to constructing these cache entries. And, if + /// the cache entries are not used very often, this cost may not be worth the + /// speedup in rendering of subsequent frames. If the developer wants to be certain + /// that populating the raster cache is not causing stutters, this option can be + /// set. Depending on the observations made, hints can be provided to the compositor + /// that aid it in making better decisions about caching. + /// + /// 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). + @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. + @FfiNative, Bool)>('SceneBuilder::setCheckerboardOffscreenLayers', isLeaf: true) + external void setCheckerboardOffscreenLayers(bool checkerboard); + + /// Finishes building the scene. + /// + /// Returns a [Scene] containing the objects that have been added to + /// this scene builder. The [Scene] can then be displayed on the + /// screen with [FlutterView.render]. + /// + /// After calling this function, the scene builder object is invalid and + /// cannot be used further. + Scene build() { + final Scene scene = Scene._(); + _build(scene); + return scene; + } + + @FfiNative, Handle)>('SceneBuilder::build') + external void _build(Scene outScene); +} diff --git a/lib/ui/experiments/ui.dart b/lib/ui/experiments/ui.dart new file mode 100644 index 0000000000000..5d7b66eda19d3 --- /dev/null +++ b/lib/ui/experiments/ui.dart @@ -0,0 +1,42 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Built-in types and core primitives for a Flutter application. +/// +/// To use, import `dart:ui`. +/// +/// 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. +library dart.ui; + +import 'dart:async'; +import 'dart:collection' as collection; +import 'dart:convert'; +import 'dart:developer' as developer; +import 'dart:ffi'; +import 'dart:io'; +import 'dart:isolate' show SendPort; +import 'dart:math' as math; +import 'dart:nativewrappers'; +import 'dart:typed_data'; + +part '../annotations.dart'; +part '../channel_buffers.dart'; +part 'compositing_3d.dart'; +part '../geometry.dart'; +part '../hash_codes.dart'; +part '../hooks.dart'; +part '../isolate_name_server.dart'; +part '../key.dart'; +part '../lerp.dart'; +part '../math.dart'; +part '../natives.dart'; +part '../painting.dart'; +part '../platform_dispatcher.dart'; +part '../plugins.dart'; +part '../pointer.dart'; +part '../semantics.dart'; +part '../text.dart'; +part '../window.dart'; diff --git a/tools/gn b/tools/gn index 27f65988f53b3..863565e7bc131 100755 --- a/tools/gn +++ b/tools/gn @@ -551,6 +551,9 @@ def to_gn_args(args): elif os.getenv('FLUTTER_IMPELLER_ENABLE_PLAYGROUND', '0') == '1': gn_args['impeller_enable_playground'] = True + if args.enable_impeller_3d: + gn_args['impeller_enable_3d'] = True + if args.prebuilt_impellerc is not None: gn_args['impeller_use_prebuilt_impellerc'] = args.prebuilt_impellerc @@ -978,6 +981,13 @@ def parse_args(args): 'https://github.com/flutter/flutter/issues/107357' ) + parser.add_argument( + '--enable-impeller-3d', + default=False, + action='store_true', + help='Enables experimental 3d support.' + ) + # Sanitizers. parser.add_argument('--asan', default=False, action='store_true') parser.add_argument('--lsan', default=False, action='store_true') From f84a0d45353e0e54ed9309c3824e27aedb036cbf Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 14:04:45 -0800 Subject: [PATCH 2/8] ++ --- lib/ui/dart_ui.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index d2b6860048bbf..640e57f09f07e 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -295,7 +295,7 @@ typedef CanvasPath Path; V(Vertices, dispose, 1) #ifdef IMPELLER_ENABLE_3D -#define FFI_METHOD_LIST_3D(V)V(SceneBuilder, addModelLayer, 6) +#define FFI_METHOD_LIST_3D(V) V(SceneBuilder, addModelLayer, 6) #endif // IMPELLER_ENABLE_3D #define FFI_FUNCTION_INSERT(FUNCTION, ARGS) \ From 9252fec4f762570b6364d5675f2894cb9ceab6e3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 14:05:18 -0800 Subject: [PATCH 3/8] ++ --- lib/snapshot/BUILD.gn | 6 ++++-- lib/ui/dart_ui.gni | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index 8a195add5bebe..e83baa240bae8 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -316,9 +316,11 @@ compile_platform("strong_platform") { single_root_scheme = "org-dartlang-sdk" single_root_base = rebase_path("../../../") if (impeller_enable_3d) { - libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries_experimental.json" + libraries_specification_uri = + "org-dartlang-sdk:///flutter/lib/snapshot/libraries_experimental.json" } else { - libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" + libraries_specification_uri = + "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" } outputs = [ diff --git a/lib/ui/dart_ui.gni b/lib/ui/dart_ui.gni index af83a3ebf745e..6186b9987b01a 100644 --- a/lib/ui/dart_ui.gni +++ b/lib/ui/dart_ui.gni @@ -28,7 +28,6 @@ if (!impeller_enable_3d) { ] dart_ui_path = "//flutter/lib/ui/ui.dart" - } else { dart_ui_files = [ "//flutter/lib/ui/annotations.dart", @@ -53,5 +52,5 @@ if (!impeller_enable_3d) { "//flutter/lib/ui/experiments/compositing_3d.dart", ] - dart_ui_path = "//flutter/lib/ui/experiments/ui.dart" + dart_ui_path = "//flutter/lib/ui/experiments/ui.dart" } From aba6049f2c9ab4eefd648515b76c0603586cca6a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 14:19:17 -0800 Subject: [PATCH 4/8] ++ --- ci/licenses_golden/licenses_flutter | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index daa6e2755f882..a2b65ebf5f18b 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1649,6 +1649,7 @@ FILE: ../../../flutter/impeller/typographer/typographer_unittests.cc FILE: ../../../flutter/lib/io/dart_io.cc FILE: ../../../flutter/lib/io/dart_io.h FILE: ../../../flutter/lib/snapshot/libraries.json +FILE: ../../../flutter/lib/snapshot/libraries_experimental.json FILE: ../../../flutter/lib/snapshot/snapshot.h FILE: ../../../flutter/lib/ui/annotations.dart FILE: ../../../flutter/lib/ui/channel_buffers.dart @@ -1663,6 +1664,8 @@ FILE: ../../../flutter/lib/ui/dart_runtime_hooks.h FILE: ../../../flutter/lib/ui/dart_ui.cc FILE: ../../../flutter/lib/ui/dart_ui.h FILE: ../../../flutter/lib/ui/dart_wrapper.h +FILE: ../../../flutter/lib/ui/experiments/compositing_3d.dart +FILE: ../../../flutter/lib/ui/experiments/ui.dart FILE: ../../../flutter/lib/ui/geometry.dart FILE: ../../../flutter/lib/ui/hash_codes.dart FILE: ../../../flutter/lib/ui/hooks.dart From 543ef4b2de871e85cd17451a909b2bf0ad7a5792 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 15:11:50 -0800 Subject: [PATCH 5/8] ++ --- lib/ui/compositing.dart | 3 + lib/ui/dart_ui.gni | 73 +- lib/ui/experiments/compositing_3d.dart | 887 +------------------------ lib/ui/experiments/ui.dart | 1 + 4 files changed, 35 insertions(+), 929 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index b039e67ff1030..459630b74ce93 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -789,6 +789,9 @@ class SceneBuilder extends NativeFieldWrapperClass1 { @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); + @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addModelLayer', isLeaf: true) + external void _addModelLayer(double dx, double dy, double width, double height, int viewId); + /// Adds a platform view (e.g an iOS UIView) to the scene. /// /// On iOS this layer splits the current output surface into two surfaces, one for the scene nodes diff --git a/lib/ui/dart_ui.gni b/lib/ui/dart_ui.gni index 6186b9987b01a..7059f7ab2ae08 100644 --- a/lib/ui/dart_ui.gni +++ b/lib/ui/dart_ui.gni @@ -2,55 +2,26 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//flutter/impeller/tools/impeller.gni") +dart_ui_files = [ + "//flutter/lib/ui/annotations.dart", + "//flutter/lib/ui/channel_buffers.dart", + "//flutter/lib/ui/compositing.dart", + "//flutter/lib/ui/geometry.dart", + "//flutter/lib/ui/hash_codes.dart", + "//flutter/lib/ui/hooks.dart", + "//flutter/lib/ui/isolate_name_server.dart", + "//flutter/lib/ui/key.dart", + "//flutter/lib/ui/lerp.dart", + "//flutter/lib/ui/math.dart", + "//flutter/lib/ui/natives.dart", + "//flutter/lib/ui/painting.dart", + "//flutter/lib/ui/platform_dispatcher.dart", + "//flutter/lib/ui/plugins.dart", + "//flutter/lib/ui/pointer.dart", + "//flutter/lib/ui/semantics.dart", + "//flutter/lib/ui/text.dart", + "//flutter/lib/ui/ui.dart", + "//flutter/lib/ui/window.dart", +] -if (!impeller_enable_3d) { - dart_ui_files = [ - "//flutter/lib/ui/annotations.dart", - "//flutter/lib/ui/channel_buffers.dart", - "//flutter/lib/ui/compositing.dart", - "//flutter/lib/ui/geometry.dart", - "//flutter/lib/ui/hash_codes.dart", - "//flutter/lib/ui/hooks.dart", - "//flutter/lib/ui/isolate_name_server.dart", - "//flutter/lib/ui/key.dart", - "//flutter/lib/ui/lerp.dart", - "//flutter/lib/ui/math.dart", - "//flutter/lib/ui/natives.dart", - "//flutter/lib/ui/painting.dart", - "//flutter/lib/ui/platform_dispatcher.dart", - "//flutter/lib/ui/plugins.dart", - "//flutter/lib/ui/pointer.dart", - "//flutter/lib/ui/semantics.dart", - "//flutter/lib/ui/text.dart", - "//flutter/lib/ui/ui.dart", - "//flutter/lib/ui/window.dart", - ] - - dart_ui_path = "//flutter/lib/ui/ui.dart" -} else { - dart_ui_files = [ - "//flutter/lib/ui/annotations.dart", - "//flutter/lib/ui/channel_buffers.dart", - "//flutter/lib/ui/compositing.dart", - "//flutter/lib/ui/geometry.dart", - "//flutter/lib/ui/hash_codes.dart", - "//flutter/lib/ui/hooks.dart", - "//flutter/lib/ui/isolate_name_server.dart", - "//flutter/lib/ui/key.dart", - "//flutter/lib/ui/lerp.dart", - "//flutter/lib/ui/math.dart", - "//flutter/lib/ui/natives.dart", - "//flutter/lib/ui/painting.dart", - "//flutter/lib/ui/platform_dispatcher.dart", - "//flutter/lib/ui/plugins.dart", - "//flutter/lib/ui/pointer.dart", - "//flutter/lib/ui/semantics.dart", - "//flutter/lib/ui/text.dart", - "//flutter/lib/ui/window.dart", - "//flutter/lib/ui/experiments/ui.dart", - "//flutter/lib/ui/experiments/compositing_3d.dart", - ] - - dart_ui_path = "//flutter/lib/ui/experiments/ui.dart" -} +dart_ui_path = "//flutter/lib/ui/ui.dart" diff --git a/lib/ui/experiments/compositing_3d.dart b/lib/ui/experiments/compositing_3d.dart index 52ee6c0f033e5..12d6851af9022 100644 --- a/lib/ui/experiments/compositing_3d.dart +++ b/lib/ui/experiments/compositing_3d.dart @@ -3,882 +3,13 @@ // found in the LICENSE file. part of dart.ui; -/// An opaque object representing a composited scene. -/// -/// To create a Scene object, use a [SceneBuilder]. -/// -/// Scene objects can be displayed on the screen using the [FlutterView.render] -/// method. -@pragma('vm:entry-point') -class Scene extends NativeFieldWrapperClass1 { - /// This class is created by the engine, and should not be instantiated - /// or extended directly. - /// - /// To create a Scene object, use a [SceneBuilder]. - @pragma('vm:entry-point') - Scene._(); - - /// Synchronously creates a handle to an image from this scene. - /// - /// {@macro dart.ui.painting.Picture.toImageSync} - Image toImageSync(int width, int height) { - if (width <= 0 || height <= 0) { - throw Exception('Invalid image dimensions.'); - } - - final _Image image = _Image._(); - final String? result = _toImageSync(width, height, image); - if (result != null) { - throw PictureRasterizationException._(result); - } - return Image._(image, image.width, image.height); - } - - @FfiNative, Uint32, Uint32, Handle)>('Scene::toImageSync') - external String? _toImageSync(int width, int height, _Image outImage); - - /// Creates a raster image representation of the current state of the scene. - /// - /// This is a slow operation that is performed on a background thread. - /// - /// Callers must dispose the [Image] when they are done with it. If the result - /// will be shared with other methods or classes, [Image.clone] should be used - /// and each handle created must be disposed. - Future toImage(int width, int height) { - if (width <= 0 || height <= 0) { - throw Exception('Invalid image dimensions.'); - } - return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { - if (image == null) { - callback(null); - } else { - callback(Image._(image, image.width, image.height)); - } - }), - ); - } - - @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. - /// - /// 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. -// -// This is used to provide a typed API for engine layers to prevent -// incompatible layers from being passed to [SceneBuilder]'s push methods. -// For example, this prevents a layer returned from `pushOpacity` from being -// passed as `oldLayer` to `pushTransform`. This is achieved by having one -// concrete subclass of this class per push method. -abstract class _EngineLayerWrapper implements EngineLayer { - _EngineLayerWrapper._(EngineLayer nativeLayer) : _nativeLayer = nativeLayer; - - EngineLayer? _nativeLayer; - - @override - void dispose() { - assert(_nativeLayer != null, 'Object disposed'); - _nativeLayer!.dispose(); - assert(() { - _nativeLayer = null; - return true; - }()); - } - - // Children of this layer. - // - // Null if this layer has no children. This field is populated only in debug - // mode. - List<_EngineLayerWrapper>? _debugChildren; - - // Whether this layer was used as `oldLayer` in a past frame. - // - // It is illegal to use a layer object again after it is passed as an - // `oldLayer` argument. - bool _debugWasUsedAsOldLayer = false; - - bool _debugCheckNotUsedAsOldLayer() { - // The hashCode formatting should match shortHash in the framework - assert( - !_debugWasUsedAsOldLayer, - 'Layer $runtimeType#${hashCode.toUnsigned(20).toRadixString(16).padLeft(5, '0')} was previously used as oldLayer.\n' - 'Once a layer is used as oldLayer, it may not be used again. Instead, ' - 'after calling one of the SceneBuilder.push* methods and passing an oldLayer ' - 'to it, use the layer returned by the method as oldLayer in subsequent ' - 'frames.'); - return true; - } -} - -/// An opaque handle to a transform engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushTransform]. -/// -/// {@template dart.ui.sceneBuilder.oldLayerCompatibility} -/// `oldLayer` parameter in [SceneBuilder] methods only accepts objects created -/// by the engine. [SceneBuilder] will throw an [AssertionError] if you pass it -/// a custom implementation of this class. -/// {@endtemplate} -class TransformEngineLayer extends _EngineLayerWrapper { - TransformEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to an offset engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushOffset]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class OffsetEngineLayer extends _EngineLayerWrapper { - OffsetEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a clip rect engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushClipRect]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ClipRectEngineLayer extends _EngineLayerWrapper { - ClipRectEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a clip rounded rect engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushClipRRect]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ClipRRectEngineLayer extends _EngineLayerWrapper { - ClipRRectEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a clip path engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushClipPath]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ClipPathEngineLayer extends _EngineLayerWrapper { - ClipPathEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to an opacity engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushOpacity]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class OpacityEngineLayer extends _EngineLayerWrapper { - OpacityEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a color filter engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushColorFilter]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ColorFilterEngineLayer extends _EngineLayerWrapper { - ColorFilterEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to an image filter engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushImageFilter]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ImageFilterEngineLayer extends _EngineLayerWrapper { - ImageFilterEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a backdrop filter engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushBackdropFilter]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class BackdropFilterEngineLayer extends _EngineLayerWrapper { - BackdropFilterEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a shader mask engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushShaderMask]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class ShaderMaskEngineLayer extends _EngineLayerWrapper { - ShaderMaskEngineLayer._(super.nativeLayer) : super._(); -} - -/// An opaque handle to a physical shape engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushPhysicalShape]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class PhysicalShapeEngineLayer extends _EngineLayerWrapper { - PhysicalShapeEngineLayer._(super.nativeLayer) : super._(); -} - -/// Builds a [Scene] containing the given visuals. -/// -/// A [Scene] can then be rendered using [FlutterView.render]. -/// -/// To draw graphical operations onto a [Scene], first create a -/// [Picture] using a [PictureRecorder] and a [Canvas], and then add -/// it to the scene using [addPicture]. -class SceneBuilder extends NativeFieldWrapperClass1 { - /// Creates an empty [SceneBuilder] object. - @pragma('vm:entry-point') - SceneBuilder() { - _constructor(); - } - - @FfiNative('SceneBuilder::Create') - external void _constructor(); - - // Layers used in this scene. - // - // The key is the layer used. The value is the description of what the layer - // is used for, e.g. "pushOpacity" or "addRetained". - final Map _usedLayers = {}; - - // In debug mode checks that the `layer` is only used once in a given scene. - bool _debugCheckUsedOnce(EngineLayer layer, String usage) { - assert(() { - assert( - !_usedLayers.containsKey(layer), - 'Layer ${layer.runtimeType} already used.\n' - 'The layer is already being used as ${_usedLayers[layer]} in this scene.\n' - 'A layer may only be used once in a given scene.'); - - _usedLayers[layer] = usage; - return true; - }()); - - return true; - } - - bool _debugCheckCanBeUsedAsOldLayer(_EngineLayerWrapper? layer, String methodName) { - assert(() { - if (layer == null) { - return true; - } - assert(layer._nativeLayer != null, 'Object disposed'); - layer._debugCheckNotUsedAsOldLayer(); - assert(_debugCheckUsedOnce(layer, 'oldLayer in $methodName')); - layer._debugWasUsedAsOldLayer = true; - return true; - }()); - return true; - } - - final List<_EngineLayerWrapper> _layerStack = <_EngineLayerWrapper>[]; - - // Pushes the `newLayer` onto the `_layerStack` and adds it to the - // `_debugChildren` of the current layer in the stack, if any. - bool _debugPushLayer(_EngineLayerWrapper newLayer) { - assert(() { - if (_layerStack.isNotEmpty) { - final _EngineLayerWrapper currentLayer = _layerStack.last; - currentLayer._debugChildren ??= <_EngineLayerWrapper>[]; - currentLayer._debugChildren!.add(newLayer); - } - _layerStack.add(newLayer); - return true; - }()); - return true; - } - - /// Pushes a transform operation onto the operation stack. - /// - /// The objects are transformed by the given matrix before rasterization. - /// - /// {@template dart.ui.sceneBuilder.oldLayer} - /// If `oldLayer` is not null the engine will attempt to reuse the resources - /// allocated for the old layer when rendering the new layer. This is purely - /// an optimization. It has no effect on the correctness of rendering. - /// {@endtemplate} - /// - /// {@template dart.ui.sceneBuilder.oldLayerVsRetained} - /// Passing a layer to [addRetained] or as `oldLayer` argument to a push - /// method counts as _usage_. A layer can be used no more than once in a scene. - /// For example, it may not be passed simultaneously to two push methods, or - /// to a push method and to `addRetained`. - /// - /// When a layer is passed to [addRetained] all descendant layers are also - /// considered as used in this scene. The same single-usage restriction - /// applies to descendants. - /// - /// When a layer is passed as an `oldLayer` argument to a push method, it may - /// no longer be used in subsequent frames. If you would like to continue - /// reusing the resources associated with the layer, store the layer object - /// returned by the push method and use that in the next frame instead of the - /// original object. - /// {@endtemplate} - /// - /// See [pop] for details about the operation stack. - TransformEngineLayer pushTransform( - Float64List matrix4, { - TransformEngineLayer? oldLayer, - }) { - assert(_matrix4IsValid(matrix4)); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushTransform')); - final EngineLayer engineLayer = EngineLayer._(); - _pushTransform(engineLayer, matrix4, oldLayer?._nativeLayer); - final TransformEngineLayer layer = TransformEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @FfiNative, Handle, Handle, Handle)>('SceneBuilder::pushTransformHandle') - external void _pushTransform(EngineLayer layer, Float64List matrix4, EngineLayer? oldLayer); - - /// Pushes an offset operation onto the operation stack. - /// - /// This is equivalent to [pushTransform] with a matrix with only translation. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - OffsetEngineLayer pushOffset( - double dx, - double dy, { - OffsetEngineLayer? oldLayer, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushOffset')); - final EngineLayer engineLayer = EngineLayer._(); - _pushOffset(engineLayer, dx, dy, oldLayer?._nativeLayer); - final OffsetEngineLayer layer = OffsetEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// Rasterization outside the given rectangle is discarded. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack, and [Clip] for different clip modes. - /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). - ClipRectEngineLayer pushClipRect( - Rect rect, { - Clip clipBehavior = Clip.antiAlias, - ClipRectEngineLayer? oldLayer, - }) { - assert(clipBehavior != null); - assert(clipBehavior != Clip.none); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipRect')); - final EngineLayer engineLayer = EngineLayer._(); - _pushClipRect(engineLayer, rect.left, rect.right, rect.top, rect.bottom, clipBehavior.index, - oldLayer?._nativeLayer); - final ClipRectEngineLayer layer = ClipRectEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// Rasterization outside the given rounded rectangle is discarded. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack, and [Clip] for different clip modes. - /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). - ClipRRectEngineLayer pushClipRRect( - RRect rrect, { - Clip clipBehavior = Clip.antiAlias, - ClipRRectEngineLayer? oldLayer, - }) { - assert(clipBehavior != null); - assert(clipBehavior != Clip.none); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipRRect')); - final EngineLayer engineLayer = EngineLayer._(); - _pushClipRRect(engineLayer, rrect._getValue32(), clipBehavior.index, oldLayer?._nativeLayer); - final ClipRRectEngineLayer layer = ClipRRectEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// Rasterization outside the given path is discarded. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. See [Clip] for different clip modes. - /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). - ClipPathEngineLayer pushClipPath( - Path path, { - Clip clipBehavior = Clip.antiAlias, - ClipPathEngineLayer? oldLayer, - }) { - assert(clipBehavior != null); - assert(clipBehavior != Clip.none); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushClipPath')); - final EngineLayer engineLayer = EngineLayer._(); - _pushClipPath(engineLayer, path, clipBehavior.index, oldLayer?._nativeLayer); - final ClipPathEngineLayer layer = ClipPathEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// The given alpha value is blended into the alpha value of the objects' - /// rasterization. An alpha value of 0 makes the objects entirely invisible. - /// An alpha value of 255 has no effect (i.e., the objects retain the current - /// opacity). - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - OpacityEngineLayer pushOpacity( - int alpha, { - Offset? offset = Offset.zero, - OpacityEngineLayer? oldLayer, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushOpacity')); - final EngineLayer engineLayer = EngineLayer._(); - _pushOpacity(engineLayer, alpha, offset!.dx, offset.dy, oldLayer?._nativeLayer); - final OpacityEngineLayer layer = OpacityEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// The given color is applied to the objects' rasterization using the given - /// blend mode. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - ColorFilterEngineLayer pushColorFilter( - ColorFilter filter, { - ColorFilterEngineLayer? oldLayer, - }) { - assert(filter != null); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushColorFilter')); - final _ColorFilter nativeFilter = filter._toNativeColorFilter()!; - assert(nativeFilter != null); - final EngineLayer engineLayer = EngineLayer._(); - _pushColorFilter(engineLayer, nativeFilter, oldLayer?._nativeLayer); - final ColorFilterEngineLayer layer = ColorFilterEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @FfiNative, Handle, Pointer, Handle)>('SceneBuilder::pushColorFilter') - external void _pushColorFilter(EngineLayer layer, _ColorFilter filter, EngineLayer? oldLayer); - - /// Pushes an image filter operation onto the operation stack. - /// - /// The given filter is applied to the children's rasterization before compositing them into - /// the scene. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - ImageFilterEngineLayer pushImageFilter( - ImageFilter filter, { - Offset offset = Offset.zero, - ImageFilterEngineLayer? oldLayer, - }) { - assert(filter != null); - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushImageFilter')); - final _ImageFilter nativeFilter = filter._toNativeImageFilter(); - assert(nativeFilter != null); - final EngineLayer engineLayer = EngineLayer._(); - _pushImageFilter(engineLayer, nativeFilter, offset.dx, offset.dy, oldLayer?._nativeLayer); - final ImageFilterEngineLayer layer = ImageFilterEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @FfiNative, Handle, Pointer, Double, Double, Handle)>('SceneBuilder::pushImageFilter') - external void _pushImageFilter(EngineLayer outEngineLayer, _ImageFilter filter, double dx, double dy, EngineLayer? oldLayer); - - /// Pushes a backdrop filter operation onto the operation stack. - /// - /// The given filter is applied to the current contents of the scene as far back as - /// the most recent save layer and rendered back to the scene using the indicated - /// [blendMode] prior to rasterizing the child layers. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - BackdropFilterEngineLayer pushBackdropFilter( - ImageFilter filter, { - BlendMode blendMode = BlendMode.srcOver, - BackdropFilterEngineLayer? oldLayer, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushBackdropFilter')); - final EngineLayer engineLayer = EngineLayer._(); - _pushBackdropFilter(engineLayer, filter._toNativeImageFilter(), blendMode.index, oldLayer?._nativeLayer); - final BackdropFilterEngineLayer layer = BackdropFilterEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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. - /// - /// The given shader is applied to the object's rasterization in the given - /// rectangle using the given blend mode. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack. - ShaderMaskEngineLayer pushShaderMask( - Shader shader, - Rect maskRect, - BlendMode blendMode, { - ShaderMaskEngineLayer? oldLayer, - FilterQuality filterQuality = FilterQuality.low, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushShaderMask')); - final EngineLayer engineLayer = EngineLayer._(); - _pushShaderMask( - engineLayer, - shader, - maskRect.left, - maskRect.right, - maskRect.top, - maskRect.bottom, - blendMode.index, - filterQuality.index, - oldLayer?._nativeLayer, - ); - final ShaderMaskEngineLayer layer = ShaderMaskEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @FfiNative, Handle, Pointer, Double, Double, Double, Double, Int32, Int32, Handle)>( - 'SceneBuilder::pushShaderMask') - external void _pushShaderMask( - EngineLayer engineLayer, - Shader shader, - double maskRectLeft, - double maskRectRight, - double maskRectTop, - double maskRectBottom, - int blendMode, - int filterQualityIndex, - EngineLayer? oldLayer); - - /// Pushes a physical layer operation for an arbitrary shape onto the - /// operation stack. - /// - /// By default, the layer's content will not be clipped (clip = [Clip.none]). - /// If clip equals [Clip.hardEdge], [Clip.antiAlias], or [Clip.antiAliasWithSaveLayer], - /// then the content is clipped to the given shape defined by [path]. - /// - /// If [elevation] is greater than 0.0, then a shadow is drawn around the layer. - /// [shadowColor] defines the color of the shadow if present and [color] defines the - /// color of the layer background. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack, and [Clip] for different clip modes. - @Deprecated( - 'Use a clip and canvas operations directly (See RenderPhysicalModel). ' - 'This feature was deprecated after v3.1.0-0.0.pre.', - ) - PhysicalShapeEngineLayer pushPhysicalShape({ - required Path path, - required double elevation, - required Color color, - Color? shadowColor, - Clip clipBehavior = Clip.none, - PhysicalShapeEngineLayer? oldLayer, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushPhysicalShape')); - final EngineLayer engineLayer = EngineLayer._(); - _pushPhysicalShape(engineLayer, path, elevation, color.value, shadowColor?.value ?? 0xFF000000, - clipBehavior.index, oldLayer?._nativeLayer); - final PhysicalShapeEngineLayer layer = PhysicalShapeEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @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); - - /// Ends the effect of the most recently pushed operation. - /// - /// Internally the scene builder maintains a stack of operations. Each of the - /// operations in the stack applies to each of the objects added to the scene. - /// Calling this function removes the most recently added operation from the - /// stack. - void pop() { - if (_layerStack.isNotEmpty) { - _layerStack.removeLast(); - } - _pop(); - } - - @FfiNative)>('SceneBuilder::pop', isLeaf: true) - external void _pop(); - - /// Add a retained engine layer subtree from previous frames. - /// - /// All the engine layers that are in the subtree of the retained layer will - /// be automatically appended to the current engine layer tree. - /// - /// Therefore, when implementing a subclass of the [Layer] concept defined in - /// the rendering layer of Flutter's framework, once this is called, there's - /// no need to call [Layer.addToScene] for its children layers. - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - void addRetained(EngineLayer retainedLayer) { - assert(retainedLayer is _EngineLayerWrapper); - assert(() { - final _EngineLayerWrapper layer = retainedLayer as _EngineLayerWrapper; - - assert(layer._nativeLayer != null); - - void recursivelyCheckChildrenUsedOnce(_EngineLayerWrapper parentLayer) { - _debugCheckUsedOnce(parentLayer, 'retained layer'); - parentLayer._debugCheckNotUsedAsOldLayer(); - - final List<_EngineLayerWrapper>? children = parentLayer._debugChildren; - if (children == null || children.isEmpty) { - return; - } - children.forEach(recursivelyCheckChildrenUsedOnce); - } - - recursivelyCheckChildrenUsedOnce(layer); - - return true; - }()); - - final _EngineLayerWrapper wrapper = retainedLayer as _EngineLayerWrapper; - _addRetained(wrapper._nativeLayer!); - } - - @FfiNative, Handle)>('SceneBuilder::addRetained') - external void _addRetained(EngineLayer retainedLayer); - - /// Adds an object to the scene that displays performance statistics. - /// - /// Useful during development to assess the performance of the application. - /// The enabledOptions controls which statistics are displayed. The bounds - /// controls where the statistics are displayed. - /// - /// enabledOptions is a bit field with the following bits defined: - /// - 0x01: displayRasterizerStatistics - show raster thread frame time - /// - 0x02: visualizeRasterizerStatistics - graph raster thread frame times - /// - 0x04: displayEngineStatistics - show UI thread frame time - /// - 0x08: visualizeEngineStatistics - graph UI thread frame times - /// Set enabledOptions to 0x0F to enable all the currently defined features. - /// - /// The "UI thread" is the thread that includes all the execution of the main - /// Dart isolate (the isolate that can call [FlutterView.render]). The UI - /// thread frame time is the total time spent executing the - /// [PlatformDispatcher.onBeginFrame] callback. The "raster thread" is the - /// thread (running on the CPU) that subsequently processes the [Scene] - /// provided by the Dart code to turn it into GPU commands and send it to the - /// GPU. - /// - /// See also the [PerformanceOverlayOption] enum in the rendering library. - /// for more details. - // Values above must match constants in //engine/src/sky/compositor/performance_overlay_layer.h - void addPerformanceOverlay(int enabledOptions, Rect bounds) { - _addPerformanceOverlay(enabledOptions, bounds.left, bounds.right, bounds.top, bounds.bottom); - } - - @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. - /// - /// The picture is rasterized at the given offset. - void addPicture( - Offset offset, - Picture picture, { - bool isComplexHint = false, - bool willChangeHint = false, - }) { - assert(!picture.debugDisposed); - final int hints = (isComplexHint ? 1 : 0) | (willChangeHint ? 2 : 0); - _addPicture(offset.dx, offset.dy, picture, hints); - } - - @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. - /// - /// The texture is scaled to the given size and rasterized at the given offset. - /// - /// If `freeze` is true the texture that is added to the scene will not - /// be updated with new frames. `freeze` is used when resizing an embedded - /// Android view: When resizing an Android view there is a short period during - /// which the framework cannot tell if the newest texture frame has the - /// previous or new size, to workaround this the framework "freezes" the - /// texture just before resizing the Android view and un-freezes it when it is - /// certain that a frame with the new size is ready. - void addTexture( - int textureId, { - Offset offset = Offset.zero, - double width = 0.0, - double height = 0.0, - bool freeze = false, - FilterQuality filterQuality = FilterQuality.low, - }) { - assert(offset != null, 'Offset argument was null'); - _addTexture(offset.dx, offset.dy, width, height, textureId, freeze, filterQuality.index); - } - - @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. - /// - /// On iOS this layer splits the current output surface into two surfaces, one for the scene nodes - /// preceding the platform view, and one for the scene nodes following the platform view. - /// - /// ## Performance impact - /// - /// Adding an additional surface doubles the amount of graphics memory directly used by Flutter - /// for output buffers. Quartz might allocated extra buffers for compositing the Flutter surfaces - /// and the platform view. - /// - /// With a platform view in the scene, Quartz has to composite the two Flutter surfaces and the - /// embedded UIView. In addition to that, on iOS versions greater than 9, the Flutter frames are - /// synchronized with the UIView frames adding additional performance overhead. - /// - /// The `offset` argument is not used for iOS and Android. - void addPlatformView( - int viewId, { - Offset offset = Offset.zero, - double width = 0.0, - double height = 0.0, - }) { - assert(offset != null, 'Offset argument was null'); - _addPlatformView(offset.dx, offset.dy, width, height, viewId); - } - - @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addPlatformView', isLeaf: true) - external void _addPlatformView(double dx, double dy, double width, double height, int viewId); - - void addModelLayer( - int viewId, { - Offset offset = Offset.zero, - double width = 0.0, - double height = 0.0, - }) { - assert(offset != null, 'Offset argument was null'); - _addModelLayer(offset.dx, offset.dy, width, height, viewId); - } - - @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addModelLayer', isLeaf: true) - external void _addModelLayer(double dx, double dy, double width, double height, int viewId); - - /// Sets a threshold after which additional debugging information should be recorded. - /// - /// 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). - /// We'll hopefully be able to figure out how to make this feature more useful - /// to you. - @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. - /// - /// The compositor can sometimes decide to cache certain portions of the - /// widget hierarchy. Such portions typically don't change often from frame to - /// frame and are expensive to render. This can speed up overall rendering. However, - /// there is certain upfront cost to constructing these cache entries. And, if - /// the cache entries are not used very often, this cost may not be worth the - /// speedup in rendering of subsequent frames. If the developer wants to be certain - /// that populating the raster cache is not causing stutters, this option can be - /// set. Depending on the observations made, hints can be provided to the compositor - /// that aid it in making better decisions about caching. - /// - /// 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). - @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. - @FfiNative, Bool)>('SceneBuilder::setCheckerboardOffscreenLayers', isLeaf: true) - external void setCheckerboardOffscreenLayers(bool checkerboard); - - /// Finishes building the scene. - /// - /// Returns a [Scene] containing the objects that have been added to - /// this scene builder. The [Scene] can then be displayed on the - /// screen with [FlutterView.render]. - /// - /// After calling this function, the scene builder object is invalid and - /// cannot be used further. - Scene build() { - final Scene scene = Scene._(); - _build(scene); - return scene; - } - - @FfiNative, Handle)>('SceneBuilder::build') - external void _build(Scene outScene); +void addModelLayer( + SceneBuilder builder, + int viewId, { + Offset offset = Offset.zero, + double width = 0.0, + double height = 0.0, +}) { + assert(offset != null, 'Offset argument was null'); + builder._addModelLayer(offset.dx, offset.dy, width, height, viewId); } diff --git a/lib/ui/experiments/ui.dart b/lib/ui/experiments/ui.dart index 5d7b66eda19d3..e6ee89e1097d2 100644 --- a/lib/ui/experiments/ui.dart +++ b/lib/ui/experiments/ui.dart @@ -24,6 +24,7 @@ import 'dart:typed_data'; part '../annotations.dart'; part '../channel_buffers.dart'; +part '../compositing.dart'; part 'compositing_3d.dart'; part '../geometry.dart'; part '../hash_codes.dart'; From 3beb81d6962347b1b356915adb4e5635d6133bf3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 15:56:26 -0800 Subject: [PATCH 6/8] ++ --- lib/snapshot/BUILD.gn | 1 + lib/ui/compositing.dart | 3 --- lib/ui/compositing/scene_builder.cc | 4 +++- lib/ui/compositing/scene_builder.h | 18 +++++++++--------- lib/ui/dart_ui.cc | 4 ++-- lib/ui/experiments/compositing_3d.dart | 5 ++++- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index e83baa240bae8..2164a5740ff1e 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -6,6 +6,7 @@ import("//build/compiled_action.gni") import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") import("//flutter/lib/ui/dart_ui.gni") +import("//flutter/impeller/tools/impeller.gni") import("//third_party/dart/utils/compile_platform.gni") # Generates the Dart/Flutter core platform files and tools. diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index 459630b74ce93..b039e67ff1030 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -789,9 +789,6 @@ class SceneBuilder extends NativeFieldWrapperClass1 { @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); - @FfiNative, Double, Double, Double, Double, Int64)>('SceneBuilder::addModelLayer', isLeaf: true) - external void _addModelLayer(double dx, double dy, double width, double height, int viewId); - /// Adds a platform view (e.g an iOS UIView) to the scene. /// /// On iOS this layer splits the current output surface into two surfaces, one for the scene nodes diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 9c9aebf35c53d..0136c04bde895 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -263,7 +263,9 @@ void SceneBuilder::addTexture(double dx, } #ifdef IMPELLER_ENABLE_3D -void SceneBuilder::addModelLayer(double dx, +// static +void SceneBuilder::addModelLayer(Dart_Handle wrapper, + double dx, double dy, double width, double height, diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h index 02953e02b9159..04d350236dabb 100644 --- a/lib/ui/compositing/scene_builder.h +++ b/lib/ui/compositing/scene_builder.h @@ -34,6 +34,15 @@ class SceneBuilder : public RefCountedDartWrappable { res->AssociateWithDartWrapper(wrapper); } +#ifdef IMPELLER_ENABLE_3D + static void addModelLayer(Dart_Handle wrapper, + double dx, + double dy, + double width, + double height, + int64_t viewId); +#endif // IMPELLER_ENABLE_3D + ~SceneBuilder() override; void pushTransformHandle(Dart_Handle layer_handle, @@ -118,15 +127,6 @@ class SceneBuilder : public RefCountedDartWrappable { bool freeze, int filterQuality); -#ifdef IMPELLER_ENABLE_3D - void addModelLayer(double dx, - double dy, - double width, - double height, - int64_t viewId); - -#endif // IMPELLER_ENABLE_3D - void addPlatformView(double dx, double dy, double width, diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 640e57f09f07e..4d1a6bca3ac0d 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -295,7 +295,7 @@ typedef CanvasPath Path; V(Vertices, dispose, 1) #ifdef IMPELLER_ENABLE_3D -#define FFI_METHOD_LIST_3D(V) V(SceneBuilder, addModelLayer, 6) +#define FFI_METHOD_LIST_3D(V) V(SceneBuilder::addModelLayer, 7) #endif // IMPELLER_ENABLE_3D #define FFI_FUNCTION_INSERT(FUNCTION, ARGS) \ @@ -325,7 +325,7 @@ void InitDispatcherMap() { FFI_FUNCTION_LIST(FFI_FUNCTION_INSERT) FFI_METHOD_LIST(FFI_METHOD_INSERT) #ifdef IMPELLER_ENABLE_3D - FFI_METHOD_LIST_3D(FFI_METHOD_INSERT) + FFI_METHOD_LIST_3D(FFI_FUNCTION_INSERT) #endif // IMPELLER_ENABLE_3D } diff --git a/lib/ui/experiments/compositing_3d.dart b/lib/ui/experiments/compositing_3d.dart index 12d6851af9022..3fce6a31e7844 100644 --- a/lib/ui/experiments/compositing_3d.dart +++ b/lib/ui/experiments/compositing_3d.dart @@ -11,5 +11,8 @@ void addModelLayer( double height = 0.0, }) { assert(offset != null, 'Offset argument was null'); - builder._addModelLayer(offset.dx, offset.dy, width, height, viewId); + _addModelLayer(builder, offset.dx, offset.dy, width, height, viewId); } + +@FfiNative('SceneBuilder::addModelLayer') +external void _addModelLayer(Object object, double dx, double dy, double width, double height, int viewId); From eb102d6a6fb35989663c7707a4234d429eb52047 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 15:57:10 -0800 Subject: [PATCH 7/8] ++ --- lib/snapshot/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index 2164a5740ff1e..98bee65ef8d1d 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -5,8 +5,8 @@ import("//build/compiled_action.gni") import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") -import("//flutter/lib/ui/dart_ui.gni") import("//flutter/impeller/tools/impeller.gni") +import("//flutter/lib/ui/dart_ui.gni") import("//third_party/dart/utils/compile_platform.gni") # Generates the Dart/Flutter core platform files and tools. From 710f33cd20ad86177099633fbcfc189025268d3c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 30 Nov 2022 16:02:32 -0800 Subject: [PATCH 8/8] ++ --- lib/ui/compositing/scene_builder.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 0136c04bde895..deba7695f4fb7 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -270,7 +270,10 @@ void SceneBuilder::addModelLayer(Dart_Handle wrapper, double width, double height, int64_t viewId) { - // NO-OP. + auto* scene_builder = tonic::DartConverter::FromDart(wrapper); + SkMatrix sk_matrix = SkMatrix::Translate(dx, dy); + auto layer = std::make_shared(sk_matrix); + scene_builder->AddLayer(std::move(layer)); } #endif // IMPELLER_ENABLE_3D