diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index d3cf0bf9c8179007aaef858b40896912b0352967..6b1c9390ee5f6acd547446616c9f42e99aecf25b 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -561,6 +561,8 @@ TYPE: LicenseType.bsd FILE: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart FILE: ../../../flutter/fml/paths_unittests.cc FILE: ../../../flutter/lib/ui/isolate_name_server.dart +FILE: ../../../flutter/lib/ui/painting/engine_layer.cc +FILE: ../../../flutter/lib/ui/painting/engine_layer.h FILE: ../../../flutter/lib/ui/painting/image_encoding.cc FILE: ../../../flutter/lib/ui/painting/image_encoding.h FILE: ../../../flutter/lib/ui/plugins.dart diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index f398c96ad1afe5504592f2f95569750ceb05b625..01ced5fd6a8aa5cf13ba09f5c0ec38ae98931863 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -10,7 +10,7 @@ ContainerLayer::ContainerLayer() {} ContainerLayer::~ContainerLayer() = default; -void ContainerLayer::Add(std::unique_ptr layer) { +void ContainerLayer::Add(std::shared_ptr layer) { layer->set_parent(this); layers_.push_back(std::move(layer)); } diff --git a/flow/layers/container_layer.h b/flow/layers/container_layer.h index 0da0a7185963ed9df3dbae97ad08c88be23817e3..aa73bb9d59c4acb02438e7887698bf99e150c834 100644 --- a/flow/layers/container_layer.h +++ b/flow/layers/container_layer.h @@ -15,7 +15,7 @@ class ContainerLayer : public Layer { ContainerLayer(); ~ContainerLayer() override; - void Add(std::unique_ptr layer); + void Add(std::shared_ptr layer); void Preroll(PrerollContext* context, const SkMatrix& matrix) override; @@ -23,7 +23,7 @@ class ContainerLayer : public Layer { void UpdateScene(SceneUpdateContext& context) override; #endif // defined(OS_FUCHSIA) - const std::vector>& layers() const { return layers_; } + const std::vector>& layers() const { return layers_; } protected: void PrerollChildren(PrerollContext* context, @@ -36,7 +36,7 @@ class ContainerLayer : public Layer { #endif // defined(OS_FUCHSIA) private: - std::vector> layers_; + std::vector> layers_; FML_DISALLOW_COPY_AND_ASSIGN(ContainerLayer); }; diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index a146a3520f60943d568b839327b98913e889b411..e8591b49661c74c21eae26729eae165f42fc9c26 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -39,7 +39,7 @@ class LayerTree { Layer* root_layer() const { return root_layer_.get(); } - void set_root_layer(std::unique_ptr root_layer) { + void set_root_layer(std::shared_ptr root_layer) { root_layer_ = std::move(root_layer); } @@ -74,7 +74,7 @@ class LayerTree { private: SkISize frame_size_; // Physical pixels. - std::unique_ptr root_layer_; + std::shared_ptr root_layer_; fml::TimeDelta construction_time_; uint32_t rasterizer_tracing_threshold_; bool checkerboard_raster_cache_images_; diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index cfb8461b196151cc9ea6da57116d7a277f2d2d8b..28791a35af6191d59fc16a5b5eb759b067665696 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -23,6 +23,8 @@ source_set("ui") { "painting/canvas.h", "painting/codec.cc", "painting/codec.h", + "painting/engine_layer.h", + "painting/engine_layer.cc", "painting/frame_info.cc", "painting/frame_info.h", "painting/gradient.cc", diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index 1e2af68025d6e60da4cc5ee99762cf52b87c4fe8..f2e5fb049cd7eccfceac6e92994a7d6d21b7bb6b 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -69,7 +69,7 @@ class SceneBuilder extends NativeFieldWrapperClass2 { /// This is equivalent to [pushTransform] with a matrix with only translation. /// /// See [pop] for details about the operation stack. - void pushOffset(double dx, double dy) native 'SceneBuilder_pushOffset'; + EngineLayer pushOffset(double dx, double dy) native 'SceneBuilder_pushOffset'; /// Pushes a rectangular clip operation onto the operation stack. /// @@ -177,10 +177,10 @@ class SceneBuilder extends NativeFieldWrapperClass2 { /// /// See [pop] for details about the operation stack, and [Clip] for different clip modes. // ignore: deprecated_member_use - void pushPhysicalShape({ Path path, double elevation, Color color, Color shadowColor, Clip clipBehavior = defaultClipBehavior}) { - _pushPhysicalShape(path, elevation, color.value, shadowColor?.value ?? 0xFF000000, clipBehavior.index); + EngineLayer pushPhysicalShape({ Path path, double elevation, Color color, Color shadowColor, Clip clipBehavior = defaultClipBehavior}) { + return _pushPhysicalShape(path, elevation, color.value, shadowColor?.value ?? 0xFF000000, clipBehavior.index); } - void _pushPhysicalShape(Path path, double elevation, int color, int shadowColor, int clipBehavior) native + EngineLayer _pushPhysicalShape(Path path, double elevation, int color, int shadowColor, int clipBehavior) native 'SceneBuilder_pushPhysicalShape'; /// Ends the effect of the most recently pushed operation. @@ -191,6 +191,16 @@ class SceneBuilder extends NativeFieldWrapperClass2 { /// stack. void pop() native 'SceneBuilder_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 subclas of the [Layer] concept defined in + /// the rendering layer of Flutter's framework, once this is called, there's + /// no need to call [addToScene] for its children layers. + EngineLayer addRetained(EngineLayer retainedLayer) native 'SceneBuilder_addRetained'; + /// Adds an object to the scene that displays performance statistics. /// /// Useful during development to assess the performance of the application. diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 2863f5307ad40979e526a53fa86c092cb334996a..735ce4419792155ce225f7ddad2973c0a6bde5ec 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -26,7 +26,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); DART_BIND_ALL(Scene, FOR_EACH_BINDING) -fml::RefPtr Scene::create(std::unique_ptr rootLayer, +fml::RefPtr Scene::create(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { @@ -35,7 +35,7 @@ fml::RefPtr Scene::create(std::unique_ptr rootLayer, checkerboardRasterCacheImages, checkerboardOffscreenLayers); } -Scene::Scene(std::unique_ptr rootLayer, +Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 09f6a3e0d833021e416cbf64cdc00e8f94b15623..bf1f1b78d826e953ef45ad454e0e387d967a9165 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -24,7 +24,7 @@ class Scene : public RefCountedDartWrappable { public: ~Scene() override; - static fml::RefPtr create(std::unique_ptr rootLayer, + static fml::RefPtr create(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); @@ -40,7 +40,7 @@ class Scene : public RefCountedDartWrappable { static void RegisterNatives(tonic::DartLibraryNatives* natives); private: - explicit Scene(std::unique_ptr rootLayer, + explicit Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 439821cf1491e90c93de9d766da24972d47bff4e..98888d77ad1fd0a4c7b5080327497f6d1356ab4a 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -53,6 +53,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder); V(SceneBuilder, pushShaderMask) \ V(SceneBuilder, pushPhysicalShape) \ V(SceneBuilder, pop) \ + V(SceneBuilder, addRetained) \ V(SceneBuilder, addPicture) \ V(SceneBuilder, addTexture) \ V(SceneBuilder, addChildScene) \ @@ -80,11 +81,12 @@ void SceneBuilder::pushTransform(const tonic::Float64List& matrix4) { PushLayer(std::move(layer)); } -void SceneBuilder::pushOffset(double dx, double dy) { +fml::RefPtr SceneBuilder::pushOffset(double dx, double dy) { SkMatrix sk_matrix = SkMatrix::MakeTrans(dx, dy); - auto layer = std::make_unique(); + auto layer = std::make_shared(); layer->set_transform(sk_matrix); - PushLayer(std::move(layer)); + PushLayer(layer); + return EngineLayer::MakeRetained(layer); } void SceneBuilder::pushClipRect(double left, @@ -148,21 +150,29 @@ void SceneBuilder::pushShaderMask(Shader* shader, PushLayer(std::move(layer)); } -void SceneBuilder::pushPhysicalShape(const CanvasPath* path, - double elevation, - int color, - int shadow_color, - int clipBehavior) { +fml::RefPtr SceneBuilder::pushPhysicalShape(const CanvasPath* path, + double elevation, + int color, + int shadow_color, + int clipBehavior) { const SkPath& sk_path = path->path(); flow::Clip clip_behavior = static_cast(clipBehavior); - auto layer = std::make_unique(clip_behavior); + auto layer = std::make_shared(clip_behavior); layer->set_path(sk_path); layer->set_elevation(elevation); layer->set_color(static_cast(color)); layer->set_shadow_color(static_cast(shadow_color)); layer->set_device_pixel_ratio( UIDartState::Current()->window()->viewport_metrics().device_pixel_ratio); - PushLayer(std::move(layer)); + PushLayer(layer); + return EngineLayer::MakeRetained(layer); +} + +void SceneBuilder::addRetained(fml::RefPtr retainedLayer) { + if (!current_layer_) { + return; + } + current_layer_->Add(retainedLayer->Layer()); } void SceneBuilder::pop() { @@ -260,7 +270,7 @@ fml::RefPtr SceneBuilder::build() { return scene; } -void SceneBuilder::PushLayer(std::unique_ptr layer) { +void SceneBuilder::PushLayer(std::shared_ptr layer) { FML_DCHECK(layer); if (!root_layer_) { diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h index 8e3ed13a411a3cd0d8b424730c02ea2839fb6d5c..e8638e6aee3bfaa6cd9df1798f30167717d3a2a5 100644 --- a/lib/ui/compositing/scene_builder.h +++ b/lib/ui/compositing/scene_builder.h @@ -12,6 +12,7 @@ #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/compositing/scene_host.h" #include "flutter/lib/ui/dart_wrapper.h" +#include "flutter/lib/ui/painting/engine_layer.h" #include "flutter/lib/ui/painting/image_filter.h" #include "flutter/lib/ui/painting/path.h" #include "flutter/lib/ui/painting/picture.h" @@ -33,7 +34,7 @@ class SceneBuilder : public RefCountedDartWrappable { ~SceneBuilder() override; void pushTransform(const tonic::Float64List& matrix4); - void pushOffset(double dx, double dy); + fml::RefPtr pushOffset(double dx, double dy); void pushClipRect(double left, double right, double top, @@ -50,11 +51,13 @@ class SceneBuilder : public RefCountedDartWrappable { double maskRectTop, double maskRectBottom, int blendMode); - void pushPhysicalShape(const CanvasPath* path, - double elevation, - int color, - int shadowColor, - int clipBehavior); + fml::RefPtr pushPhysicalShape(const CanvasPath* path, + double elevation, + int color, + int shadowColor, + int clipBehavior); + + void addRetained(fml::RefPtr retainedLayer); void pop(); @@ -92,14 +95,14 @@ class SceneBuilder : public RefCountedDartWrappable { private: SceneBuilder(); - std::unique_ptr root_layer_; + std::shared_ptr root_layer_; flow::ContainerLayer* current_layer_ = nullptr; int rasterizer_tracing_threshold_ = 0; bool checkerboard_raster_cache_images_ = false; bool checkerboard_offscreen_layers_ = false; - void PushLayer(std::unique_ptr layer); + void PushLayer(std::shared_ptr layer); FML_DISALLOW_COPY_AND_ASSIGN(SceneBuilder); }; diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 0fc867834c8a9ff73050ba7e84c2559d01389b38..d5c923031a92285b4a15ef01a3060f244bccfc36 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -11,6 +11,7 @@ #include "flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h" #include "flutter/lib/ui/painting/canvas.h" #include "flutter/lib/ui/painting/codec.h" +#include "flutter/lib/ui/painting/engine_layer.h" #include "flutter/lib/ui/painting/frame_info.h" #include "flutter/lib/ui/painting/gradient.h" #include "flutter/lib/ui/painting/image.h" @@ -70,6 +71,7 @@ void DartUI::InitForGlobal() { CanvasPathMeasure::RegisterNatives(g_natives); Codec::RegisterNatives(g_natives); DartRuntimeHooks::RegisterNatives(g_natives); + EngineLayer::RegisterNatives(g_natives); FrameInfo::RegisterNatives(g_natives); ImageFilter::RegisterNatives(g_natives); ImageShader::RegisterNatives(g_natives); diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 5844565bbf3465345da8e4c79d89276f9b30881e..92e6dfda92807a935996651792ddc056c3642bc0 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -1761,6 +1761,14 @@ enum PathOperation { reverseDifference, } +/// A handle for the framework to hold and retain an engine layer across frames. +class EngineLayer extends NativeFieldWrapperClass2 { + /// This class is created by the engine, and should not be instantiated + /// or extended directly. + @pragma('vm:entry-point') + EngineLayer._(); +} + /// A complex, one-dimensional subset of a plane. /// /// A path consists of a number of subpaths, and a _current point_. diff --git a/lib/ui/painting/engine_layer.cc b/lib/ui/painting/engine_layer.cc new file mode 100644 index 0000000000000000000000000000000000000000..5ff6e96f615742f32b16e57bd11759d3a33c6b61 --- /dev/null +++ b/lib/ui/painting/engine_layer.cc @@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/lib/ui/painting/engine_layer.h" + +#include "flutter/flow/layers/container_layer.h" + +#include "third_party/tonic/converter/dart_converter.h" +#include "third_party/tonic/dart_args.h" +#include "third_party/tonic/dart_binding_macros.h" +#include "third_party/tonic/dart_library_natives.h" + +using tonic::ToDart; + +namespace blink { + +EngineLayer::~EngineLayer() = default; + +IMPLEMENT_WRAPPERTYPEINFO(ui, EngineLayer); + +#define FOR_EACH_BINDING(V) // nothing to bind + +DART_BIND_ALL(EngineLayer, FOR_EACH_BINDING) + +} // namespace blink diff --git a/lib/ui/painting/engine_layer.h b/lib/ui/painting/engine_layer.h new file mode 100644 index 0000000000000000000000000000000000000000..e79b5f8e639674d4c9ce2e0d422f1c46f8670ea4 --- /dev/null +++ b/lib/ui/painting/engine_layer.h @@ -0,0 +1,44 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_LIB_UI_PAINTING_ENGINE_LAYER_H_ +#define FLUTTER_LIB_UI_PAINTING_ENGINE_LAYER_H_ + +#include "flutter/lib/ui/dart_wrapper.h" + +#include "flutter/flow/layers/layer.h" + +namespace tonic { +class DartLibraryNatives; +} // namespace tonic + +namespace blink { + +class EngineLayer; + +class EngineLayer : public RefCountedDartWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + ~EngineLayer() override; + static fml::RefPtr MakeRetained( + std::shared_ptr layer) { + return fml::MakeRefCounted(layer); + } + + static void RegisterNatives(tonic::DartLibraryNatives* natives); + + std::shared_ptr Layer() const { return layer_; } + + private: + explicit EngineLayer(std::shared_ptr layer) + : layer_(layer) {} + std::shared_ptr layer_; + + FML_FRIEND_MAKE_REF_COUNTED(EngineLayer); +}; + +} // namespace blink + +#endif // FLUTTER_LIB_UI_PAINTING_ENGINE_LAYER_H_