diff --git a/flow/layers/child_scene_layer.cc b/flow/layers/child_scene_layer.cc index 795946e0855c9..2a51590ff785c 100644 --- a/flow/layers/child_scene_layer.cc +++ b/flow/layers/child_scene_layer.cc @@ -4,8 +4,6 @@ #include "flutter/flow/layers/child_scene_layer.h" -#include "flutter/flow/view_holder.h" - namespace flutter { ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id, @@ -19,11 +17,9 @@ ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id, void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { TRACE_EVENT0("flutter", "ChildSceneLayer::Preroll"); - set_needs_system_composite(true); - - CheckForChildLayerBelow(context); context->child_scene_layer_exists_below = true; + CheckForChildLayerBelow(context); // An alpha "hole punch" is required if the frame behind us is not opaque. if (!context->is_opaque) { @@ -49,15 +45,7 @@ void ChildSceneLayer::Paint(PaintContext& context) const { void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) { TRACE_EVENT0("flutter", "ChildSceneLayer::UpdateScene"); FML_DCHECK(needs_system_composite()); - - Layer::UpdateScene(context); - - auto* view_holder = ViewHolder::FromId(layer_id_); - FML_DCHECK(view_holder); - - view_holder->UpdateScene(context, offset_, size_, - SkScalarRoundToInt(context.alphaf() * 255), - hit_testable_); + context.UpdateView(layer_id_, offset_, size_, hit_testable_); } } // namespace flutter diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index d8bf8ed13a1b4..825826b70835f 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -4,6 +4,8 @@ #include "flutter/flow/layers/container_layer.h" +#include + namespace flutter { ContainerLayer::ContainerLayer() {} @@ -30,6 +32,9 @@ void ContainerLayer::PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, SkRect* child_paint_bounds) { #if defined(LEGACY_FUCHSIA_EMBEDDER) + // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), + // Layers that appear above the embedded content will be turned into their own + // Scenic layers. child_layer_exists_below_ = context->child_scene_layer_exists_below; context->child_scene_layer_exists_below = false; #endif @@ -98,63 +103,20 @@ void ContainerLayer::UpdateScene(SceneUpdateContext& context) { } void ContainerLayer::UpdateSceneChildren(SceneUpdateContext& context) { - auto update_scene_layers = [&] { - // Paint all of the layers which need to be drawn into the container. - // These may be flattened down to a containing Scenic Frame. - for (auto& layer : layers_) { - if (layer->needs_system_composite()) { - layer->UpdateScene(context); - } - } - }; - FML_DCHECK(needs_system_composite()); - // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), - // PhysicalShapeLayers that appear above the embedded content will be turned - // into their own Scenic layers. + std::optional frame; if (child_layer_exists_below_) { - float global_scenic_elevation = - context.GetGlobalElevationForNextScenicLayer(); - float local_scenic_elevation = - global_scenic_elevation - context.scenic_elevation(); - float z_translation = -local_scenic_elevation; - - // Retained rendering: speedup by reusing a retained entity node if - // possible. When an entity node is reused, no paint layer is added to the - // frame so we won't call PhysicalShapeLayer::Paint. - LayerRasterCacheKey key(unique_id(), context.Matrix()); - if (context.HasRetainedNode(key)) { - TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit"); - scenic::EntityNode* retained_node = context.GetRetainedNode(key); - FML_DCHECK(context.top_entity()); - FML_DCHECK(retained_node->session() == context.session()); - - // Re-adjust the elevation. - retained_node->SetTranslation(0.f, 0.f, z_translation); - - context.top_entity()->entity_node().AddChild(*retained_node); - return; - } - - TRACE_EVENT_INSTANT0("flutter", "cache miss, creating"); - // If we can't find an existing retained surface, create one. - SceneUpdateContext::Frame frame( + frame.emplace( context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT, - SkScalarRoundToInt(context.alphaf() * 255), - "flutter::PhysicalShapeLayer", z_translation, this); - - frame.AddPaintLayer(this); - - // Node: UpdateSceneChildren needs to be called here so that |frame| is - // still in scope (and therefore alive) while UpdateSceneChildren is being - // called. - float scenic_elevation = context.scenic_elevation(); - context.set_scenic_elevation(scenic_elevation + local_scenic_elevation); - update_scene_layers(); - context.set_scenic_elevation(scenic_elevation); - } else { - update_scene_layers(); + SkScalarRoundToInt(context.alphaf() * 255), "flutter::ContainerLayer"); + frame->AddPaintLayer(this); + } + + for (auto& layer : layers_) { + if (layer->needs_system_composite()) { + layer->UpdateScene(context); + } } } diff --git a/flow/layers/fuchsia_layer_unittests.cc b/flow/layers/fuchsia_layer_unittests.cc index b1e7d2be05500..fcc17c0ad06e4 100644 --- a/flow/layers/fuchsia_layer_unittests.cc +++ b/flow/layers/fuchsia_layer_unittests.cc @@ -238,57 +238,17 @@ class MockSession : public fuchsia::ui::scenic::testing::Session_TestBase { fuchsia::ui::scenic::SessionListenerPtr listener_; }; -class MockSurfaceProducerSurface - : public SceneUpdateContext::SurfaceProducerSurface { +class MockSessionWrapper : public flutter::SessionWrapper { public: - MockSurfaceProducerSurface(scenic::Session* session, const SkISize& size) - : image_(session, 0, 0, {}), size_(size) {} + MockSessionWrapper(fuchsia::ui::scenic::SessionPtr session_ptr) + : session_(std::move(session_ptr)) {} + ~MockSessionWrapper() override = default; - size_t AdvanceAndGetAge() override { return 0; } - - bool FlushSessionAcquireAndReleaseEvents() override { return false; } - - bool IsValid() const override { return false; } - - SkISize GetSize() const override { return size_; } - - void SignalWritesFinished( - const std::function& on_writes_committed) override {} - - scenic::Image* GetImage() override { return &image_; }; - - sk_sp GetSkiaSurface() const override { return nullptr; }; + scenic::Session* get() override { return &session_; } + void Present() override { session_.Flush(); } private: - scenic::Image image_; - SkISize size_; -}; - -class MockSurfaceProducer : public SceneUpdateContext::SurfaceProducer { - public: - MockSurfaceProducer(scenic::Session* session) : session_(session) {} - std::unique_ptr ProduceSurface( - const SkISize& size, - const LayerRasterCacheKey& layer_key, - std::unique_ptr entity_node) override { - return std::make_unique(session_, size); - } - - // Query a retained entity node (owned by a retained surface) for retained - // rendering. - bool HasRetainedNode(const LayerRasterCacheKey& key) const override { - return false; - } - - scenic::EntityNode* GetRetainedNode(const LayerRasterCacheKey& key) override { - return nullptr; - } - - void SubmitSurface(std::unique_ptr - surface) override {} - - private: - scenic::Session* session_; + scenic::Session session_; }; struct TestContext { @@ -297,12 +257,11 @@ struct TestContext { fml::RefPtr task_runner; // Session. - MockSession mock_session; fidl::InterfaceRequest listener_request; - std::unique_ptr session; + MockSession mock_session; + std::unique_ptr mock_session_wrapper; // SceneUpdateContext. - std::unique_ptr mock_surface_producer; std::unique_ptr scene_update_context; // PrerollContext. @@ -324,15 +283,13 @@ std::unique_ptr InitTest() { fuchsia::ui::scenic::SessionListenerPtr listener; context->listener_request = listener.NewRequest(); context->mock_session.Bind(session_ptr.NewRequest(), std::move(listener)); - context->session = std::make_unique(std::move(session_ptr)); + context->mock_session_wrapper = + std::make_unique(std::move(session_ptr)); // Init SceneUpdateContext. - context->mock_surface_producer = - std::make_unique(context->session.get()); context->scene_update_context = std::make_unique( - context->session.get(), context->mock_surface_producer.get()); - context->scene_update_context->set_metrics( - fidl::MakeOptional(fuchsia::ui::gfx::Metrics{1.f, 1.f, 1.f})); + "fuchsia_layer_unittest", fuchsia::ui::views::ViewToken(), + scenic::ViewRefPair::New(), *(context->mock_session_wrapper)); // Init PrerollContext. context->preroll_context = std::unique_ptr(new PrerollContext{ @@ -348,7 +305,6 @@ std::unique_ptr InitTest() { context->unused_texture_registry, // texture registry (not // supported) false, // checkerboard_offscreen_layers - 100.f, // maximum depth allowed for rendering 1.f // ratio between logical and physical }); @@ -602,7 +558,7 @@ TEST_F(FuchsiaLayerTest, DISABLED_PhysicalShapeLayersAndChildSceneLayers) { // against the list above. root->UpdateScene(*(test_context->scene_update_context)); - test_context->session->Flush(); + test_context->mock_session_wrapper->Present(); // Run loop until idle, so that the Session receives and processes // its method calls. @@ -784,7 +740,7 @@ TEST_F(FuchsiaLayerTest, DISABLED_OpacityAndTransformLayer) { // commands against the list above. root->UpdateScene(*(test_context->scene_update_context)); - test_context->session->Flush(); + test_context->mock_session_wrapper->Present(); // Run loop until idle, so that the Session receives and processes // its method calls. diff --git a/flow/layers/layer.cc b/flow/layers/layer.cc index 97da04f7f54c8..a242f977cde29 100644 --- a/flow/layers/layer.cc +++ b/flow/layers/layer.cc @@ -58,6 +58,9 @@ Layer::AutoPrerollSaveLayerState::~AutoPrerollSaveLayerState() { #if defined(LEGACY_FUCHSIA_EMBEDDER) void Layer::CheckForChildLayerBelow(PrerollContext* context) { + // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), + // PhysicalShapeLayers that appear above the embedded content will be turned + // into their own Scenic layers. child_layer_exists_below_ = context->child_scene_layer_exists_below; if (child_layer_exists_below_) { set_needs_system_composite(true); @@ -65,42 +68,14 @@ void Layer::CheckForChildLayerBelow(PrerollContext* context) { } void Layer::UpdateScene(SceneUpdateContext& context) { - // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), - // PhysicalShapeLayers that appear above the embedded content will be turned - // into their own Scenic layers. - if (child_layer_exists_below_) { - float global_scenic_elevation = - context.GetGlobalElevationForNextScenicLayer(); - float local_scenic_elevation = - global_scenic_elevation - context.scenic_elevation(); - float z_translation = -local_scenic_elevation; - - // Retained rendering: speedup by reusing a retained entity node if - // possible. When an entity node is reused, no paint layer is added to the - // frame so we won't call PhysicalShapeLayer::Paint. - LayerRasterCacheKey key(unique_id(), context.Matrix()); - if (context.HasRetainedNode(key)) { - TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit"); - scenic::EntityNode* retained_node = context.GetRetainedNode(key); - FML_DCHECK(context.top_entity()); - FML_DCHECK(retained_node->session() == context.session()); - - // Re-adjust the elevation. - retained_node->SetTranslation(0.f, 0.f, z_translation); - - context.top_entity()->entity_node().AddChild(*retained_node); - return; - } - - TRACE_EVENT_INSTANT0("flutter", "cache miss, creating"); - // If we can't find an existing retained surface, create one. - SceneUpdateContext::Frame frame( - context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT, - SkScalarRoundToInt(context.alphaf() * 255), - "flutter::PhysicalShapeLayer", z_translation, this); - - frame.AddPaintLayer(this); - } + FML_DCHECK(needs_system_composite()); + FML_DCHECK(child_layer_exists_below_); + + SceneUpdateContext::Frame frame( + context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT, + SkScalarRoundToInt(context.alphaf() * 255), "flutter::Layer"); + + frame.AddPaintLayer(this); } #endif diff --git a/flow/layers/layer.h b/flow/layers/layer.h index b22a322a73422..f9732760a7770 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -56,14 +56,10 @@ struct PrerollContext { const Stopwatch& ui_time; TextureRegistry& texture_registry; const bool checkerboard_offscreen_layers; - - // These allow us to make use of the scene metrics during Preroll. - float frame_physical_depth; - float frame_device_pixel_ratio; + const float frame_device_pixel_ratio; // These allow us to track properties like elevation, opacity, and the // prescence of a platform view during Preroll. - float total_elevation = 0.0f; bool has_platform_view = false; bool is_opaque = true; #if defined(LEGACY_FUCHSIA_EMBEDDER) @@ -128,10 +124,7 @@ class Layer { TextureRegistry& texture_registry; const RasterCache* raster_cache; const bool checkerboard_offscreen_layers; - - // These allow us to make use of the scene metrics during Paint. - float frame_physical_depth; - float frame_device_pixel_ratio; + const float frame_device_pixel_ratio; }; // Calls SkCanvas::saveLayer and restores the layer upon destruction. Also diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 121391d69a3ba..e0ac5157fc746 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -11,15 +11,14 @@ namespace flutter { -LayerTree::LayerTree(const SkISize& frame_size, - float frame_physical_depth, - float frame_device_pixel_ratio) +LayerTree::LayerTree(const SkISize& frame_size, float device_pixel_ratio) : frame_size_(frame_size), - frame_physical_depth_(frame_physical_depth), - frame_device_pixel_ratio_(frame_device_pixel_ratio), + device_pixel_ratio_(device_pixel_ratio), rasterizer_tracing_threshold_(0), checkerboard_raster_cache_images_(false), - checkerboard_offscreen_layers_(false) {} + checkerboard_offscreen_layers_(false) { + FML_CHECK(device_pixel_ratio_ != 0.0f); +} void LayerTree::RecordBuildTime(fml::TimePoint vsync_start, fml::TimePoint build_start, @@ -56,32 +55,21 @@ bool LayerTree::Preroll(CompositorContext::ScopedFrame& frame, frame.context().ui_time(), frame.context().texture_registry(), checkerboard_offscreen_layers_, - frame_physical_depth_, - frame_device_pixel_ratio_}; + device_pixel_ratio_}; root_layer_->Preroll(&context, frame.root_surface_transformation()); return context.surface_needs_readback; } #if defined(LEGACY_FUCHSIA_EMBEDDER) -void LayerTree::UpdateScene(SceneUpdateContext& context, - scenic::ContainerNode& container) { +void LayerTree::UpdateScene(SceneUpdateContext& context) { TRACE_EVENT0("flutter", "LayerTree::UpdateScene"); - // Ensure the context is aware of the view metrics. - context.set_dimensions(frame_size_, frame_physical_depth_, - frame_device_pixel_ratio_); - - const auto& metrics = context.metrics(); - FML_DCHECK(metrics->scale_x > 0.0f); - FML_DCHECK(metrics->scale_y > 0.0f); - FML_DCHECK(metrics->scale_z > 0.0f); + // Reset for a new Scene. + context.Reset(); - SceneUpdateContext::Transform transform(context, // context - 1.0f / metrics->scale_x, // X - 1.0f / metrics->scale_y, // Y - 1.0f / metrics->scale_z // Z - ); + const float inv_dpr = 1.0f / device_pixel_ratio_; + SceneUpdateContext::Transform transform(context, inv_dpr, inv_dpr, 1.0f); SceneUpdateContext::Frame frame( context, @@ -94,7 +82,7 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, if (root_layer_->needs_painting()) { frame.AddPaintLayer(root_layer_.get()); } - container.AddChild(transform.entity_node()); + context.root_node().AddChild(transform.entity_node()); } #endif @@ -127,8 +115,7 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, frame.context().texture_registry(), ignore_raster_cache ? nullptr : &frame.context().raster_cache(), checkerboard_offscreen_layers_, - frame_physical_depth_, - frame_device_pixel_ratio_}; + device_pixel_ratio_}; if (root_layer_->needs_painting()) { root_layer_->Paint(context); @@ -153,19 +140,18 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { root_surface_transformation.reset(); PrerollContext preroll_context{ - nullptr, // raster_cache (don't consult the cache) - nullptr, // gr_context (used for the raster cache) - nullptr, // external view embedder - unused_stack, // mutator stack - nullptr, // SkColorSpace* dst_color_space - kGiantRect, // SkRect cull_rect - false, // layer reads from surface - unused_stopwatch, // frame time (dont care) - unused_stopwatch, // engine time (dont care) - unused_texture_registry, // texture registry (not supported) - false, // checkerboard_offscreen_layers - frame_physical_depth_, // maximum depth allowed for rendering - frame_device_pixel_ratio_ // ratio between logical and physical + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // external view embedder + unused_stack, // mutator stack + nullptr, // SkColorSpace* dst_color_space + kGiantRect, // SkRect cull_rect + false, // layer reads from surface + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry, // texture registry (not supported) + false, // checkerboard_offscreen_layers + device_pixel_ratio_ // ratio between logical and physical }; SkISize canvas_size = canvas->getBaseLayerSize(); @@ -177,13 +163,12 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { canvas, // canvas nullptr, nullptr, - unused_stopwatch, // frame time (dont care) - unused_stopwatch, // engine time (dont care) - unused_texture_registry, // texture registry (not supported) - nullptr, // raster cache - false, // checkerboard offscreen layers - frame_physical_depth_, // maximum depth allowed for rendering - frame_device_pixel_ratio_ // ratio between logical and physical + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry, // texture registry (not supported) + nullptr, // raster cache + false, // checkerboard offscreen layers + device_pixel_ratio_ // ratio between logical and physical }; // Even if we don't have a root layer, we still need to create an empty diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 0ecd610c9737d..81423c353d458 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -20,9 +20,7 @@ namespace flutter { class LayerTree { public: - LayerTree(const SkISize& frame_size, - float frame_physical_depth, - float frame_device_pixel_ratio); + LayerTree(const SkISize& frame_size, float device_pixel_ratio); // Perform a preroll pass on the tree and return information about // the tree that affects rendering this frame. @@ -35,8 +33,7 @@ class LayerTree { bool ignore_raster_cache = false); #if defined(LEGACY_FUCHSIA_EMBEDDER) - void UpdateScene(SceneUpdateContext& context, - scenic::ContainerNode& container); + void UpdateScene(SceneUpdateContext& context); #endif void Paint(CompositorContext::ScopedFrame& frame, @@ -51,8 +48,7 @@ class LayerTree { } const SkISize& frame_size() const { return frame_size_; } - float frame_physical_depth() const { return frame_physical_depth_; } - float frame_device_pixel_ratio() const { return frame_device_pixel_ratio_; } + float device_pixel_ratio() const { return device_pixel_ratio_; } void RecordBuildTime(fml::TimePoint vsync_start, fml::TimePoint build_start, @@ -83,8 +79,6 @@ class LayerTree { checkerboard_offscreen_layers_ = checkerboard; } - double device_pixel_ratio() const { return frame_device_pixel_ratio_; } - private: std::shared_ptr root_layer_; fml::TimePoint vsync_start_; @@ -92,8 +86,7 @@ class LayerTree { fml::TimePoint build_finish_; fml::TimePoint target_time_; SkISize frame_size_ = SkISize::MakeEmpty(); // Physical pixels. - float frame_physical_depth_; - float frame_device_pixel_ratio_ = 1.0f; // Logical / Physical pixels ratio. + const float device_pixel_ratio_; // Logical / Physical pixels ratio. uint32_t rasterizer_tracing_threshold_; bool checkerboard_raster_cache_images_; bool checkerboard_offscreen_layers_; diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index 1215b72f78726..7045497692afe 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -18,7 +18,7 @@ namespace testing { class LayerTreeTest : public CanvasTest { public: LayerTreeTest() - : layer_tree_(SkISize::Make(64, 64), 100.0f, 1.0f), + : layer_tree_(SkISize::Make(64, 64), 1.0f), compositor_context_(fml::kDefaultFrameBudget), root_transform_(SkMatrix::Translate(1.0f, 1.0f)), scoped_frame_(compositor_context_.AcquireFrame(nullptr, diff --git a/flow/layers/opacity_layer.h b/flow/layers/opacity_layer.h index 73e508f854bc4..ed5f0283ad356 100644 --- a/flow/layers/opacity_layer.h +++ b/flow/layers/opacity_layer.h @@ -38,7 +38,6 @@ class OpacityLayer : public MergedContainerLayer { private: SkAlpha alpha_; SkPoint offset_; - SkRRect frameRRect_; FML_DISALLOW_COPY_AND_ASSIGN(OpacityLayer); }; diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 4f87fb23605a0..7ba2b7cb734ea 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -21,28 +21,7 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color, shadow_color_(shadow_color), elevation_(elevation), path_(path), - isRect_(false), - clip_behavior_(clip_behavior) { - SkRect rect; - if (path.isRect(&rect)) { - isRect_ = true; - frameRRect_ = SkRRect::MakeRect(rect); - } else if (path.isRRect(&frameRRect_)) { - isRect_ = frameRRect_.isRect(); - } else if (path.isOval(&rect)) { - // isRRect returns false for ovals, so we need to explicitly check isOval - // as well. - frameRRect_ = SkRRect::MakeOval(rect); - } else { - // Scenic currently doesn't provide an easy way to create shapes from - // arbitrary paths. - // For shapes that cannot be represented as a rounded rectangle we - // default to use the bounding rectangle. - // TODO(amirh): fix this once we have a way to create a Scenic shape from - // an SkPath. - frameRRect_ = SkRRect::MakeRect(path.getBounds()); - } -} + clip_behavior_(clip_behavior) {} void PhysicalShapeLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { @@ -50,14 +29,9 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); - context->total_elevation += elevation_; - total_elevation_ = context->total_elevation; - SkRect child_paint_bounds; PrerollChildren(context, matrix, &child_paint_bounds); - context->total_elevation -= elevation_; - if (elevation_ == 0) { set_paint_bounds(path_.getBounds()); } else { diff --git a/flow/layers/physical_shape_layer.h b/flow/layers/physical_shape_layer.h index 2c04368e9a81e..ce49af1a003ae 100644 --- a/flow/layers/physical_shape_layer.h +++ b/flow/layers/physical_shape_layer.h @@ -35,16 +35,13 @@ class PhysicalShapeLayer : public ContainerLayer { return clip_behavior_ == Clip::antiAliasWithSaveLayer; } - float total_elevation() const { return total_elevation_; } + float elevation() const { return elevation_; } private: SkColor color_; SkColor shadow_color_; float elevation_ = 0.0f; - float total_elevation_ = 0.0f; SkPath path_; - bool isRect_; - SkRRect frameRRect_; Clip clip_behavior_; }; diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc index 7ad0b4e5eddcb..bb5d0acfad757 100644 --- a/flow/layers/physical_shape_layer_unittests.cc +++ b/flow/layers/physical_shape_layer_unittests.cc @@ -131,7 +131,7 @@ TEST_F(PhysicalShapeLayerTest, ElevationSimple) { initial_elevation, 1.0f)); EXPECT_TRUE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(layer->total_elevation(), initial_elevation); + EXPECT_EQ(layer->elevation(), initial_elevation); // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and // their shadows , so we do not use the direct |Paint()| path there. @@ -162,7 +162,6 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) { // | // layers[1] + 2.0f = 3.0f constexpr float initial_elevations[4] = {1.0f, 2.0f, 3.0f, 4.0f}; - constexpr float total_elevations[4] = {1.0f, 3.0f, 4.0f, 8.0f}; SkPath layer_path; layer_path.addRect(0, 0, 80, 80).close(); @@ -187,7 +186,6 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) { 1.0f /* pixel_ratio */))); EXPECT_TRUE(layers[i]->needs_painting()); EXPECT_FALSE(layers[i]->needs_system_composite()); - EXPECT_EQ(layers[i]->total_elevation(), total_elevations[i]); } // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and diff --git a/flow/layers/platform_view_layer.cc b/flow/layers/platform_view_layer.cc index 0bd6ee7f6dfab..80514b5213e18 100644 --- a/flow/layers/platform_view_layer.cc +++ b/flow/layers/platform_view_layer.cc @@ -48,7 +48,9 @@ void PlatformViewLayer::Paint(PaintContext& context) const { #if defined(LEGACY_FUCHSIA_EMBEDDER) void PlatformViewLayer::UpdateScene(SceneUpdateContext& context) { - context.UpdateScene(view_id_, offset_, size_); + TRACE_EVENT0("flutter", "PlatformViewLayer::UpdateScene"); + FML_DCHECK(needs_system_composite()); + context.UpdateView(view_id_, offset_, size_); } #endif diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc index d01c21950e498..8fe5dd32e1e85 100644 --- a/flow/layers/transform_layer.cc +++ b/flow/layers/transform_layer.cc @@ -4,6 +4,8 @@ #include "flutter/flow/layers/transform_layer.h" +#include + namespace flutter { TransformLayer::TransformLayer(const SkMatrix& transform) @@ -56,12 +58,12 @@ void TransformLayer::UpdateScene(SceneUpdateContext& context) { TRACE_EVENT0("flutter", "TransformLayer::UpdateScene"); FML_DCHECK(needs_system_composite()); + std::optional transform; if (!transform_.isIdentity()) { - SceneUpdateContext::Transform transform(context, transform_); - UpdateSceneChildren(context); - } else { - UpdateSceneChildren(context); + transform.emplace(context, transform_); } + + UpdateSceneChildren(context); } #endif diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index 6a45232fce1ca..72f55bc7e3bef 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -169,7 +169,6 @@ std::unique_ptr RasterCache::RasterizeLayer( context->texture_registry, context->has_platform_view ? nullptr : context->raster_cache, context->checkerboard_offscreen_layers, - context->frame_physical_depth, context->frame_device_pixel_ratio}; if (layer->needs_painting()) { layer->Paint(paintContext); diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index b0628edf0c417..28f3042d5a2a3 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -4,6 +4,7 @@ #include "flutter/flow/scene_update_context.h" +#include #include #include "flutter/flow/layers/layer.h" @@ -13,10 +14,10 @@ #include "include/core/SkColor.h" namespace flutter { +namespace { -// Helper function to generate clip planes for a scenic::EntityNode. -static void SetEntityNodeClipPlanes(scenic::EntityNode& entity_node, - const SkRect& bounds) { +void SetEntityNodeClipPlanes(scenic::EntityNode& entity_node, + const SkRect& bounds) { const float top = bounds.top(); const float bottom = bounds.bottom(); const float left = bounds.left(); @@ -53,20 +54,69 @@ static void SetEntityNodeClipPlanes(scenic::EntityNode& entity_node, entity_node.SetClipPlanes(std::move(clip_planes)); } -SceneUpdateContext::SceneUpdateContext(scenic::Session* session, - SurfaceProducer* surface_producer) - : session_(session), surface_producer_(surface_producer) { - FML_DCHECK(surface_producer_ != nullptr); +void SetMaterialColor(scenic::Material& material, + SkColor color, + SkAlpha opacity) { + const SkAlpha color_alpha = static_cast( + ((float)SkColorGetA(color) * (float)opacity) / 255.0f); + material.SetColor(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), + color_alpha); +} + +} // namespace + +SceneUpdateContext::SceneUpdateContext(std::string debug_label, + fuchsia::ui::views::ViewToken view_token, + scenic::ViewRefPair view_ref_pair, + SessionWrapper& session) + : session_(session), + root_view_(session_.get(), + std::move(view_token), + std::move(view_ref_pair.control_ref), + std::move(view_ref_pair.view_ref), + debug_label), + root_node_(session_.get()) { + root_view_.AddChild(root_node_); + root_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask); + + session_.Present(); +} + +std::vector SceneUpdateContext::GetPaintTasks() { + std::vector frame_paint_tasks = std::move(paint_tasks_); + + paint_tasks_.clear(); + + return frame_paint_tasks; } -void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node, +void SceneUpdateContext::EnableWireframe(bool enable) { + session_.get()->Enqueue( + scenic::NewSetEnableDebugViewBoundsCmd(root_view_.id(), enable)); +} + +void SceneUpdateContext::Reset() { + paint_tasks_.clear(); + top_entity_ = nullptr; + top_scale_x_ = 1.f; + top_scale_y_ = 1.f; + top_elevation_ = 0.f; + next_elevation_ = 0.f; + alpha_ = 1.f; + + // We are going to be sending down a fresh node hierarchy every frame. So just + // enqueue a detach op on the imported root node. + session_.get()->Enqueue(scenic::NewDetachChildrenCmd(root_node_.id())); +} + +void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node, const SkRRect& rrect, SkColor color, SkAlpha opacity, const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer) { - FML_DCHECK(!rrect.isEmpty()); + std::vector paint_layers) { + if (rrect.isEmpty()) + return; // Frames always clip their children. SkRect shape_bounds = rrect.getBounds(); @@ -74,11 +124,8 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node, // and possibly for its texture. // TODO(SCN-137): Need to be able to express the radii as vectors. - scenic::ShapeNode shape_node(session()); - scenic::Rectangle shape(session_, // session - rrect.width(), // width - rrect.height() // height - ); + scenic::ShapeNode shape_node(session_.get()); + scenic::Rectangle shape(session_.get(), rrect.width(), rrect.height()); shape_node.SetShape(shape); shape_node.SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(), shape_bounds.height() * 0.5f + shape_bounds.top(), @@ -88,155 +135,53 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode entity_node, if (paint_bounds.isEmpty() || !paint_bounds.intersects(shape_bounds)) paint_layers.clear(); - scenic::Material material(session()); + scenic::Material material(session_.get()); shape_node.SetMaterial(material); entity_node.AddChild(shape_node); // Check whether a solid color will suffice. - if (paint_layers.empty()) { + if (paint_layers.empty() || shape_bounds.isEmpty()) { SetMaterialColor(material, color, opacity); } else { - // Apply current metrics and transformation scale factors. - const float scale_x = ScaleX(); - const float scale_y = ScaleY(); - - // Apply a texture to the whole shape. - SetMaterialTextureAndColor(material, color, opacity, scale_x, scale_y, - shape_bounds, std::move(paint_layers), layer, - std::move(entity_node)); - } -} - -void SceneUpdateContext::SetMaterialTextureAndColor( - scenic::Material& material, - SkColor color, - SkAlpha opacity, - SkScalar scale_x, - SkScalar scale_y, - const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer, - scenic::EntityNode entity_node) { - scenic::Image* image = GenerateImageIfNeeded( - color, scale_x, scale_y, paint_bounds, std::move(paint_layers), layer, - std::move(entity_node)); - - if (image != nullptr) { // The final shape's color is material_color * texture_color. The passed in // material color was already used as a background when generating the // texture, so set the model color to |SK_ColorWHITE| in order to allow // using the texture's color unmodified. SetMaterialColor(material, SK_ColorWHITE, opacity); - material.SetTexture(*image); - } else { - // No texture was needed, so apply a solid color to the whole shape. - SetMaterialColor(material, color, opacity); - } -} -void SceneUpdateContext::SetMaterialColor(scenic::Material& material, - SkColor color, - SkAlpha opacity) { - const SkAlpha color_alpha = static_cast( - ((float)SkColorGetA(color) * (float)opacity) / 255.0f); - material.SetColor(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), - color_alpha); -} - -scenic::Image* SceneUpdateContext::GenerateImageIfNeeded( - SkColor color, - SkScalar scale_x, - SkScalar scale_y, - const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer, - scenic::EntityNode entity_node) { - // Bail if there's nothing to paint. - if (paint_layers.empty()) - return nullptr; - - // Bail if the physical bounds are empty after rounding. - SkISize physical_size = SkISize::Make(paint_bounds.width() * scale_x, - paint_bounds.height() * scale_y); - if (physical_size.isEmpty()) - return nullptr; - - // Acquire a surface from the surface producer and register the paint tasks. - std::unique_ptr surface = - surface_producer_->ProduceSurface( - physical_size, - LayerRasterCacheKey( - // Root frame has a nullptr layer - layer ? layer->unique_id() : 0, Matrix()), - std::make_unique(std::move(entity_node))); - - if (!surface) { - FML_LOG(ERROR) << "Could not acquire a surface from the surface producer " - "of size: " - << physical_size.width() << "x" << physical_size.height(); - return nullptr; + // Enqueue a paint task for these layers, to apply a texture to the whole + // shape. + // + // The task uses the |shape_bounds| as its rendering bounds instead of the + // |paint_bounds|. If the paint_bounds is large than the shape_bounds it + // will be clipped. + paint_tasks_.emplace_back(PaintTask{.paint_bounds = shape_bounds, + .scale_x = top_scale_x_, + .scale_y = top_scale_y_, + .background_color = color, + .material = std::move(material), + .layers = std::move(paint_layers)}); } - - auto image = surface->GetImage(); - - // Enqueue the paint task. - paint_tasks_.push_back({.surface = std::move(surface), - .left = paint_bounds.left(), - .top = paint_bounds.top(), - .scale_x = scale_x, - .scale_y = scale_y, - .background_color = color, - .layers = std::move(paint_layers)}); - return image; } -std::vector< - std::unique_ptr> -SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { - TRACE_EVENT0("flutter", "SceneUpdateContext::ExecutePaintTasks"); - std::vector> surfaces_to_submit; - for (auto& task : paint_tasks_) { - FML_DCHECK(task.surface); - SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); - Layer::PaintContext context = {canvas, - canvas, - frame.gr_context(), - nullptr, - frame.context().raster_time(), - frame.context().ui_time(), - frame.context().texture_registry(), - &frame.context().raster_cache(), - false, - frame_physical_depth_, - frame_device_pixel_ratio_}; - canvas->restoreToCount(1); - canvas->save(); - canvas->clear(task.background_color); - canvas->scale(task.scale_x, task.scale_y); - canvas->translate(-task.left, -task.top); - for (Layer* layer : task.layers) { - layer->Paint(context); - } - surfaces_to_submit.emplace_back(std::move(task.surface)); - } - paint_tasks_.clear(); - alpha_ = 1.f; - topmost_global_scenic_elevation_ = kScenicZElevationBetweenLayers; - scenic_elevation_ = 0.f; - return surfaces_to_submit; -} - -void SceneUpdateContext::UpdateScene(int64_t view_id, - const SkPoint& offset, - const SkSize& size) { +void SceneUpdateContext::UpdateView(int64_t view_id, + const SkPoint& offset, + const SkSize& size, + std::optional override_hit_testable) { auto* view_holder = ViewHolder::FromId(view_id); FML_DCHECK(view_holder); - view_holder->SetProperties(size.width(), size.height(), 0, 0, 0, 0, - view_holder->focusable()); - view_holder->UpdateScene(*this, offset, size, - SkScalarRoundToInt(alphaf() * 255), - view_holder->hit_testable()); + if (size.width() > 0.f && size.height() > 0.f) { + view_holder->SetProperties(size.width(), size.height(), 0, 0, 0, 0, + view_holder->focusable()); + } + + bool hit_testable = override_hit_testable.has_value() + ? *override_hit_testable + : view_holder->hit_testable(); + view_holder->UpdateScene(session_.get(), top_entity_->embedder_node(), offset, + size, SkScalarRoundToInt(alphaf() * 255), + hit_testable); } void SceneUpdateContext::CreateView(int64_t view_id, @@ -260,13 +205,17 @@ void SceneUpdateContext::DestroyView(int64_t view_id) { SceneUpdateContext::Entity::Entity(SceneUpdateContext& context) : context_(context), previous_entity_(context.top_entity_), - entity_node_(context.session()) { - if (previous_entity_) - previous_entity_->embedder_node().AddChild(entity_node_); + entity_node_(context.session_.get()) { context.top_entity_ = this; } SceneUpdateContext::Entity::~Entity() { + if (previous_entity_) { + previous_entity_->embedder_node().AddChild(entity_node_); + } else { + context_.root_node_.AddChild(entity_node_); + } + FML_DCHECK(context_.top_entity_ == this); context_.top_entity_ = previous_entity_; } @@ -329,18 +278,20 @@ SceneUpdateContext::Frame::Frame(SceneUpdateContext& context, const SkRRect& rrect, SkColor color, SkAlpha opacity, - std::string label, - float z_translation, - Layer* layer) + std::string label) : Entity(context), + previous_elevation_(context.top_elevation_), rrect_(rrect), color_(color), opacity_(opacity), - opacity_node_(context.session()), - paint_bounds_(SkRect::MakeEmpty()), - layer_(layer) { + opacity_node_(context.session_.get()), + paint_bounds_(SkRect::MakeEmpty()) { entity_node().SetLabel(label); - entity_node().SetTranslation(0.f, 0.f, z_translation); + entity_node().SetTranslation(0.f, 0.f, + context.next_elevation_ - previous_elevation_); + context.top_elevation_ += kScenicZElevationBetweenLayers; + context.next_elevation_ += kScenicZElevationBetweenLayers; + entity_node().AddChild(opacity_node_); // Scenic currently lacks an API to enable rendering of alpha channel; alpha // channels are only rendered if there is a OpacityNode higher in the tree @@ -350,20 +301,11 @@ SceneUpdateContext::Frame::Frame(SceneUpdateContext& context, } SceneUpdateContext::Frame::~Frame() { - // We don't need a shape if the frame is zero size. - if (rrect_.isEmpty()) - return; - - // isEmpty should account for this, but we are adding these experimental - // checks to validate if this is the root cause for b/144933519. - if (std::isnan(rrect_.width()) || std::isnan(rrect_.height())) { - FML_LOG(ERROR) << "Invalid RoundedRectangle"; - return; - } - // Add a part which represents the frame's geometry for clipping purposes - context().CreateFrame(std::move(entity_node()), rrect_, color_, opacity_, - paint_bounds_, std::move(paint_layers_), layer_); + context().CreateFrame(entity_node(), rrect_, color_, opacity_, paint_bounds_, + std::move(paint_layers_)); + + context().top_elevation_ = previous_elevation_; } void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) { diff --git a/flow/scene_update_context.h b/flow/scene_update_context.h index 3b46fb2247f3c..9ca6c7dde4c05 100644 --- a/flow/scene_update_context.h +++ b/flow/scene_update_context.h @@ -5,18 +5,19 @@ #ifndef FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_ #define FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_ +#include +#include +#include +#include + #include #include #include #include -#include "flutter/flow/compositor_context.h" #include "flutter/flow/embedded_views.h" -#include "flutter/flow/raster_cache_key.h" -#include "flutter/fml/compiler_specific.h" #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" -#include "lib/ui/scenic/cpp/resources.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" @@ -33,50 +34,16 @@ constexpr float kOneMinusEpsilon = 1 - FLT_EPSILON; // How much layers are separated in Scenic z elevation. constexpr float kScenicZElevationBetweenLayers = 10.f; -class SceneUpdateContext : public flutter::ExternalViewEmbedder { +class SessionWrapper { public: - class SurfaceProducerSurface { - public: - virtual ~SurfaceProducerSurface() = default; - - virtual size_t AdvanceAndGetAge() = 0; - - virtual bool FlushSessionAcquireAndReleaseEvents() = 0; - - virtual bool IsValid() const = 0; + virtual ~SessionWrapper() {} - virtual SkISize GetSize() const = 0; - - virtual void SignalWritesFinished( - const std::function& on_writes_committed) = 0; - - virtual scenic::Image* GetImage() = 0; - - virtual sk_sp GetSkiaSurface() const = 0; - }; - - class SurfaceProducer { - public: - virtual ~SurfaceProducer() = default; - - // The produced surface owns the entity_node and has a layer_key for - // retained rendering. The surface will only be retained if the layer_key - // has a non-null layer pointer (layer_key.id()). - virtual std::unique_ptr ProduceSurface( - const SkISize& size, - const LayerRasterCacheKey& layer_key, - std::unique_ptr entity_node) = 0; - - // Query a retained entity node (owned by a retained surface) for retained - // rendering. - virtual bool HasRetainedNode(const LayerRasterCacheKey& key) const = 0; - virtual scenic::EntityNode* GetRetainedNode( - const LayerRasterCacheKey& key) = 0; - - virtual void SubmitSurface( - std::unique_ptr surface) = 0; - }; + virtual scenic::Session* get() = 0; + virtual void Present() = 0; +}; +class SceneUpdateContext : public flutter::ExternalViewEmbedder { + public: class Entity { public: Entity(SceneUpdateContext& context); @@ -116,9 +83,7 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder { const SkRRect& rrect, SkColor color, SkAlpha opacity, - std::string label, - float z_translation = 0.0f, - Layer* layer = nullptr); + std::string label); virtual ~Frame(); scenic::ContainerNode& embedder_node() override { return opacity_node_; } @@ -126,6 +91,8 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder { void AddPaintLayer(Layer* layer); private: + const float previous_elevation_; + const SkRRect rrect_; SkColor const color_; SkAlpha const opacity_; @@ -133,7 +100,6 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder { scenic::OpacityNodeHACK opacity_node_; std::vector paint_layers_; SkRect paint_bounds_; - Layer* layer_; }; class Clip : public Entity { @@ -142,68 +108,35 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder { ~Clip() = default; }; - SceneUpdateContext(scenic::Session* session, - SurfaceProducer* surface_producer); - ~SceneUpdateContext() = default; - - scenic::Session* session() { return session_; } + struct PaintTask { + SkRect paint_bounds; + SkScalar scale_x; + SkScalar scale_y; + SkColor background_color; + scenic::Material material; + std::vector layers; + }; - Entity* top_entity() { return top_entity_; } + SceneUpdateContext(std::string debug_label, + fuchsia::ui::views::ViewToken view_token, + scenic::ViewRefPair view_ref_pair, + SessionWrapper& session); + ~SceneUpdateContext() = default; - bool has_metrics() const { return !!metrics_; } - void set_metrics(fuchsia::ui::gfx::MetricsPtr metrics) { - metrics_ = std::move(metrics); - } - const fuchsia::ui::gfx::MetricsPtr& metrics() const { return metrics_; } - - void set_dimensions(const SkISize& frame_physical_size, - float frame_physical_depth, - float frame_device_pixel_ratio) { - frame_physical_size_ = frame_physical_size; - frame_physical_depth_ = frame_physical_depth; - frame_device_pixel_ratio_ = frame_device_pixel_ratio; - } - const SkISize& frame_size() const { return frame_physical_size_; } - float frame_physical_depth() const { return frame_physical_depth_; } - float frame_device_pixel_ratio() const { return frame_device_pixel_ratio_; } - - // TODO(chinmaygarde): This method must submit the surfaces as soon as paint - // tasks are done. However, given that there is no support currently for - // Vulkan semaphores, we need to submit all the surfaces after an explicit - // CPU wait. Once Vulkan semaphores are available, this method must return - // void and the implementation must submit surfaces on its own as soon as the - // specific canvas operations are done. - [[nodiscard]] std::vector> - ExecutePaintTasks(CompositorContext::ScopedFrame& frame); - - float ScaleX() const { return metrics_->scale_x * top_scale_x_; } - float ScaleY() const { return metrics_->scale_y * top_scale_y_; } - - // The transformation matrix of the current context. It's used to construct - // the LayerRasterCacheKey for a given layer. - SkMatrix Matrix() const { return SkMatrix::MakeScale(ScaleX(), ScaleY()); } - - bool HasRetainedNode(const LayerRasterCacheKey& key) const { - return surface_producer_->HasRetainedNode(key); - } - scenic::EntityNode* GetRetainedNode(const LayerRasterCacheKey& key) { - return surface_producer_->GetRetainedNode(key); - } + scenic::ContainerNode& root_node() { return root_node_; } // The cumulative alpha value based on all the parent OpacityLayers. void set_alphaf(float alpha) { alpha_ = alpha; } float alphaf() { return alpha_; } - // The global scenic elevation at a given point in the traversal. - float scenic_elevation() { return scenic_elevation_; } + // Returns all `PaintTask`s generated for the current frame. + std::vector GetPaintTasks(); - void set_scenic_elevation(float elevation) { scenic_elevation_ = elevation; } + // Enable/disable wireframe rendering around the root view bounds. + void EnableWireframe(bool enable); - float GetGlobalElevationForNextScenicLayer() { - float elevation = topmost_global_scenic_elevation_; - topmost_global_scenic_elevation_ += kScenicZElevationBetweenLayers; - return elevation; - } + // Reset state for a new frame. + void Reset(); // |ExternalViewEmbedder| SkCanvas* GetRootCanvas() override { return nullptr; } @@ -234,73 +167,34 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder { } void CreateView(int64_t view_id, bool hit_testable, bool focusable); - void DestroyView(int64_t view_id); - - void UpdateScene(int64_t view_id, const SkPoint& offset, const SkSize& size); + void UpdateView(int64_t view_id, + const SkPoint& offset, + const SkSize& size, + std::optional override_hit_testable = std::nullopt); private: - struct PaintTask { - std::unique_ptr surface; - SkScalar left; - SkScalar top; - SkScalar scale_x; - SkScalar scale_y; - SkColor background_color; - std::vector layers; - }; - - // Setup the entity_node as a frame that materialize all the paint_layers. In - // most cases, this creates a VulkanSurface (SurfaceProducerSurface) by - // calling SetShapeTextureOrColor and GenerageImageIfNeeded. Such surface will - // own the associated entity_node. If the layer pointer isn't nullptr, the - // surface (and thus the entity_node) will be retained for that layer to - // improve the performance. - void CreateFrame(scenic::EntityNode entity_node, + void CreateFrame(scenic::EntityNode& entity_node, const SkRRect& rrect, SkColor color, SkAlpha opacity, const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer); - void SetMaterialTextureAndColor(scenic::Material& material, - SkColor color, - SkAlpha opacity, - SkScalar scale_x, - SkScalar scale_y, - const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer, - scenic::EntityNode entity_node); - void SetMaterialColor(scenic::Material& material, - SkColor color, - SkAlpha opacity); - scenic::Image* GenerateImageIfNeeded(SkColor color, - SkScalar scale_x, - SkScalar scale_y, - const SkRect& paint_bounds, - std::vector paint_layers, - Layer* layer, - scenic::EntityNode entity_node); + std::vector paint_layers); - Entity* top_entity_ = nullptr; - float top_scale_x_ = 1.f; - float top_scale_y_ = 1.f; + SessionWrapper& session_; - scenic::Session* const session_; - SurfaceProducer* const surface_producer_; + scenic::View root_view_; + scenic::EntityNode root_node_; - fuchsia::ui::gfx::MetricsPtr metrics_; - SkISize frame_physical_size_; - float frame_physical_depth_ = 0.0f; - float frame_device_pixel_ratio_ = - 1.0f; // Ratio between logical and physical pixels. + std::vector paint_tasks_; - float alpha_ = 1.0f; - float scenic_elevation_ = 0.f; - float topmost_global_scenic_elevation_ = kScenicZElevationBetweenLayers; + Entity* top_entity_ = nullptr; + float top_scale_x_ = 1.f; + float top_scale_y_ = 1.f; + float top_elevation_ = 0.f; - std::vector paint_tasks_; + float next_elevation_ = 0.f; + float alpha_ = 1.f; FML_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext); }; diff --git a/flow/testing/layer_test.h b/flow/testing/layer_test.h index c63057fca1942..d2df8b404ca9b 100644 --- a/flow/testing/layer_test.h +++ b/flow/testing/layer_test.h @@ -47,11 +47,9 @@ class LayerTestBase : public CanvasTestBase { kGiantRect, /* cull_rect */ false, /* layer reads from surface */ raster_time_, ui_time_, texture_registry_, - false, /* checkerboard_offscreen_layers */ - 100.0f, /* frame_physical_depth */ - 1.0f, /* frame_device_pixel_ratio */ - 0.0f, /* total_elevation */ - false, /* has_platform_view */ + false, /* checkerboard_offscreen_layers */ + 1.0f, /* frame_device_pixel_ratio */ + false, /* has_platform_view */ }), paint_context_({ TestT::mock_canvas().internal_canvas(), /* internal_nodes_canvas */ @@ -61,7 +59,6 @@ class LayerTestBase : public CanvasTestBase { raster_time_, ui_time_, texture_registry_, nullptr, /* raster_cache */ false, /* checkerboard_offscreen_layers */ - 100.0f, /* frame_physical_depth */ 1.0f, /* frame_device_pixel_ratio */ }) { use_null_raster_cache(); diff --git a/flow/testing/mock_layer.cc b/flow/testing/mock_layer.cc index 5fe1b98088af1..b32bdb23abc09 100644 --- a/flow/testing/mock_layer.cc +++ b/flow/testing/mock_layer.cc @@ -22,7 +22,6 @@ void MockLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { parent_mutators_ = context->mutators_stack; parent_matrix_ = matrix; parent_cull_rect_ = context->cull_rect; - parent_elevation_ = context->total_elevation; parent_has_platform_view_ = context->has_platform_view; context->has_platform_view = fake_has_platform_view_; diff --git a/flow/testing/mock_layer.h b/flow/testing/mock_layer.h index 835c3ee9621cc..b92583f581209 100644 --- a/flow/testing/mock_layer.h +++ b/flow/testing/mock_layer.h @@ -28,7 +28,6 @@ class MockLayer : public Layer { const MutatorsStack& parent_mutators() { return parent_mutators_; } const SkMatrix& parent_matrix() { return parent_matrix_; } const SkRect& parent_cull_rect() { return parent_cull_rect_; } - float parent_elevation() { return parent_elevation_; } bool parent_has_platform_view() { return parent_has_platform_view_; } private: @@ -37,7 +36,6 @@ class MockLayer : public Layer { SkRect parent_cull_rect_ = SkRect::MakeEmpty(); SkPath fake_paint_path_; SkPaint fake_paint_; - float parent_elevation_ = 0; bool parent_has_platform_view_ = false; bool fake_has_platform_view_ = false; bool fake_needs_system_composite_ = false; diff --git a/flow/testing/mock_layer_unittests.cc b/flow/testing/mock_layer_unittests.cc index 0e6e37978c2e1..ebb837ca8b8dd 100644 --- a/flow/testing/mock_layer_unittests.cc +++ b/flow/testing/mock_layer_unittests.cc @@ -39,13 +39,11 @@ TEST_F(MockLayerTest, SimpleParams) { const SkMatrix start_matrix = SkMatrix::Translate(1.0f, 2.0f); const SkMatrix scale_matrix = SkMatrix::Scale(0.5f, 0.5f); const SkRect cull_rect = SkRect::MakeWH(5.0f, 5.0f); - const float parent_elevation = 5.0f; const bool parent_has_platform_view = true; auto layer = std::make_shared(path, paint); preroll_context()->mutators_stack.PushTransform(scale_matrix); preroll_context()->cull_rect = cull_rect; - preroll_context()->total_elevation = parent_elevation; preroll_context()->has_platform_view = parent_has_platform_view; layer->Preroll(preroll_context(), start_matrix); EXPECT_EQ(preroll_context()->has_platform_view, false); @@ -55,7 +53,6 @@ TEST_F(MockLayerTest, SimpleParams) { EXPECT_EQ(layer->parent_mutators(), std::vector{Mutator(scale_matrix)}); EXPECT_EQ(layer->parent_matrix(), start_matrix); EXPECT_EQ(layer->parent_cull_rect(), cull_rect); - EXPECT_EQ(layer->parent_elevation(), parent_elevation); EXPECT_EQ(layer->parent_has_platform_view(), parent_has_platform_view); layer->Paint(paint_context()); diff --git a/flow/view_holder.cc b/flow/view_holder.cc index 7fd00500bb02c..c2011825c9474 100644 --- a/flow/view_holder.cc +++ b/flow/view_holder.cc @@ -4,6 +4,8 @@ #include "flutter/flow/view_holder.h" +#include + #include "flutter/fml/thread_local.h" namespace { @@ -98,18 +100,17 @@ ViewHolder::ViewHolder(fml::RefPtr ui_task_runner, FML_DCHECK(pending_view_holder_token_.value); } -void ViewHolder::UpdateScene(SceneUpdateContext& context, +void ViewHolder::UpdateScene(scenic::Session* session, + scenic::ContainerNode& container_node, const SkPoint& offset, const SkSize& size, SkAlpha opacity, bool hit_testable) { if (pending_view_holder_token_.value) { - entity_node_ = std::make_unique(context.session()); - opacity_node_ = - std::make_unique(context.session()); + entity_node_ = std::make_unique(session); + opacity_node_ = std::make_unique(session); view_holder_ = std::make_unique( - context.session(), std::move(pending_view_holder_token_), - "Flutter SceneHost"); + session, std::move(pending_view_holder_token_), "Flutter SceneHost"); opacity_node_->AddChild(*entity_node_); opacity_node_->SetLabel("flutter::ViewHolder"); entity_node_->Attach(*view_holder_); @@ -125,7 +126,7 @@ void ViewHolder::UpdateScene(SceneUpdateContext& context, FML_DCHECK(opacity_node_); FML_DCHECK(view_holder_); - context.top_entity()->embedder_node().AddChild(*opacity_node_); + container_node.AddChild(*opacity_node_); opacity_node_->SetOpacity(opacity / 255.0f); entity_node_->SetTranslation(offset.x(), offset.y(), -0.1f); entity_node_->SetHitTestBehavior( diff --git a/flow/view_holder.h b/flow/view_holder.h index bb8ff83d776ab..f25b205c7823c 100644 --- a/flow/view_holder.h +++ b/flow/view_holder.h @@ -9,17 +9,17 @@ #include #include #include +#include #include -#include "third_party/skia/include/core/SkMatrix.h" -#include "third_party/skia/include/core/SkPoint.h" -#include "third_party/skia/include/core/SkSize.h" #include -#include "flutter/flow/scene_update_context.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/task_runner.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkSize.h" namespace flutter { @@ -54,7 +54,8 @@ class ViewHolder { // Creates or updates the contained ViewHolder resource using the specified // |SceneUpdateContext|. - void UpdateScene(SceneUpdateContext& context, + void UpdateScene(scenic::Session* session, + scenic::ContainerNode& container_node, const SkPoint& offset, const SkSize& size, SkAlpha opacity, diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index d70033a346b09..96eac5885d083 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -50,7 +50,6 @@ Scene::Scene(std::shared_ptr rootLayer, layer_tree_ = std::make_unique( SkISize::Make(viewport_metrics.physical_width, viewport_metrics.physical_height), - static_cast(viewport_metrics.physical_depth), static_cast(viewport_metrics.device_pixel_ratio)); layer_tree_->set_root_layer(std::move(rootLayer)); layer_tree_->set_rasterizer_tracing_threshold(rasterizerTracingThreshold); diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index c2a74aa10c3ec..a911d79f63a8d 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -14,7 +14,6 @@ void _updateWindowMetrics( double devicePixelRatio, double width, double height, - double depth, double viewPaddingTop, double viewPaddingRight, double viewPaddingBottom, @@ -31,7 +30,6 @@ void _updateWindowMetrics( window .._devicePixelRatio = devicePixelRatio .._physicalSize = Size(width, height) - .._physicalDepth = depth .._viewPadding = WindowPadding._( top: viewPaddingTop, right: viewPaddingRight, diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 3fb31bf51ec00..a39c5407ad45e 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -656,20 +656,6 @@ class Window { Size get physicalSize => _physicalSize; Size _physicalSize = Size.zero; - /// The physical depth is the maximum elevation that the Window allows. - /// - /// Physical layers drawn at or above this elevation will have their elevation - /// clamped to this value. This can happen if the physical layer itself has - /// an elevation larger than available depth, or if some ancestor of the layer - /// causes it to have a cumulative elevation that is larger than the available - /// depth. - /// - /// The default value is [double.maxFinite], which is used for platforms that - /// do not specify a maximum elevation. This property is currently on expected - /// to be set to a non-default value on Fuchsia. - double get physicalDepth => _physicalDepth; - double _physicalDepth = double.maxFinite; - /// The number of physical pixels on each side of the display rectangle into /// which the application can render, but over which the operating system /// will likely place system UI, such as the keyboard, that fully obscures diff --git a/lib/ui/window/viewport_metrics.cc b/lib/ui/window/viewport_metrics.cc index 329cea01c036a..f642bd116966f 100644 --- a/lib/ui/window/viewport_metrics.cc +++ b/lib/ui/window/viewport_metrics.cc @@ -8,6 +8,8 @@ namespace flutter { +ViewportMetrics::ViewportMetrics() = default; + ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio, double p_physical_width, double p_physical_height, @@ -46,40 +48,6 @@ ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio, FML_DCHECK(device_pixel_ratio > 0); } -ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio, - double p_physical_width, - double p_physical_height, - double p_physical_depth, - double p_physical_padding_top, - double p_physical_padding_right, - double p_physical_padding_bottom, - double p_physical_padding_left, - double p_physical_view_inset_front, - double p_physical_view_inset_back, - double p_physical_view_inset_top, - double p_physical_view_inset_right, - double p_physical_view_inset_bottom, - double p_physical_view_inset_left) - : device_pixel_ratio(p_device_pixel_ratio), - physical_width(p_physical_width), - physical_height(p_physical_height), - physical_depth(p_physical_depth), - physical_padding_top(p_physical_padding_top), - physical_padding_right(p_physical_padding_right), - physical_padding_bottom(p_physical_padding_bottom), - physical_padding_left(p_physical_padding_left), - physical_view_inset_top(p_physical_view_inset_top), - physical_view_inset_right(p_physical_view_inset_right), - physical_view_inset_bottom(p_physical_view_inset_bottom), - physical_view_inset_left(p_physical_view_inset_left), - physical_view_inset_front(p_physical_view_inset_front), - physical_view_inset_back(p_physical_view_inset_back) { - // Ensure we don't have nonsensical dimensions. - FML_DCHECK(physical_width >= 0); - FML_DCHECK(physical_height >= 0); - FML_DCHECK(device_pixel_ratio > 0); -} - ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio, double p_physical_width, double p_physical_height) diff --git a/lib/ui/window/viewport_metrics.h b/lib/ui/window/viewport_metrics.h index d4a7311ad95f3..01081e3f345f1 100644 --- a/lib/ui/window/viewport_metrics.h +++ b/lib/ui/window/viewport_metrics.h @@ -5,21 +5,10 @@ #ifndef FLUTTER_LIB_UI_WINDOW_VIEWPORT_METRICS_H_ #define FLUTTER_LIB_UI_WINDOW_VIEWPORT_METRICS_H_ -#include - namespace flutter { -// This is the value of double.maxFinite from dart:core. -// Platforms that do not explicitly set a depth will use this value, which -// avoids the need to special case logic that wants to check the max depth on -// the Dart side. -static const double kUnsetDepth = 1.7976931348623157e+308; - struct ViewportMetrics { - ViewportMetrics() = default; - ViewportMetrics(const ViewportMetrics& other) = default; - - // Create a 2D ViewportMetrics instance. + ViewportMetrics(); ViewportMetrics(double p_device_pixel_ratio, double p_physical_width, double p_physical_height, @@ -36,22 +25,6 @@ struct ViewportMetrics { double p_physical_system_gesture_inset_bottom, double p_physical_system_gesture_inset_left); - // Create a ViewportMetrics instance that contains z information. - ViewportMetrics(double p_device_pixel_ratio, - double p_physical_width, - double p_physical_height, - double p_physical_depth, - double p_physical_padding_top, - double p_physical_padding_right, - double p_physical_padding_bottom, - double p_physical_padding_left, - double p_physical_view_inset_front, - double p_physical_view_inset_back, - double p_physical_view_inset_top, - double p_physical_view_inset_right, - double p_physical_view_inset_bottom, - double p_physical_view_inset_left); - // Create a ViewportMetrics instance that doesn't include depth, padding, or // insets. ViewportMetrics(double p_device_pixel_ratio, @@ -61,7 +34,6 @@ struct ViewportMetrics { double device_pixel_ratio = 1.0; double physical_width = 0; double physical_height = 0; - double physical_depth = kUnsetDepth; double physical_padding_top = 0; double physical_padding_right = 0; double physical_padding_bottom = 0; @@ -70,8 +42,6 @@ struct ViewportMetrics { double physical_view_inset_right = 0; double physical_view_inset_bottom = 0; double physical_view_inset_left = 0; - double physical_view_inset_front = kUnsetDepth; - double physical_view_inset_back = kUnsetDepth; double physical_system_gesture_inset_top = 0; double physical_system_gesture_inset_right = 0; double physical_system_gesture_inset_bottom = 0; @@ -81,7 +51,6 @@ struct ViewportMetrics { struct LogicalSize { double width = 0.0; double height = 0.0; - double depth = kUnsetDepth; }; struct LogicalInset { @@ -89,14 +58,11 @@ struct LogicalInset { double top = 0.0; double right = 0.0; double bottom = 0.0; - double front = kUnsetDepth; - double back = kUnsetDepth; }; struct LogicalMetrics { LogicalSize size; double scale = 1.0; - double scale_z = 1.0; LogicalInset padding; LogicalInset view_inset; }; diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc index d583682888313..1779998945554 100644 --- a/lib/ui/window/window.cc +++ b/lib/ui/window/window.cc @@ -49,7 +49,6 @@ void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) { tonic::ToDart(metrics.device_pixel_ratio), tonic::ToDart(metrics.physical_width), tonic::ToDart(metrics.physical_height), - tonic::ToDart(metrics.physical_depth), tonic::ToDart(metrics.physical_padding_top), tonic::ToDart(metrics.physical_padding_right), tonic::ToDart(metrics.physical_padding_bottom), diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 9bee5d15c43fa..7dbb1497c716d 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -151,9 +151,6 @@ class EngineWindow extends ui.Window { /// Overrides the value of [physicalSize] in tests. ui.Size? webOnlyDebugPhysicalSizeOverride; - @override - double get physicalDepth => double.maxFinite; - /// Handles the browser history integration to allow users to use the back /// button, etc. final BrowserHistory _browserHistory = BrowserHistory(); diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index b004a95782c9f..deaad0df46a72 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -455,19 +455,6 @@ abstract class Window { /// observe when this value changes. Size get physicalSize; - /// The physical depth is the maximum elevation that the Window allows. - /// - /// Physical layers drawn at or above this elevation will have their elevation - /// clamped to this value. This can happen if the physical layer itself has - /// an elevation larger than available depth, or if some ancestor of the layer - /// causes it to have a cumulative elevation that is larger than the available - /// depth. - /// - /// The default value is [double.maxFinite], which is used for platforms that - /// do not specify a maximum elevation. This property is currently on expected - /// to be set to a non-default value on Fuchsia. - double get physicalDepth; - /// The number of physical pixels on each side of the display rectangle into /// which the application can render, but over which the operating system /// will likely place system UI, such as the keyboard, that fully obscures diff --git a/shell/common/engine.cc b/shell/common/engine.cc index d4338c663be06..315780f23346b 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -290,7 +290,6 @@ void Engine::SetViewportMetrics(const ViewportMetrics& metrics) { bool dimensions_changed = viewport_metrics_.physical_height != metrics.physical_height || viewport_metrics_.physical_width != metrics.physical_width || - viewport_metrics_.physical_depth != metrics.physical_depth || viewport_metrics_.device_pixel_ratio != metrics.device_pixel_ratio; viewport_metrics_ = metrics; runtime_controller_->SetViewportMetrics(viewport_metrics_); @@ -476,8 +475,7 @@ void Engine::Render(std::unique_ptr layer_tree) { // Ensure frame dimensions are sane. if (layer_tree->frame_size().isEmpty() || - layer_tree->frame_physical_depth() <= 0.0f || - layer_tree->frame_device_pixel_ratio() <= 0.0f) { + layer_tree->device_pixel_ratio() <= 0.0f) { return; } diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index d60c80805ce9d..b3a64f3fd6993 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -129,7 +129,6 @@ void ShellTest::PumpOneFrame(Shell* shell, auto layer_tree = std::make_unique( SkISize::Make(viewport_metrics.physical_width, viewport_metrics.physical_height), - static_cast(viewport_metrics.physical_depth), static_cast(viewport_metrics.device_pixel_ratio)); SkMatrix identity; identity.setIdentity(); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 95ab0071fdb36..86724c1a36d08 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -1403,11 +1403,9 @@ TEST_F(ShellTest, OnServiceProtocolEstimateRasterCacheMemoryWorks) { kGiantRect, /* cull_rect */ false, /* layer reads from surface */ raster_time, ui_time, texture_registry, - false, /* checkerboard_offscreen_layers */ - 100.0f, /* frame_physical_depth */ - 1.0f, /* frame_device_pixel_ratio */ - 0.0f, /* total_elevation */ - false, /* has_platform_view */ + false, /* checkerboard_offscreen_layers */ + 1.0f, /* frame_device_pixel_ratio */ + false, /* has_platform_view */ }; raster_cache.Prepare(&preroll_context, picture_layer.get(), SkMatrix::I()); diff --git a/shell/platform/fuchsia/flutter/component.cc b/shell/platform/fuchsia/flutter/component.cc index 00cd9d318ae83..0106931820887 100644 --- a/shell/platform/fuchsia/flutter/component.cc +++ b/shell/platform/fuchsia/flutter/component.cc @@ -365,6 +365,12 @@ Application::Application( // Controls whether category "skia" trace events are enabled. settings_.trace_skia = true; + settings_.verbose_logging = true; + + settings_.advisory_script_uri = debug_label_; + + settings_.advisory_script_entrypoint = debug_label_; + settings_.icu_data_path = ""; settings_.assets_dir = application_assets_directory_.get(); diff --git a/shell/platform/fuchsia/flutter/compositor_context.cc b/shell/platform/fuchsia/flutter/compositor_context.cc index b0bbfc7ecbc28..599ebf77b0dd2 100644 --- a/shell/platform/fuchsia/flutter/compositor_context.cc +++ b/shell/platform/fuchsia/flutter/compositor_context.cc @@ -4,6 +4,8 @@ #include "compositor_context.h" +#include + #include "flutter/flow/layers/layer_tree.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -11,30 +13,38 @@ namespace flutter_runner { class ScopedFrame final : public flutter::CompositorContext::ScopedFrame { public: - ScopedFrame(flutter::CompositorContext& context, - const SkMatrix& root_surface_transformation, + ScopedFrame(CompositorContext& context, + GrContext* gr_context, + SkCanvas* canvas, flutter::ExternalViewEmbedder* view_embedder, + const SkMatrix& root_surface_transformation, bool instrumentation_enabled, - SessionConnection& session_connection) - : flutter::CompositorContext::ScopedFrame( - context, - session_connection.vulkan_surface_producer()->gr_context(), - nullptr, - view_embedder, - root_surface_transformation, - instrumentation_enabled, - true, - nullptr), - session_connection_(session_connection) {} + bool surface_supports_readback, + fml::RefPtr raster_thread_merger, + SessionConnection& session_connection, + VulkanSurfaceProducer& surface_producer, + flutter::SceneUpdateContext& scene_update_context) + : flutter::CompositorContext::ScopedFrame(context, + surface_producer.gr_context(), + canvas, + view_embedder, + root_surface_transformation, + instrumentation_enabled, + surface_supports_readback, + raster_thread_merger), + session_connection_(session_connection), + surface_producer_(surface_producer), + scene_update_context_(scene_update_context) {} private: SessionConnection& session_connection_; + VulkanSurfaceProducer& surface_producer_; + flutter::SceneUpdateContext& scene_update_context_; flutter::RasterStatus Raster(flutter::LayerTree& layer_tree, bool ignore_raster_cache) override { - if (!session_connection_.has_metrics()) { - return flutter::RasterStatus::kSuccess; - } + std::vector frame_paint_tasks; + std::vector> frame_surfaces; { // Preroll the Flutter layer tree. This allows Flutter to perform @@ -47,15 +57,80 @@ class ScopedFrame final : public flutter::CompositorContext::ScopedFrame { // Traverse the Flutter layer tree so that the necessary session ops to // represent the frame are enqueued in the underlying session. TRACE_EVENT0("flutter", "UpdateScene"); - layer_tree.UpdateScene(session_connection_.scene_update_context(), - session_connection_.root_node()); + layer_tree.UpdateScene(scene_update_context_); } { - // Flush all pending session ops. + // Flush all pending session ops: create surfaces and enqueue session + // Image ops for the frame's paint tasks, then Present. TRACE_EVENT0("flutter", "SessionPresent"); + frame_paint_tasks = scene_update_context_.GetPaintTasks(); + for (auto& task : frame_paint_tasks) { + SkISize physical_size = + SkISize::Make(layer_tree.device_pixel_ratio() * task.scale_x * + task.paint_bounds.width(), + layer_tree.device_pixel_ratio() * task.scale_y * + task.paint_bounds.height()); + if (physical_size.width() == 0 || physical_size.height() == 0) { + frame_surfaces.emplace_back(nullptr); + continue; + } + + std::unique_ptr surface = + surface_producer_.ProduceSurface(physical_size); + if (!surface) { + FML_LOG(ERROR) + << "Could not acquire a surface from the surface producer " + "of size: " + << physical_size.width() << "x" << physical_size.height(); + } else { + task.material.SetTexture(*(surface->GetImage())); + } + + frame_surfaces.emplace_back(std::move(surface)); + } + + session_connection_.Present(); + } - session_connection_.Present(this); + { + // Execute paint tasks in parallel with Scenic's side of the Present, then + // signal fences. + TRACE_EVENT0("flutter", "ExecutePaintTasks"); + size_t surface_index = 0; + for (auto& task : frame_paint_tasks) { + std::unique_ptr& task_surface = + frame_surfaces[surface_index++]; + if (!task_surface) { + continue; + } + + SkCanvas* canvas = task_surface->GetSkiaSurface()->getCanvas(); + flutter::Layer::PaintContext paint_context = { + canvas, + canvas, + gr_context(), + nullptr, + context().raster_time(), + context().ui_time(), + context().texture_registry(), + &context().raster_cache(), + false, + layer_tree.device_pixel_ratio()}; + canvas->restoreToCount(1); + canvas->save(); + canvas->clear(task.background_color); + canvas->scale(layer_tree.device_pixel_ratio() * task.scale_x, + layer_tree.device_pixel_ratio() * task.scale_y); + canvas->translate(-task.paint_bounds.left(), -task.paint_bounds.top()); + for (flutter::Layer* layer : task.layers) { + layer->Paint(paint_context); + } + } + + // Tell the surface producer that a present has occurred so it can perform + // book-keeping on buffer caches. + surface_producer_.OnSurfacesPresented(std::move(frame_surfaces)); } return flutter::RasterStatus::kSuccess; @@ -65,51 +140,14 @@ class ScopedFrame final : public flutter::CompositorContext::ScopedFrame { }; CompositorContext::CompositorContext( - std::string debug_label, - fuchsia::ui::views::ViewToken view_token, - scenic::ViewRefPair view_ref_pair, - fidl::InterfaceHandle session, - fml::closure session_error_callback, - zx_handle_t vsync_event_handle) - : debug_label_(std::move(debug_label)), - session_connection_( - debug_label_, - std::move(view_token), - std::move(view_ref_pair), - std::move(session), - session_error_callback, - [](auto) {}, - vsync_event_handle) {} - -void CompositorContext::OnSessionMetricsDidChange( - const fuchsia::ui::gfx::Metrics& metrics) { - session_connection_.set_metrics(metrics); -} + SessionConnection& session_connection, + VulkanSurfaceProducer& surface_producer, + flutter::SceneUpdateContext& scene_update_context) + : session_connection_(session_connection), + surface_producer_(surface_producer), + scene_update_context_(scene_update_context) {} -void CompositorContext::OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor) { - session_connection_.OnSessionSizeChangeHint(width_change_factor, - height_change_factor); -} - -void CompositorContext::OnWireframeEnabled(bool enabled) { - session_connection_.set_enable_wireframe(enabled); -} - -void CompositorContext::OnCreateView(int64_t view_id, - bool hit_testable, - bool focusable) { - session_connection_.scene_update_context().CreateView(view_id, hit_testable, - focusable); -} - -void CompositorContext::OnDestroyView(int64_t view_id) { - session_connection_.scene_update_context().DestroyView(view_id); -} - -CompositorContext::~CompositorContext() { - OnGrContextDestroyed(); -} +CompositorContext::~CompositorContext() = default; std::unique_ptr CompositorContext::AcquireFrame( @@ -120,16 +158,10 @@ CompositorContext::AcquireFrame( bool instrumentation_enabled, bool surface_supports_readback, fml::RefPtr raster_thread_merger) { - // TODO: The AcquireFrame interface is too broad and must be refactored to get - // rid of the context and canvas arguments as those seem to be only used for - // colorspace correctness purposes on the mobile shells. return std::make_unique( - *this, // - root_surface_transformation, // - view_embedder, - instrumentation_enabled, // - session_connection_ // - ); + *this, gr_context, canvas, view_embedder, root_surface_transformation, + instrumentation_enabled, surface_supports_readback, raster_thread_merger, + session_connection_, surface_producer_, scene_update_context_); } } // namespace flutter_runner diff --git a/shell/platform/fuchsia/flutter/compositor_context.h b/shell/platform/fuchsia/flutter/compositor_context.h index 2fdcb02ce963b..542e5d314fa71 100644 --- a/shell/platform/fuchsia/flutter/compositor_context.h +++ b/shell/platform/fuchsia/flutter/compositor_context.h @@ -5,15 +5,15 @@ #ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_COMPOSITOR_CONTEXT_H_ #define FLUTTER_SHELL_PLATFORM_FUCHSIA_COMPOSITOR_CONTEXT_H_ -#include -#include -#include -#include +#include #include "flutter/flow/compositor_context.h" #include "flutter/flow/embedded_views.h" +#include "flutter/flow/scene_update_context.h" #include "flutter/fml/macros.h" + #include "session_connection.h" +#include "vulkan_surface_producer.h" namespace flutter_runner { @@ -21,35 +21,16 @@ namespace flutter_runner { // Fuchsia. class CompositorContext final : public flutter::CompositorContext { public: - CompositorContext(std::string debug_label, - fuchsia::ui::views::ViewToken view_token, - scenic::ViewRefPair view_ref_pair, - fidl::InterfaceHandle session, - fml::closure session_error_callback, - zx_handle_t vsync_event_handle); + CompositorContext(SessionConnection& session_connection, + VulkanSurfaceProducer& surface_producer, + flutter::SceneUpdateContext& scene_update_context); ~CompositorContext() override; - void OnSessionMetricsDidChange(const fuchsia::ui::gfx::Metrics& metrics); - void OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor); - - void OnWireframeEnabled(bool enabled); - void OnCreateView(int64_t view_id, bool hit_testable, bool focusable); - void OnDestroyView(int64_t view_id); - - flutter::ExternalViewEmbedder* GetViewEmbedder() { - return &session_connection_.scene_update_context(); - } - - GrDirectContext* GetGrContext() { - return session_connection_.vulkan_surface_producer()->gr_context(); - } - private: - const std::string debug_label_; - scenic::ViewRefPair view_ref_pair_; - SessionConnection session_connection_; + SessionConnection& session_connection_; + VulkanSurfaceProducer& surface_producer_; + flutter::SceneUpdateContext& scene_update_context_; // |flutter::CompositorContext| std::unique_ptr AcquireFrame( diff --git a/shell/platform/fuchsia/flutter/engine.cc b/shell/platform/fuchsia/flutter/engine.cc index a23c488b64708..f7c9a251234f2 100644 --- a/shell/platform/fuchsia/flutter/engine.cc +++ b/shell/platform/fuchsia/flutter/engine.cc @@ -7,9 +7,6 @@ #include #include -#include - -#include "compositor_context.h" #include "flutter/common/task_runners.h" #include "flutter/fml/make_copyable.h" #include "flutter/fml/synchronization/waitable_event.h" @@ -17,18 +14,21 @@ #include "flutter/runtime/dart_vm_lifecycle.h" #include "flutter/shell/common/rasterizer.h" #include "flutter/shell/common/run_configuration.h" +#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" + +#include "../runtime/dart/utils/files.h" +#include "compositor_context.h" #include "flutter_runner_product_configuration.h" #include "fuchsia_intl.h" #include "platform_view.h" -#include "runtime/dart/utils/files.h" #include "task_runner_adapter.h" -#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" #include "thread.h" namespace flutter_runner { +namespace { -static void UpdateNativeThreadLabelNames(const std::string& label, - const flutter::TaskRunners& runners) { +void UpdateNativeThreadLabelNames(const std::string& label, + const flutter::TaskRunners& runners) { auto set_thread_name = [](fml::RefPtr runner, std::string prefix, std::string suffix) { if (!runner) { @@ -44,13 +44,15 @@ static void UpdateNativeThreadLabelNames(const std::string& label, set_thread_name(runners.GetIOTaskRunner(), label, ".io"); } -static fml::RefPtr MakeLocalizationPlatformMessage( +fml::RefPtr MakeLocalizationPlatformMessage( const fuchsia::intl::Profile& intl_profile) { return fml::MakeRefCounted( "flutter/localization", MakeLocalizationPlatformMessageData(intl_profile), nullptr); } +} // namespace + Engine::Engine(Delegate& delegate, std::string thread_label, std::shared_ptr svc, @@ -64,20 +66,24 @@ Engine::Engine(Delegate& delegate, FlutterRunnerProductConfiguration product_config) : delegate_(delegate), thread_label_(std::move(thread_label)), - settings_(std::move(settings)), weak_factory_(this) { if (zx::event::create(0, &vsync_event_) != ZX_OK) { FML_DLOG(ERROR) << "Could not create the vsync event."; return; } - // Launch the threads that will be used to run the shell. These threads will - // be joined in the destructor. - for (auto& thread : threads_) { - thread.reset(new Thread()); - } + // Get the task runners from the managed threads. The current thread will be + // used as the "platform" thread. + const flutter::TaskRunners task_runners( + thread_label_, // Dart thread labels + CreateFMLTaskRunner(async_get_default_dispatcher()), // platform + CreateFMLTaskRunner(threads_[0].dispatcher()), // raster + CreateFMLTaskRunner(threads_[1].dispatcher()), // ui + CreateFMLTaskRunner(threads_[2].dispatcher()) // io + ); + UpdateNativeThreadLabelNames(thread_label_, task_runners); - // Set up the session connection. + // Connect to Scenic. auto scenic = svc->Connect(); fidl::InterfaceHandle session; fidl::InterfaceHandle session_listener; @@ -86,8 +92,46 @@ Engine::Engine(Delegate& delegate, scenic->CreateSession2(session.NewRequest(), session_listener.Bind(), focuser.NewRequest()); - // Grab the parent environment services. The platform view may want to access - // some of these services. + // Make clones of the `ViewRef` before sending it down to Scenic. + fuchsia::ui::views::ViewRef platform_view_ref, isolate_view_ref; + view_ref_pair.view_ref.Clone(&platform_view_ref); + view_ref_pair.view_ref.Clone(&isolate_view_ref); + + // Session is terminated on the raster thread, but we must terminate ourselves + // on the platform thread. + // + // This handles the fidl error callback when the Session connection is + // broken. The SessionListener interface also has an OnError method, which is + // invoked on the platform thread (in PlatformView). + fml::closure session_error_callback = [dispatcher = + async_get_default_dispatcher(), + weak = weak_factory_.GetWeakPtr()]() { + async::PostTask(dispatcher, [weak]() { + if (weak) { + weak->Terminate(); + } + }); + }; + + // Set up the session connection and other Scenic helpers on the raster + // thread. + task_runners.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( + [this, session = std::move(session), + session_error_callback = std::move(session_error_callback), + view_token = std::move(view_token), + view_ref_pair = std::move(view_ref_pair), + vsync_handle = vsync_event_.get()]() mutable { + session_connection_.emplace( + thread_label_, std::move(session), + std::move(session_error_callback), [](auto) {}, vsync_handle); + surface_producer_.emplace(session_connection_->get()); + scene_update_context_.emplace(thread_label_, std::move(view_token), + std::move(view_ref_pair), + session_connection_.value()); + })); + + // Grab the parent environment services. The platform view may want to + // access some of these services. fuchsia::sys::EnvironmentPtr environment; svc->Connect(environment.NewRequest()); fidl::InterfaceHandle @@ -95,23 +139,15 @@ Engine::Engine(Delegate& delegate, environment->GetServices(parent_environment_service_provider.NewRequest()); environment.Unbind(); - // We need to manually schedule a frame when the session metrics change. - OnMetricsUpdate on_session_metrics_change_callback = std::bind( - &Engine::OnSessionMetricsDidChange, this, std::placeholders::_1); - - OnSizeChangeHint on_session_size_change_hint_callback = - std::bind(&Engine::OnSessionSizeChangeHint, this, std::placeholders::_1, - std::placeholders::_2); - OnEnableWireframe on_enable_wireframe_callback = std::bind( - &Engine::OnDebugWireframeSettingsChanged, this, std::placeholders::_1); + &Engine::DebugWireframeSettingsChanged, this, std::placeholders::_1); - flutter_runner::OnCreateView on_create_view_callback = - std::bind(&Engine::OnCreateView, this, std::placeholders::_1, + OnCreateView on_create_view_callback = + std::bind(&Engine::CreateView, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - flutter_runner::OnDestroyView on_destroy_view_callback = - std::bind(&Engine::OnDestroyView, this, std::placeholders::_1); + OnDestroyView on_destroy_view_callback = + std::bind(&Engine::DestroyView, this, std::placeholders::_1); OnGetViewEmbedder on_get_view_embedder_callback = std::bind(&Engine::GetViewEmbedder, this); @@ -132,10 +168,6 @@ Engine::Engine(Delegate& delegate, }); }; - fuchsia::ui::views::ViewRef platform_view_ref, isolate_view_ref; - view_ref_pair.view_ref.Clone(&platform_view_ref); - view_ref_pair.view_ref.Clone(&isolate_view_ref); - // Setup the callback that will instantiate the platform view. flutter::Shell::CreateCallback on_create_platform_view = fml::MakeCopyable( @@ -147,10 +179,6 @@ Engine::Engine(Delegate& delegate, focuser = std::move(focuser), on_session_listener_error_callback = std::move(on_session_listener_error_callback), - on_session_metrics_change_callback = - std::move(on_session_metrics_change_callback), - on_session_size_change_hint_callback = - std::move(on_session_size_change_hint_callback), on_enable_wireframe_callback = std::move(on_enable_wireframe_callback), on_create_view_callback = std::move(on_create_view_callback), @@ -170,8 +198,6 @@ Engine::Engine(Delegate& delegate, std::move(session_listener_request), // session listener std::move(focuser), std::move(on_session_listener_error_callback), - std::move(on_session_metrics_change_callback), - std::move(on_session_size_change_hint_callback), std::move(on_enable_wireframe_callback), std::move(on_create_view_callback), std::move(on_destroy_view_callback), @@ -181,70 +207,25 @@ Engine::Engine(Delegate& delegate, product_config); }); - // Session can be terminated on the raster thread, but we must terminate - // ourselves on the platform thread. - // - // This handles the fidl error callback when the Session connection is - // broken. The SessionListener interface also has an OnError method, which is - // invoked on the platform thread (in PlatformView). - fml::closure on_session_error_callback = - [dispatcher = async_get_default_dispatcher(), - weak = weak_factory_.GetWeakPtr()]() { - async::PostTask(dispatcher, [weak]() { - if (weak) { - weak->Terminate(); - } - }); - }; - - // Get the task runners from the managed threads. The current thread will be - // used as the "platform" thread. - const flutter::TaskRunners task_runners( - thread_label_, // Dart thread labels - CreateFMLTaskRunner(async_get_default_dispatcher()), // platform - CreateFMLTaskRunner(threads_[0]->dispatcher()), // raster - CreateFMLTaskRunner(threads_[1]->dispatcher()), // ui - CreateFMLTaskRunner(threads_[2]->dispatcher()) // io - ); - // Setup the callback that will instantiate the rasterizer. flutter::Shell::CreateCallback on_create_rasterizer = - fml::MakeCopyable([thread_label = thread_label_, // - view_token = std::move(view_token), // - view_ref_pair = std::move(view_ref_pair), // - session = std::move(session), // - on_session_error_callback, // - vsync_event = vsync_event_.get() // - ](flutter::Shell& shell) mutable { - std::unique_ptr compositor_context; - { - TRACE_DURATION("flutter", "CreateCompositorContext"); - compositor_context = - std::make_unique( - thread_label, // debug label - std::move(view_token), // scenic view we attach our tree to - std::move(view_ref_pair), // scenic view ref/view ref control - std::move(session), // scenic session - on_session_error_callback, // session did encounter error - vsync_event); // vsync event handle - } + fml::MakeCopyable([this](flutter::Shell& shell) mutable { + FML_DCHECK(session_connection_); + FML_DCHECK(surface_producer_); + FML_DCHECK(scene_update_context_); + + std::unique_ptr compositor_context = + std::make_unique( + session_connection_.value(), surface_producer_.value(), + scene_update_context_.value()); return std::make_unique( shell, std::move(compositor_context)); }); - UpdateNativeThreadLabelNames(thread_label_, task_runners); - - settings_.verbose_logging = true; - - settings_.advisory_script_uri = thread_label_; - - settings_.advisory_script_entrypoint = thread_label_; - - settings_.root_isolate_create_callback = + settings.root_isolate_create_callback = std::bind(&Engine::OnMainIsolateStart, this); - - settings_.root_isolate_shutdown_callback = + settings.root_isolate_shutdown_callback = std::bind([weak = weak_factory_.GetWeakPtr(), runner = task_runners.GetPlatformTaskRunner()]() { runner->PostTask([weak = std::move(weak)] { @@ -254,7 +235,7 @@ Engine::Engine(Delegate& delegate, }); }); - auto vm = flutter::DartVMRef::Create(settings_); + auto vm = flutter::DartVMRef::Create(settings); if (!isolate_snapshot) { isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot(); @@ -263,13 +244,13 @@ Engine::Engine(Delegate& delegate, { TRACE_EVENT0("flutter", "CreateShell"); shell_ = flutter::Shell::Create( - task_runners, // host task runners - flutter::PlatformData(), // default window data - settings_, // shell launch settings - std::move(isolate_snapshot), // isolate snapshot - on_create_platform_view, // platform view create callback - on_create_rasterizer, // rasterizer create callback - std::move(vm) // vm reference + std::move(task_runners), // host task runners + flutter::PlatformData(), // default window data + std::move(settings), // shell launch settings + std::move(isolate_snapshot), // isolate snapshot + std::move(on_create_platform_view), // platform view create callback + std::move(on_create_rasterizer), // rasterizer create callback + std::move(vm) // vm reference ); } @@ -346,7 +327,7 @@ Engine::Engine(Delegate& delegate, // Launch the engine in the appropriate configuration. auto run_configuration = flutter::RunConfiguration::InferFromSettings( - settings_, task_runners.GetIOTaskRunner()); + shell_->GetSettings(), shell_->GetTaskRunners().GetIOTaskRunner()); auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() { // The engine could have been killed by the caller right after the @@ -383,11 +364,11 @@ Engine::Engine(Delegate& delegate, Engine::~Engine() { shell_.reset(); - for (const auto& thread : threads_) { - thread->Quit(); + for (auto& thread : threads_) { + thread.Quit(); } - for (const auto& thread : threads_) { - thread->Join(); + for (auto& thread : threads_) { + thread.Join(); } } @@ -492,105 +473,41 @@ void Engine::Terminate() { // collected this object. } -void Engine::OnSessionMetricsDidChange( - const fuchsia::ui::gfx::Metrics& metrics) { - if (!shell_) { +void Engine::DebugWireframeSettingsChanged(bool enabled) { + if (!shell_ || !scene_update_context_) { return; } shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [rasterizer = shell_->GetRasterizer(), metrics]() { - if (rasterizer) { - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - - compositor_context->OnSessionMetricsDidChange(metrics); - } - }); + [this, enabled]() { scene_update_context_->EnableWireframe(enabled); }); } -void Engine::OnDebugWireframeSettingsChanged(bool enabled) { - if (!shell_) { +void Engine::CreateView(int64_t view_id, bool hit_testable, bool focusable) { + if (!shell_ || !scene_update_context_) { return; } shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [rasterizer = shell_->GetRasterizer(), enabled]() { - if (rasterizer) { - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - - compositor_context->OnWireframeEnabled(enabled); - } + [this, view_id, hit_testable, focusable]() { + scene_update_context_->CreateView(view_id, hit_testable, focusable); }); } -void Engine::OnCreateView(int64_t view_id, bool hit_testable, bool focusable) { - if (!shell_) { +void Engine::DestroyView(int64_t view_id) { + if (!shell_ || !scene_update_context_) { return; } shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [rasterizer = shell_->GetRasterizer(), view_id, hit_testable, - focusable]() { - if (rasterizer) { - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - compositor_context->OnCreateView(view_id, hit_testable, focusable); - } - }); -} - -void Engine::OnDestroyView(int64_t view_id) { - if (!shell_) { - return; - } - - shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [rasterizer = shell_->GetRasterizer(), view_id]() { - if (rasterizer) { - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - compositor_context->OnDestroyView(view_id); - } - }); + [this, view_id]() { scene_update_context_->DestroyView(view_id); }); } flutter::ExternalViewEmbedder* Engine::GetViewEmbedder() { - // GetEmbedder should be called only after rasterizer is created. - FML_DCHECK(shell_); - FML_DCHECK(shell_->GetRasterizer()); - - auto rasterizer = shell_->GetRasterizer(); - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - flutter::ExternalViewEmbedder* view_embedder = - compositor_context->GetViewEmbedder(); - return view_embedder; -} - -void Engine::OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor) { - if (!shell_) { - return; + if (!scene_update_context_) { + return nullptr; } - shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [rasterizer = shell_->GetRasterizer(), width_change_factor, - height_change_factor]() { - if (rasterizer) { - auto compositor_context = reinterpret_cast( - rasterizer->compositor_context()); - - compositor_context->OnSessionSizeChangeHint(width_change_factor, - height_change_factor); - } - }); + return &scene_update_context_.value(); } GrDirectContext* Engine::GetGrContext() { @@ -598,12 +515,7 @@ GrDirectContext* Engine::GetGrContext() { FML_DCHECK(shell_); FML_DCHECK(shell_->GetRasterizer()); - auto rasterizer = shell_->GetRasterizer(); - auto compositor_context = - reinterpret_cast( - rasterizer->compositor_context()); - GrDirectContext* gr_context = compositor_context->GetGrContext(); - return gr_context; + return surface_producer_->gr_context(); } #if !defined(DART_PRODUCT) diff --git a/shell/platform/fuchsia/flutter/engine.h b/shell/platform/fuchsia/flutter/engine.h index 70e9373cb5de5..dfd0026608dd2 100644 --- a/shell/platform/fuchsia/flutter/engine.h +++ b/shell/platform/fuchsia/flutter/engine.h @@ -15,11 +15,15 @@ #include #include "flutter/flow/embedded_views.h" +#include "flutter/flow/scene_update_context.h" #include "flutter/fml/macros.h" #include "flutter/shell/common/shell.h" + #include "flutter_runner_product_configuration.h" #include "isolate_configurator.h" +#include "session_connection.h" #include "thread.h" +#include "vulkan_surface_producer.h" namespace flutter_runner { @@ -55,15 +59,22 @@ class Engine final { private: Delegate& delegate_; + const std::string thread_label_; - flutter::Settings settings_; - std::array, 3> threads_; + std::array threads_; + + std::optional session_connection_; + std::optional surface_producer_; + std::optional scene_update_context_; + std::unique_ptr isolate_configurator_; std::unique_ptr shell_; + + fuchsia::intl::PropertyProviderPtr intl_property_provider_; + zx::event vsync_event_; + fml::WeakPtrFactory weak_factory_; - // A stub for the FIDL protocol fuchsia.intl.PropertyProvider. - fuchsia::intl::PropertyProviderPtr intl_property_provider_; void OnMainIsolateStart(); @@ -71,15 +82,9 @@ class Engine final { void Terminate(); - void OnSessionMetricsDidChange(const fuchsia::ui::gfx::Metrics& metrics); - void OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor); - - void OnDebugWireframeSettingsChanged(bool enabled); - - void OnCreateView(int64_t view_id, bool hit_testable, bool focusable); - - void OnDestroyView(int64_t view_id); + void DebugWireframeSettingsChanged(bool enabled); + void CreateView(int64_t view_id, bool hit_testable, bool focusable); + void DestroyView(int64_t view_id); flutter::ExternalViewEmbedder* GetViewEmbedder(); diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index 69fd116c5a25c..ac7e2635bb529 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -6,6 +6,7 @@ #include "platform_view.h" +#include #include #include "flutter/fml/logging.h" @@ -22,41 +23,6 @@ namespace flutter_runner { -namespace { - -inline fuchsia::ui::gfx::vec3 Add(const fuchsia::ui::gfx::vec3& a, - const fuchsia::ui::gfx::vec3& b) { - return {.x = a.x + b.x, .y = a.y + b.y, .z = a.z + b.z}; -} - -inline fuchsia::ui::gfx::vec3 Subtract(const fuchsia::ui::gfx::vec3& a, - const fuchsia::ui::gfx::vec3& b) { - return {.x = a.x - b.x, .y = a.y - b.y, .z = a.z - b.z}; -} - -inline fuchsia::ui::gfx::BoundingBox InsetBy( - const fuchsia::ui::gfx::BoundingBox& box, - const fuchsia::ui::gfx::vec3& inset_from_min, - const fuchsia::ui::gfx::vec3& inset_from_max) { - return {.min = Add(box.min, inset_from_min), - .max = Subtract(box.max, inset_from_max)}; -} - -inline fuchsia::ui::gfx::BoundingBox ViewPropertiesLayoutBox( - const fuchsia::ui::gfx::ViewProperties& view_properties) { - return InsetBy(view_properties.bounding_box, view_properties.inset_from_min, - view_properties.inset_from_max); -} - -inline fuchsia::ui::gfx::vec3 Max(const fuchsia::ui::gfx::vec3& v, - float min_val) { - return {.x = std::max(v.x, min_val), - .y = std::max(v.y, min_val), - .z = std::max(v.z, min_val)}; -} - -} // end namespace - static constexpr char kFlutterPlatformChannel[] = "flutter/platform"; static constexpr char kTextInputChannel[] = "flutter/textinput"; static constexpr char kKeyEventChannel[] = "flutter/keyevent"; @@ -90,8 +56,6 @@ PlatformView::PlatformView( session_listener_request, fidl::InterfaceHandle focuser, fit::closure session_listener_error_callback, - OnMetricsUpdate session_metrics_did_change_callback, - OnSizeChangeHint session_size_change_hint_callback, OnEnableWireframe wireframe_enabled_callback, OnCreateView on_create_view_callback, OnDestroyView on_destroy_view_callback, @@ -106,8 +70,6 @@ PlatformView::PlatformView( session_listener_binding_(this, std::move(session_listener_request)), session_listener_error_callback_( std::move(session_listener_error_callback)), - metrics_changed_callback_(std::move(session_metrics_did_change_callback)), - size_change_hint_callback_(std::move(session_size_change_hint_callback)), wireframe_enabled_callback_(std::move(wireframe_enabled_callback)), on_create_view_callback_(std::move(on_create_view_callback)), on_destroy_view_callback_(std::move(on_destroy_view_callback)), @@ -156,64 +118,6 @@ void PlatformView::RegisterPlatformMessageHandlers() { this, std::placeholders::_1); } -void PlatformView::OnPropertiesChanged( - const fuchsia::ui::gfx::ViewProperties& view_properties) { - fuchsia::ui::gfx::BoundingBox layout_box = - ViewPropertiesLayoutBox(view_properties); - - fuchsia::ui::gfx::vec3 logical_size = - Max(Subtract(layout_box.max, layout_box.min), 0.f); - - metrics_.size.width = logical_size.x; - metrics_.size.height = logical_size.y; - metrics_.size.depth = logical_size.z; - metrics_.padding.left = view_properties.inset_from_min.x; - metrics_.padding.top = view_properties.inset_from_min.y; - metrics_.padding.front = view_properties.inset_from_min.z; - metrics_.padding.right = view_properties.inset_from_max.x; - metrics_.padding.bottom = view_properties.inset_from_max.y; - metrics_.padding.back = view_properties.inset_from_max.z; - - FlushViewportMetrics(); -} - -// TODO(SCN-975): Re-enable. -// void PlatformView::ConnectSemanticsProvider( -// fuchsia::ui::viewsv1token::ViewToken token) { -// semantics_bridge_.SetupEnvironment( -// token.value, parent_environment_service_provider_.get()); -// } - -void PlatformView::UpdateViewportMetrics( - const fuchsia::ui::gfx::Metrics& metrics) { - metrics_.scale = metrics.scale_x; - metrics_.scale_z = metrics.scale_z; - - FlushViewportMetrics(); -} - -void PlatformView::FlushViewportMetrics() { - const auto scale = metrics_.scale; - const auto scale_z = metrics_.scale_z; - - SetViewportMetrics({ - scale, // device_pixel_ratio - metrics_.size.width * scale, // physical_width - metrics_.size.height * scale, // physical_height - metrics_.size.depth * scale_z, // physical_depth - metrics_.padding.top * scale, // physical_padding_top - metrics_.padding.right * scale, // physical_padding_right - metrics_.padding.bottom * scale, // physical_padding_bottom - metrics_.padding.left * scale, // physical_padding_left - metrics_.view_inset.front * scale_z, // physical_view_inset_front - metrics_.view_inset.back * scale_z, // physical_view_inset_back - metrics_.view_inset.top * scale, // physical_view_inset_top - metrics_.view_inset.right * scale, // physical_view_inset_right - metrics_.view_inset.bottom * scale, // physical_view_inset_bottom - metrics_.view_inset.left * scale // physical_view_inset_left - }); -} - // |fuchsia::ui::input::InputMethodEditorClient| void PlatformView::DidUpdateState( fuchsia::ui::input::TextInputState state, @@ -306,27 +210,40 @@ void PlatformView::OnScenicError(std::string error) { void PlatformView::OnScenicEvent( std::vector events) { TRACE_EVENT0("flutter", "PlatformView::OnScenicEvent"); + bool should_update_metrics = false; for (const auto& event : events) { switch (event.Which()) { case fuchsia::ui::scenic::Event::Tag::kGfx: switch (event.gfx().Which()) { case fuchsia::ui::gfx::Event::Tag::kMetrics: { - if (!fidl::Equals(event.gfx().metrics().metrics, scenic_metrics_)) { - scenic_metrics_ = std::move(event.gfx().metrics().metrics); - metrics_changed_callback_(scenic_metrics_); - UpdateViewportMetrics(scenic_metrics_); + const fuchsia::ui::gfx::Metrics& metrics = + event.gfx().metrics().metrics; + const float new_view_pixel_ratio = metrics.scale_x; + + // Avoid metrics update when possible -- it is computationally + // expensive. + if (view_pixel_ratio_ != new_view_pixel_ratio) { + view_pixel_ratio_ = new_view_pixel_ratio; + should_update_metrics = true; } break; } - case fuchsia::ui::gfx::Event::Tag::kSizeChangeHint: { - size_change_hint_callback_( - event.gfx().size_change_hint().width_change_factor, - event.gfx().size_change_hint().height_change_factor); - break; - } case fuchsia::ui::gfx::Event::Tag::kViewPropertiesChanged: { - OnPropertiesChanged( - std::move(event.gfx().view_properties_changed().properties)); + const fuchsia::ui::gfx::BoundingBox& bounding_box = + event.gfx().view_properties_changed().properties.bounding_box; + const float new_view_width = + std::max(bounding_box.max.x - bounding_box.min.x, 0.0f); + const float new_view_height = + std::max(bounding_box.max.y - bounding_box.min.y, 0.0f); + + // Avoid metrics update when possible -- it is computationally + // expensive. + if (view_width_ != new_view_width || + view_height_ != new_view_width) { + view_width_ = new_view_width; + view_height_ = new_view_height; + should_update_metrics = true; + } break; } case fuchsia::ui::gfx::Event::Tag::kViewConnected: @@ -376,6 +293,26 @@ void PlatformView::OnScenicEvent( } } } + + if (should_update_metrics) { + SetViewportMetrics({ + view_pixel_ratio_, // device_pixel_ratio + view_width_ * view_pixel_ratio_, // physical_width + view_height_ * view_pixel_ratio_, // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left + }); + } } void PlatformView::OnChildViewConnected(scenic::ResourceId view_holder_id) { @@ -455,8 +392,9 @@ bool PlatformView::OnHandlePointerEvent( pointer_data.change = GetChangeFromPointerEventPhase(pointer.phase); pointer_data.kind = GetKindFromPointerType(pointer.type); pointer_data.device = pointer.pointer_id; - pointer_data.physical_x = pointer.x * metrics_.scale; - pointer_data.physical_y = pointer.y * metrics_.scale; + // Pointer events are in logical pixels, so scale to physical. + pointer_data.physical_x = pointer.x * view_pixel_ratio_; + pointer_data.physical_y = pointer.y * view_pixel_ratio_; // Buttons are single bit values starting with kMousePrimaryButton = 1. pointer_data.buttons = static_cast(pointer.buttons); diff --git a/shell/platform/fuchsia/flutter/platform_view.h b/shell/platform/fuchsia/flutter/platform_view.h index 5e9edf50dcd3f..0e45b8d7712cf 100644 --- a/shell/platform/fuchsia/flutter/platform_view.h +++ b/shell/platform/fuchsia/flutter/platform_view.h @@ -5,7 +5,6 @@ #ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_PLATFORM_VIEW_H_ #define FLUTTER_SHELL_PLATFORM_FUCHSIA_PLATFORM_VIEW_H_ -#include #include #include #include @@ -14,7 +13,6 @@ #include #include "flutter/fml/macros.h" -#include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/shell/common/platform_view.h" #include "flutter/shell/platform/fuchsia/flutter/accessibility_bridge.h" #include "flutter_runner_product_configuration.h" @@ -24,9 +22,6 @@ namespace flutter_runner { -using OnMetricsUpdate = fit::function; -using OnSizeChangeHint = - fit::function; using OnEnableWireframe = fit::function; using OnCreateView = fit::function; using OnDestroyView = fit::function; @@ -55,8 +50,6 @@ class PlatformView final : public flutter::PlatformView, session_listener_request, fidl::InterfaceHandle focuser, fit::closure on_session_listener_error_callback, - OnMetricsUpdate session_metrics_did_change_callback, - OnSizeChangeHint session_size_change_hint_callback, OnEnableWireframe wireframe_enabled_callback, OnCreateView on_create_view_callback, OnDestroyView on_destroy_view_callback, @@ -64,17 +57,9 @@ class PlatformView final : public flutter::PlatformView, OnGetGrContext on_get_gr_context_callback, zx_handle_t vsync_event_handle, FlutterRunnerProductConfiguration product_config); - PlatformView(flutter::PlatformView::Delegate& delegate, - std::string debug_label, - flutter::TaskRunners task_runners, - fidl::InterfaceHandle - parent_environment_service_provider, - zx_handle_t vsync_event_handle); ~PlatformView(); - void UpdateViewportMetrics(const fuchsia::ui::gfx::Metrics& metrics); - // |flutter::PlatformView| // |flutter_runner::AccessibilityBridge::Delegate| void SetSemanticsEnabled(bool enabled) override; @@ -96,8 +81,6 @@ class PlatformView final : public flutter::PlatformView, fidl::Binding session_listener_binding_; fit::closure session_listener_error_callback_; - OnMetricsUpdate metrics_changed_callback_; - OnSizeChangeHint size_change_hint_callback_; OnEnableWireframe wireframe_enabled_callback_; OnCreateView on_create_view_callback_; OnDestroyView on_destroy_view_callback_; @@ -110,8 +93,7 @@ class PlatformView final : public flutter::PlatformView, fuchsia::ui::input::ImeServicePtr text_sync_service_; fuchsia::sys::ServiceProviderPtr parent_environment_service_provider_; - flutter::LogicalMetrics metrics_; - fuchsia::ui::gfx::Metrics scenic_metrics_; + // last_text_state_ is the last state of the text input as reported by the IME // or initialized by Flutter. We set it to null if Flutter doesn't want any // input, since then there is no text input state at all. @@ -129,16 +111,14 @@ class PlatformView final : public flutter::PlatformView, std::set unregistered_channels_; zx_handle_t vsync_event_handle_ = 0; + float view_width_ = 0.0f; // Width in logical pixels. + float view_height_ = 0.0f; // Height in logical pixels. + float view_pixel_ratio_ = 0.0f; // Logical / physical pixel ratio. + FlutterRunnerProductConfiguration product_config_; void RegisterPlatformMessageHandlers(); - void FlushViewportMetrics(); - - // Called when the view's properties have changed. - void OnPropertiesChanged( - const fuchsia::ui::gfx::ViewProperties& view_properties); - // |fuchsia::ui::input::InputMethodEditorClient| void DidUpdateState( fuchsia::ui::input::TextInputState state, diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 0144efd8e3c8b..731a0c55e1346 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -4,7 +4,7 @@ #include "flutter/shell/platform/fuchsia/flutter/platform_view.h" -#include +#include #include #include #include @@ -15,11 +15,11 @@ #include #include -#include "flutter/flow/scene_update_context.h" +#include "flutter/flow/embedded_views.h" #include "flutter/lib/ui/window/platform_message.h" #include "flutter/lib/ui/window/window.h" -#include "fuchsia/ui/views/cpp/fidl.h" #include "gtest/gtest.h" + #include "task_runner_adapter.h" namespace flutter_runner_test::flutter_runner_a11y_test { @@ -41,6 +41,33 @@ class PlatformViewTests : public testing::Test { FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewTests); }; +class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { + public: + MockExternalViewEmbedder() = default; + ~MockExternalViewEmbedder() override = default; + + SkCanvas* GetRootCanvas() override { return nullptr; } + std::vector GetCurrentCanvases() override { + return std::vector(); + } + + void CancelFrame() override {} + void BeginFrame( + SkISize frame_size, + GrDirectContext* context, + double device_pixel_ratio, + fml::RefPtr raster_thread_merger) override {} + void SubmitFrame(GrDirectContext* context, + std::unique_ptr frame) override { + return; + } + + void PrerollCompositeEmbeddedView( + int view_id, + std::unique_ptr params) override {} + SkCanvas* CompositeEmbeddedView(int view_id) override { return nullptr; } +}; + class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { public: // |flutter::PlatformView::Delegate| @@ -100,30 +127,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { int32_t semantics_features_ = 0; }; -class MockSurfaceProducer - : public flutter::SceneUpdateContext::SurfaceProducer { - public: - std::unique_ptr - ProduceSurface(const SkISize& size, - const flutter::LayerRasterCacheKey& layer_key, - std::unique_ptr entity_node) override { - return nullptr; - } - - bool HasRetainedNode(const flutter::LayerRasterCacheKey& key) const override { - return false; - } - - scenic::EntityNode* GetRetainedNode( - const flutter::LayerRasterCacheKey& key) override { - return nullptr; - } - - void SubmitSurface( - std::unique_ptr - surface) override {} -}; - class MockFocuser : public fuchsia::ui::views::Focuser { public: MockFocuser() = default; @@ -163,8 +166,6 @@ TEST_F(PlatformViewTests, ChangesAccessibilitySettings) { nullptr, // session_listener_request nullptr, // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, nullptr, // on_destroy_view_callback, @@ -221,8 +222,6 @@ TEST_F(PlatformViewTests, EnableWireframeTest) { nullptr, // session_listener_request nullptr, // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback EnableWireframeCallback, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, nullptr, // on_destroy_view_callback, @@ -290,8 +289,6 @@ TEST_F(PlatformViewTests, CreateViewTest) { nullptr, // session_listener_request nullptr, // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, CreateViewCallback, // on_create_view_callback, nullptr, // on_destroy_view_callback, @@ -361,8 +358,6 @@ TEST_F(PlatformViewTests, DestroyViewTest) { nullptr, // session_listener_request nullptr, // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, DestroyViewCallback, // on_destroy_view_callback, @@ -426,8 +421,6 @@ TEST_F(PlatformViewTests, RequestFocusTest) { nullptr, // session_listener_request std::move(focuser_handle), // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, nullptr, // on_destroy_view_callback, @@ -485,11 +478,8 @@ TEST_F(PlatformViewTests, GetViewEmbedderTest) { ); // Test get view embedder callback function. - MockSurfaceProducer surfaceProducer; - flutter::SceneUpdateContext scene_update_context(nullptr, &surfaceProducer); - flutter::ExternalViewEmbedder* view_embedder = - reinterpret_cast(&scene_update_context); - auto GetViewEmbedderCallback = [view_embedder]() { return view_embedder; }; + MockExternalViewEmbedder view_embedder; + auto GetViewEmbedderCallback = [&view_embedder]() { return &view_embedder; }; auto platform_view = flutter_runner::PlatformView( delegate, // delegate @@ -501,8 +491,6 @@ TEST_F(PlatformViewTests, GetViewEmbedderTest) { nullptr, // session_listener_request nullptr, // focuser, nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, nullptr, // on_destroy_view_callback, @@ -518,7 +506,7 @@ TEST_F(PlatformViewTests, GetViewEmbedderTest) { RunLoopUntilIdle(); - EXPECT_EQ(view_embedder, delegate.get_view_embedder()); + EXPECT_EQ(&view_embedder, delegate.get_view_embedder()); } // Test to make sure that PlatformView correctly returns a Surface instance @@ -557,8 +545,6 @@ TEST_F(PlatformViewTests, GetGrContextTest) { nullptr, // session_listener_request nullptr, // focuser nullptr, // on_session_listener_error_callback - nullptr, // session_metrics_did_change_callback - nullptr, // session_size_change_hint_callback nullptr, // on_enable_wireframe_callback, nullptr, // on_create_view_callback, nullptr, // on_destroy_view_callback, diff --git a/shell/platform/fuchsia/flutter/session_connection.cc b/shell/platform/fuchsia/flutter/session_connection.cc index 133dc9a43b8be..c87368a8993b9 100644 --- a/shell/platform/fuchsia/flutter/session_connection.cc +++ b/shell/platform/fuchsia/flutter/session_connection.cc @@ -5,8 +5,8 @@ #include "session_connection.h" #include "flutter/fml/make_copyable.h" -#include "lib/fidl/cpp/optional.h" -#include "lib/ui/scenic/cpp/commands.h" +#include "flutter/fml/trace_event.h" + #include "vsync_recorder.h" #include "vsync_waiter.h" @@ -14,23 +14,11 @@ namespace flutter_runner { SessionConnection::SessionConnection( std::string debug_label, - fuchsia::ui::views::ViewToken view_token, - scenic::ViewRefPair view_ref_pair, fidl::InterfaceHandle session, fml::closure session_error_callback, on_frame_presented_event on_frame_presented_callback, zx_handle_t vsync_event_handle) - : debug_label_(std::move(debug_label)), - session_wrapper_(session.Bind(), nullptr), - root_view_(&session_wrapper_, - std::move(view_token), - std::move(view_ref_pair.control_ref), - std::move(view_ref_pair.view_ref), - debug_label), - root_node_(&session_wrapper_), - surface_producer_( - std::make_unique(&session_wrapper_)), - scene_update_context_(&session_wrapper_, surface_producer_.get()), + : session_wrapper_(session.Bind(), nullptr), on_frame_presented_callback_(std::move(on_frame_presented_callback)), vsync_event_handle_(vsync_event_handle) { session_wrapper_.set_error_handler( @@ -63,11 +51,7 @@ SessionConnection::SessionConnection( } // callback ); - session_wrapper_.SetDebugName(debug_label_); - - root_view_.AddChild(root_node_); - root_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask | - fuchsia::ui::gfx::kSizeChangeHintEventMask); + session_wrapper_.SetDebugName(debug_label); // Get information to finish initialization and only then allow Present()s. session_wrapper_.RequestPresentationTimes( @@ -91,8 +75,7 @@ SessionConnection::SessionConnection( SessionConnection::~SessionConnection() = default; -void SessionConnection::Present( - flutter::CompositorContext::ScopedFrame* frame) { +void SessionConnection::Present() { TRACE_EVENT0("gfx", "SessionConnection::Present"); TRACE_FLOW_BEGIN("gfx", "SessionConnection::PresentSession", @@ -114,21 +97,6 @@ void SessionConnection::Present( present_session_pending_ = true; ToggleSignal(vsync_event_handle_, false); } - - if (frame) { - // Execute paint tasks and signal fences. - auto surfaces_to_submit = scene_update_context_.ExecutePaintTasks(*frame); - - // Tell the surface producer that a present has occurred so it can perform - // book-keeping on buffer caches. - surface_producer_->OnSurfacesPresented(std::move(surfaces_to_submit)); - } -} - -void SessionConnection::OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor) { - surface_producer_->OnSessionSizeChangeHint(width_change_factor, - height_change_factor); } fml::TimePoint SessionConnection::CalculateNextLatchPoint( @@ -160,17 +128,6 @@ fml::TimePoint SessionConnection::CalculateNextLatchPoint( return minimum_latch_point_to_target; } -void SessionConnection::set_enable_wireframe(bool enable) { - session_wrapper_.Enqueue( - scenic::NewSetEnableDebugViewBoundsCmd(root_view_.id(), enable)); -} - -void SessionConnection::EnqueueClearOps() { - // We are going to be sending down a fresh node hierarchy every frame. So just - // enqueue a detach op on the imported root node. - session_wrapper_.Enqueue(scenic::NewDetachChildrenCmd(root_node_.id())); -} - void SessionConnection::PresentSession() { TRACE_EVENT0("gfx", "SessionConnection::PresentSession"); @@ -232,10 +189,6 @@ void SessionConnection::PresentSession() { VsyncRecorder::GetInstance().UpdateNextPresentationInfo( std::move(info)); }); - - // Prepare for the next frame. These ops won't be processed till the next - // present. - EnqueueClearOps(); } void SessionConnection::ToggleSignal(zx_handle_t handle, bool set) { diff --git a/shell/platform/fuchsia/flutter/session_connection.h b/shell/platform/fuchsia/flutter/session_connection.h index dcd55f19afbf4..7630d15e77837 100644 --- a/shell/platform/fuchsia/flutter/session_connection.h +++ b/shell/platform/fuchsia/flutter/session_connection.h @@ -5,22 +5,14 @@ #ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_SESSION_CONNECTION_H_ #define FLUTTER_SHELL_PLATFORM_FUCHSIA_SESSION_CONNECTION_H_ -#include +#include #include -#include #include -#include -#include -#include #include -#include -#include "flutter/flow/compositor_context.h" #include "flutter/flow/scene_update_context.h" #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" -#include "flutter/fml/trace_event.h" -#include "vulkan_surface_producer.h" namespace flutter_runner { @@ -29,11 +21,9 @@ using on_frame_presented_event = // The component residing on the raster thread that is responsible for // maintaining the Scenic session connection and presenting node updates. -class SessionConnection final { +class SessionConnection final : public flutter::SessionWrapper { public: SessionConnection(std::string debug_label, - fuchsia::ui::views::ViewToken view_token, - scenic::ViewRefPair view_ref_pair, fidl::InterfaceHandle session, fml::closure session_error_callback, on_frame_presented_event on_frame_presented_callback, @@ -41,36 +31,8 @@ class SessionConnection final { ~SessionConnection(); - bool has_metrics() const { return scene_update_context_.has_metrics(); } - - const fuchsia::ui::gfx::MetricsPtr& metrics() const { - return scene_update_context_.metrics(); - } - - void set_metrics(const fuchsia::ui::gfx::Metrics& metrics) { - fuchsia::ui::gfx::Metrics metrics_copy; - metrics.Clone(&metrics_copy); - scene_update_context_.set_metrics( - fidl::MakeOptional(std::move(metrics_copy))); - } - - void set_enable_wireframe(bool enable); - - flutter::SceneUpdateContext& scene_update_context() { - return scene_update_context_; - } - - scenic::ContainerNode& root_node() { return root_node_; } - scenic::View* root_view() { return &root_view_; } - - void Present(flutter::CompositorContext::ScopedFrame* frame); - - void OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor); - - VulkanSurfaceProducer* vulkan_surface_producer() { - return surface_producer_.get(); - } + scenic::Session* get() override { return &session_wrapper_; } + void Present() override; static fml::TimePoint CalculateNextLatchPoint( fml::TimePoint present_requested_time, @@ -82,14 +44,8 @@ class SessionConnection final { future_presentation_infos); private: - const std::string debug_label_; scenic::Session session_wrapper_; - scenic::View root_view_; - scenic::EntityNode root_node_; - - std::unique_ptr surface_producer_; - flutter::SceneUpdateContext scene_update_context_; on_frame_presented_event on_frame_presented_callback_; zx_handle_t vsync_event_handle_; @@ -122,8 +78,6 @@ class SessionConnection final { bool present_session_pending_ = false; - void EnqueueClearOps(); - void PresentSession(); static void ToggleSignal(zx_handle_t handle, bool raise); diff --git a/shell/platform/fuchsia/flutter/tests/session_connection_unittests.cc b/shell/platform/fuchsia/flutter/tests/session_connection_unittests.cc index 87efa11e95f2a..5a5463266faa8 100644 --- a/shell/platform/fuchsia/flutter/tests/session_connection_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/session_connection_unittests.cc @@ -2,18 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "gtest/gtest.h" - +#include +#include +#include #include #include -#include - -#include -#include #include "flutter/shell/platform/fuchsia/flutter/logging.h" #include "flutter/shell/platform/fuchsia/flutter/runner.h" #include "flutter/shell/platform/fuchsia/flutter/session_connection.h" +#include "gtest/gtest.h" using namespace flutter_runner; @@ -30,12 +28,8 @@ class SessionConnectionTest : public ::testing::Test { loop_.StartThread("SessionConnectionTestThread", &fidl_thread_)); auto session_listener_request = session_listener_.NewRequest(); - auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); - view_token_ = std::move(view_token); scenic_->CreateSession(session_.NewRequest(), session_listener_.Bind()); - presenter_->PresentOrReplaceView(std::move(view_holder_token), nullptr); - FML_CHECK(zx::event::create(0, &vsync_event_) == ZX_OK); // Ensure Scenic has had time to wake up before the test logic begins. @@ -60,7 +54,6 @@ class SessionConnectionTest : public ::testing::Test { fidl::InterfaceHandle session_; fidl::InterfaceHandle session_listener_; - fuchsia::ui::views::ViewToken view_token_; zx::event vsync_event_; thrd_t fidl_thread_; }; @@ -76,12 +69,11 @@ TEST_F(SessionConnectionTest, SimplePresentTest) { }; flutter_runner::SessionConnection session_connection( - "debug label", std::move(view_token_), scenic::ViewRefPair::New(), - std::move(session_), on_session_error_callback, + "debug label", std::move(session_), on_session_error_callback, on_frame_presented_callback, vsync_event_.get()); for (int i = 0; i < 200; ++i) { - session_connection.Present(nullptr); + session_connection.Present(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } @@ -99,12 +91,11 @@ TEST_F(SessionConnectionTest, BatchedPresentTest) { }; flutter_runner::SessionConnection session_connection( - "debug label", std::move(view_token_), scenic::ViewRefPair::New(), - std::move(session_), on_session_error_callback, + "debug label", std::move(session_), on_session_error_callback, on_frame_presented_callback, vsync_event_.get()); for (int i = 0; i < 200; ++i) { - session_connection.Present(nullptr); + session_connection.Present(); if (i % 10 == 9) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); } diff --git a/shell/platform/fuchsia/flutter/vulkan_surface.h b/shell/platform/fuchsia/flutter/vulkan_surface.h index e6b7eb4e8943a..bff2713a011c9 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface.h +++ b/shell/platform/fuchsia/flutter/vulkan_surface.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -12,17 +13,46 @@ #include #include "flutter/flow/raster_cache_key.h" -#include "flutter/flow/scene_update_context.h" #include "flutter/fml/macros.h" #include "flutter/vulkan/vulkan_command_buffer.h" #include "flutter/vulkan/vulkan_handle.h" #include "flutter/vulkan/vulkan_proc_table.h" #include "flutter/vulkan/vulkan_provider.h" -#include "lib/ui/scenic/cpp/resources.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter_runner { +class SurfaceProducerSurface { + public: + virtual ~SurfaceProducerSurface() = default; + + virtual size_t AdvanceAndGetAge() = 0; + + virtual bool FlushSessionAcquireAndReleaseEvents() = 0; + + virtual bool IsValid() const = 0; + + virtual SkISize GetSize() const = 0; + + virtual void SignalWritesFinished( + const std::function& on_writes_committed) = 0; + + virtual scenic::Image* GetImage() = 0; + + virtual sk_sp GetSkiaSurface() const = 0; +}; + +class SurfaceProducer { + public: + virtual ~SurfaceProducer() = default; + + virtual std::unique_ptr ProduceSurface( + const SkISize& size) = 0; + + virtual void SubmitSurface( + std::unique_ptr surface) = 0; +}; + // A |VkImage| and its relevant metadata. struct VulkanImage { VulkanImage() = default; @@ -44,8 +74,7 @@ bool CreateVulkanImage(vulkan::VulkanProvider& vulkan_provider, const SkISize& size, VulkanImage* out_vulkan_image); -class VulkanSurface final - : public flutter::SceneUpdateContext::SurfaceProducerSurface { +class VulkanSurface final : public SurfaceProducerSurface { public: VulkanSurface(vulkan::VulkanProvider& vulkan_provider, sk_sp context, @@ -54,16 +83,16 @@ class VulkanSurface final ~VulkanSurface() override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| size_t AdvanceAndGetAge() override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| bool FlushSessionAcquireAndReleaseEvents() override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| bool IsValid() const override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| SkISize GetSize() const override; // Note: It is safe for the caller to collect the surface in the @@ -71,10 +100,10 @@ class VulkanSurface final void SignalWritesFinished( const std::function& on_writes_committed) override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| scenic::Image* GetImage() override; - // |flutter::SceneUpdateContext::SurfaceProducerSurface| + // |SurfaceProducerSurface| sk_sp GetSkiaSurface() const override; const vulkan::VulkanHandle& GetVkImage() { @@ -119,41 +148,6 @@ class VulkanSurface final // if the swap was not successful. bool BindToImage(sk_sp context, VulkanImage vulkan_image); - // Flutter may retain a |VulkanSurface| for a |flutter::Layer| subtree to - // improve the performance. The |retained_key_| identifies which layer subtree - // this |VulkanSurface| is retained for. The key has two parts. One is the - // pointer to the root of that layer subtree: |retained_key_.id()|. Another is - // the transformation matrix: |retained_key_.matrix()|. We need the matrix - // part because a different matrix would invalidate the pixels (raster cache) - // in this |VulkanSurface|. - const flutter::LayerRasterCacheKey& GetRetainedKey() const { - return retained_key_; - } - - // For better safety in retained rendering, Flutter uses a retained - // |EntityNode| associated with the retained surface instead of using the - // retained surface directly. Hence Flutter can't modify the surface during - // retained rendering. However, the node itself is modifiable to be able - // to adjust its position. - scenic::EntityNode* GetRetainedNode() { - used_in_retained_rendering_ = true; - return retained_node_.get(); - } - - // Check whether the retained surface (and its associated |EntityNode|) is - // used in the current frame or not. If unused, the |VulkanSurfacePool| will - // try to recycle the surface. This flag is reset after each frame. - bool IsUsedInRetainedRendering() const { return used_in_retained_rendering_; } - void ResetIsUsedInRetainedRendering() { used_in_retained_rendering_ = false; } - - // Let this surface own the retained EntityNode associated with it (see - // |GetRetainedNode|), and set the retained key (see |GetRetainedKey|). - void SetRetainedInfo(const flutter::LayerRasterCacheKey& key, - std::unique_ptr node) { - retained_key_ = key; - retained_node_ = std::move(node); - } - private: static constexpr int kSizeHistorySize = 4; @@ -202,11 +196,6 @@ class VulkanSurface final size_t age_ = 0; bool valid_ = false; - flutter::LayerRasterCacheKey retained_key_ = {0, SkMatrix::Scale(1, 1)}; - std::unique_ptr retained_node_ = nullptr; - - std::atomic used_in_retained_rendering_ = {false}; - FML_DISALLOW_COPY_AND_ASSIGN(VulkanSurface); }; diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc b/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc index cb40dd25ddbb3..1b85a957898bd 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc +++ b/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc @@ -112,8 +112,7 @@ std::unique_ptr VulkanSurfacePool::GetCachedOrCreateSurface( } void VulkanSurfacePool::SubmitSurface( - std::unique_ptr - p_surface) { + std::unique_ptr p_surface) { TRACE_EVENT0("flutter", "VulkanSurfacePool::SubmitSurface"); // This cast is safe because |VulkanSurface| is the only implementation of @@ -126,43 +125,14 @@ void VulkanSurfacePool::SubmitSurface( return; } - const flutter::LayerRasterCacheKey& retained_key = - vulkan_surface->GetRetainedKey(); - - // TODO(https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=44141): Re-enable - // retained surfaces after we find out why textures are being prematurely - // recycled. - const bool kUseRetainedSurfaces = false; - if (kUseRetainedSurfaces && retained_key.id() != 0) { - // Add the surface to |retained_surfaces_| if its retained key has a valid - // layer id (|retained_key.id()|). - // - // We have to add the entry to |retained_surfaces_| map early when it's - // still pending (|is_pending| = true). Otherwise (if we add the surface - // later when |SignalRetainedReady| is called), Flutter would fail to find - // the retained node before the painting is done (which could take multiple - // frames). Flutter would then create a new |VulkanSurface| for the layer - // upon the failed lookup. The new |VulkanSurface| would invalidate this - // surface, and before the new |VulkanSurface| is done painting, another - // newer |VulkanSurface| is likely to be created to replace the new - // |VulkanSurface|. That would make the retained rendering much less useful - // in improving the performance. - auto insert_iterator = retained_surfaces_.insert(std::make_pair( - retained_key, RetainedSurface({true, std::move(vulkan_surface)}))); - if (insert_iterator.second) { - insert_iterator.first->second.vk_surface->SignalWritesFinished(std::bind( - &VulkanSurfacePool::SignalRetainedReady, this, retained_key)); - } - } else { - uintptr_t surface_key = reinterpret_cast(vulkan_surface.get()); - auto insert_iterator = pending_surfaces_.insert(std::make_pair( - surface_key, // key - std::move(vulkan_surface) // value - )); - if (insert_iterator.second) { - insert_iterator.first->second->SignalWritesFinished(std::bind( - &VulkanSurfacePool::RecyclePendingSurface, this, surface_key)); - } + uintptr_t surface_key = reinterpret_cast(vulkan_surface.get()); + auto insert_iterator = pending_surfaces_.insert(std::make_pair( + surface_key, // key + std::move(vulkan_surface) // value + )); + if (insert_iterator.second) { + insert_iterator.first->second->SignalWritesFinished(std::bind( + &VulkanSurfacePool::RecyclePendingSurface, this, surface_key)); } } @@ -213,25 +183,6 @@ void VulkanSurfacePool::RecycleSurface(std::unique_ptr surface) { TraceStats(); } -void VulkanSurfacePool::RecycleRetainedSurface( - const flutter::LayerRasterCacheKey& key) { - auto it = retained_surfaces_.find(key); - if (it == retained_surfaces_.end()) { - return; - } - - // The surface should not be pending. - FML_DCHECK(!it->second.is_pending); - - auto surface_to_recycle = std::move(it->second.vk_surface); - retained_surfaces_.erase(it); - RecycleSurface(std::move(surface_to_recycle)); -} - -void VulkanSurfacePool::SignalRetainedReady(flutter::LayerRasterCacheKey key) { - retained_surfaces_[key].is_pending = false; -} - void VulkanSurfacePool::AgeAndCollectOldBuffers() { TRACE_EVENT0("flutter", "VulkanSurfacePool::AgeAndCollectOldBuffers"); @@ -268,25 +219,6 @@ void VulkanSurfacePool::AgeAndCollectOldBuffers() { } } - // Recycle retained surfaces that are not used and not pending in this frame. - // - // It's safe to recycle any retained surfaces that are not pending no matter - // whether they're used or not. Hence if there's memory pressure, feel free to - // recycle all retained surfaces that are not pending. - std::vector recycle_keys; - for (auto& [key, retained_surface] : retained_surfaces_) { - if (retained_surface.is_pending || - retained_surface.vk_surface->IsUsedInRetainedRendering()) { - // Reset the flag for the next frame - retained_surface.vk_surface->ResetIsUsedInRetainedRendering(); - } else { - recycle_keys.push_back(key); - } - } - for (auto& key : recycle_keys) { - RecycleRetainedSurface(key); - } - TraceStats(); } @@ -320,15 +252,9 @@ void VulkanSurfacePool::ShrinkToFit() { void VulkanSurfacePool::TraceStats() { // Resources held in cached buffers. size_t cached_surfaces_bytes = 0; - size_t retained_surfaces_bytes = 0; - for (const auto& surface : available_surfaces_) { cached_surfaces_bytes += surface->GetAllocationSize(); } - for (const auto& retained_entry : retained_surfaces_) { - retained_surfaces_bytes += - retained_entry.second.vk_surface->GetAllocationSize(); - } // Resources held by Skia. int skia_resources = 0; @@ -342,13 +268,13 @@ void VulkanSurfacePool::TraceStats() { "Created", trace_surfaces_created_, // "Reused", trace_surfaces_reused_, // "PendingInCompositor", pending_surfaces_.size(), // - "Retained", retained_surfaces_.size(), // + "Retained", 0, // "SkiaCacheResources", skia_resources // ); TRACE_COUNTER("flutter", "SurfacePoolBytes", 0u, // "CachedBytes", cached_surfaces_bytes, // - "RetainedBytes", retained_surfaces_bytes, // + "RetainedBytes", 0, // "SkiaCacheBytes", skia_bytes, // "SkiaCachePurgeable", skia_cache_purgeable // ); diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_pool.h b/shell/platform/fuchsia/flutter/vulkan_surface_pool.h index 302be9bac7b8a..0667db88d6c0c 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_pool.h +++ b/shell/platform/fuchsia/flutter/vulkan_surface_pool.h @@ -28,9 +28,7 @@ class VulkanSurfacePool final { std::unique_ptr AcquireSurface(const SkISize& size); - void SubmitSurface( - std::unique_ptr - surface); + void SubmitSurface(std::unique_ptr surface); void AgeAndCollectOldBuffers(); @@ -38,26 +36,7 @@ class VulkanSurfacePool final { // small as they can be. void ShrinkToFit(); - // For |VulkanSurfaceProducer::HasRetainedNode|. - bool HasRetainedNode(const flutter::LayerRasterCacheKey& key) const { - return retained_surfaces_.find(key) != retained_surfaces_.end(); - } - // For |VulkanSurfaceProducer::GetRetainedNode|. - scenic::EntityNode* GetRetainedNode(const flutter::LayerRasterCacheKey& key) { - FML_DCHECK(HasRetainedNode(key)); - return retained_surfaces_[key].vk_surface->GetRetainedNode(); - } - private: - // Struct for retained_surfaces_ map. - struct RetainedSurface { - // If |is_pending| is true, the |vk_surface| is still under painting - // (similar to those in |pending_surfaces_|) so we can't recycle the - // |vk_surface| yet. - bool is_pending; - std::unique_ptr vk_surface; - }; - vulkan::VulkanProvider& vulkan_provider_; sk_sp context_; scenic::Session* scenic_session_; @@ -65,9 +44,6 @@ class VulkanSurfacePool final { std::unordered_map> pending_surfaces_; - // Retained surfaces keyed by the layer that created and used the surface. - flutter::LayerRasterCacheKey::Map retained_surfaces_; - size_t trace_surfaces_created_ = 0; size_t trace_surfaces_reused_ = 0; @@ -79,13 +55,6 @@ class VulkanSurfacePool final { void RecyclePendingSurface(uintptr_t surface_key); - // Clear the |is_pending| flag of the retained surface. - void SignalRetainedReady(flutter::LayerRasterCacheKey key); - - // Remove the corresponding surface from |retained_surfaces| and recycle it. - // The surface must not be pending. - void RecycleRetainedSurface(const flutter::LayerRasterCacheKey& key); - void TraceStats(); FML_DISALLOW_COPY_AND_ASSIGN(VulkanSurfacePool); diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc index 1e0d03df847a8..36eeadd85afa3 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc +++ b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc @@ -155,9 +155,7 @@ bool VulkanSurfaceProducer::Initialize(scenic::Session* scenic_session) { } void VulkanSurfaceProducer::OnSurfacesPresented( - std::vector< - std::unique_ptr> - surfaces) { + std::vector> surfaces) { TRACE_EVENT0("flutter", "VulkanSurfaceProducer::OnSurfacesPresented"); // Do a single flush for all canvases derived from the context. @@ -197,11 +195,12 @@ void VulkanSurfaceProducer::OnSurfacesPresented( } bool VulkanSurfaceProducer::TransitionSurfacesToExternal( - const std::vector< - std::unique_ptr>& - surfaces) { + const std::vector>& surfaces) { for (auto& surface : surfaces) { auto vk_surface = static_cast(surface.get()); + if (!vk_surface) { + continue; + } vulkan::VulkanCommandBuffer* command_buffer = vk_surface->GetCommandBuffer(logical_device_->GetCommandPool()); @@ -259,21 +258,15 @@ bool VulkanSurfaceProducer::TransitionSurfacesToExternal( return true; } -std::unique_ptr -VulkanSurfaceProducer::ProduceSurface( - const SkISize& size, - const flutter::LayerRasterCacheKey& layer_key, - std::unique_ptr entity_node) { +std::unique_ptr VulkanSurfaceProducer::ProduceSurface( + const SkISize& size) { FML_DCHECK(valid_); last_produce_time_ = async::Now(async_get_default_dispatcher()); - auto surface = surface_pool_->AcquireSurface(size); - surface->SetRetainedInfo(layer_key, std::move(entity_node)); - return surface; + return surface_pool_->AcquireSurface(size); } void VulkanSurfaceProducer::SubmitSurface( - std::unique_ptr - surface) { + std::unique_ptr surface) { FML_DCHECK(valid_ && surface != nullptr); surface_pool_->SubmitSurface(std::move(surface)); } diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_producer.h b/shell/platform/fuchsia/flutter/vulkan_surface_producer.h index 403ecd19bebbe..2caaf64a36d7f 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_producer.h +++ b/shell/platform/fuchsia/flutter/vulkan_surface_producer.h @@ -8,8 +8,8 @@ #include #include -#include "flutter/flow/scene_update_context.h" #include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" #include "flutter/vulkan/vulkan_application.h" #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" @@ -22,9 +22,8 @@ namespace flutter_runner { -class VulkanSurfaceProducer final - : public flutter::SceneUpdateContext::SurfaceProducer, - public vulkan::VulkanProvider { +class VulkanSurfaceProducer final : public SurfaceProducer, + public vulkan::VulkanProvider { public: VulkanSurfaceProducer(scenic::Session* scenic_session); @@ -32,39 +31,15 @@ class VulkanSurfaceProducer final bool IsValid() const { return valid_; } - // |flutter::SceneUpdateContext::SurfaceProducer| - std::unique_ptr - ProduceSurface(const SkISize& size, - const flutter::LayerRasterCacheKey& layer_key, - std::unique_ptr entity_node) override; + // |SurfaceProducer| + std::unique_ptr ProduceSurface( + const SkISize& size) override; - // |flutter::SceneUpdateContext::SurfaceProducer| - void SubmitSurface( - std::unique_ptr - surface) override; - - // |flutter::SceneUpdateContext::HasRetainedNode| - bool HasRetainedNode(const flutter::LayerRasterCacheKey& key) const override { - return surface_pool_->HasRetainedNode(key); - } - - // |flutter::SceneUpdateContext::GetRetainedNode| - scenic::EntityNode* GetRetainedNode( - const flutter::LayerRasterCacheKey& key) override { - return surface_pool_->GetRetainedNode(key); - } + // |SurfaceProducer| + void SubmitSurface(std::unique_ptr surface) override; void OnSurfacesPresented( - std::vector< - std::unique_ptr> - surfaces); - - void OnSessionSizeChangeHint(float width_change_factor, - float height_change_factor) { - FX_LOGF(INFO, LOG_TAG, - "VulkanSurfaceProducer:OnSessionSizeChangeHint %f, %f", - width_change_factor, height_change_factor); - } + std::vector> surfaces); GrDirectContext* gr_context() { return context_.get(); } @@ -76,9 +51,7 @@ class VulkanSurfaceProducer final } bool TransitionSurfacesToExternal( - const std::vector< - std::unique_ptr>& - surfaces); + const std::vector>& surfaces); // Note: the order here is very important. The proctable must be destroyed // last because it contains the function pointers for VkDestroyDevice and diff --git a/testing/dart/window_hooks_integration_test.dart b/testing/dart/window_hooks_integration_test.dart index 186ca928a1c3e..21eda23623664 100644 --- a/testing/dart/window_hooks_integration_test.dart +++ b/testing/dart/window_hooks_integration_test.dart @@ -46,7 +46,6 @@ void main() { double? oldDPR; Size? oldSize; - double? oldDepth; WindowPadding? oldPadding; WindowPadding? oldInsets; WindowPadding? oldSystemGestureInsets; @@ -54,7 +53,6 @@ void main() { void setUp() { oldDPR = window.devicePixelRatio; oldSize = window.physicalSize; - oldDepth = window.physicalDepth; oldPadding = window.viewPadding; oldInsets = window.viewInsets; oldSystemGestureInsets = window.systemGestureInsets; @@ -76,7 +74,6 @@ void main() { oldDPR!, // DPR oldSize!.width, // width oldSize!.height, // height - oldDepth!, // depth oldPadding!.top, // padding top oldPadding!.right, // padding right oldPadding!.bottom, // padding bottom @@ -161,7 +158,6 @@ void main() { 0.1234, // DPR 0.0, // width 0.0, // height - 0.0, // depth 0.0, // padding top 0.0, // padding right 0.0, // padding bottom @@ -378,7 +374,6 @@ void main() { 1.0, // DPR 800.0, // width 600.0, // height - 100.0, // depth 50.0, // padding top 0.0, // padding right 40.0, // padding bottom @@ -396,14 +391,12 @@ void main() { expectEquals(window.viewInsets.bottom, 0.0); expectEquals(window.viewPadding.bottom, 40.0); expectEquals(window.padding.bottom, 40.0); - expectEquals(window.physicalDepth, 100.0); expectEquals(window.systemGestureInsets.bottom, 0.0); _updateWindowMetrics( 1.0, // DPR 800.0, // width 600.0, // height - 100.0, // depth 50.0, // padding top 0.0, // padding right 40.0, // padding bottom @@ -421,7 +414,6 @@ void main() { expectEquals(window.viewInsets.bottom, 400.0); expectEquals(window.viewPadding.bottom, 40.0); expectEquals(window.padding.bottom, 0.0); - expectEquals(window.physicalDepth, 100.0); expectEquals(window.systemGestureInsets.bottom, 44.0); }); }