From 4785b0c28a3326f42b59156ca944ef36019d3d78 Mon Sep 17 00:00:00 2001 From: naudzghebre Date: Tue, 28 Jun 2022 22:25:17 +0000 Subject: [PATCH] Revert "[fuchsia][a11y] Set explicit hit regions per compositor layer on GFX. (#33852)" This reverts commit 0720dc10c042df83420d9c711946c8396c5d7d6b. --- .../flutter/gfx_external_view_embedder.cc | 115 ++---- .../flutter/gfx_external_view_embedder.h | 47 +-- .../gfx_external_view_embedder_unittests.cc | 328 ++++-------------- 3 files changed, 107 insertions(+), 383 deletions(-) diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc index 225cf31b0c3c0..a98fb019e4152 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc @@ -10,7 +10,6 @@ #include // For std::clamp -#include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkSurface.h" @@ -170,9 +169,8 @@ void GfxExternalViewEmbedder::PrerollCompositeEmbeddedView( zx_handle_t handle = static_cast(view_id); FML_CHECK(frame_layers_.count(handle) == 0); - frame_layers_.emplace(std::make_pair( - EmbedderLayerId{handle}, - EmbedderLayer(frame_size_, *params, flutter::RTreeFactory()))); + frame_layers_.emplace(std::make_pair(EmbedderLayerId{handle}, + EmbedderLayer(frame_size_, *params))); frame_composition_order_.push_back(handle); } @@ -202,9 +200,8 @@ void GfxExternalViewEmbedder::BeginFrame( frame_dpr_ = device_pixel_ratio; // Create the root layer. - frame_layers_.emplace(std::make_pair( - kRootLayerId, - EmbedderLayer(frame_size, std::nullopt, flutter::RTreeFactory()))); + frame_layers_.emplace( + std::make_pair(kRootLayerId, EmbedderLayer(frame_size, std::nullopt))); frame_composition_order_.push_back(kRootLayerId); // Set up the input interceptor at the top of the scene, if applicable. @@ -274,19 +271,6 @@ void GfxExternalViewEmbedder::SubmitFrame( } } - // Finish recording SkPictures. - { - TRACE_EVENT0("flutter", "FinishRecordingPictures"); - - for (const auto& surface_index : frame_surface_indices) { - const auto& layer = frame_layers_.find(surface_index.first); - FML_CHECK(layer != frame_layers_.end()); - layer->second.picture = - layer->second.recorder->finishRecordingAsPicture(); - FML_CHECK(layer->second.picture != nullptr); - } - } - // Submit layers and platform views to Scenic in composition order. { TRACE_EVENT0("flutter", "SubmitLayers"); @@ -453,18 +437,10 @@ void GfxExternalViewEmbedder::SubmitFrame( FML_CHECK(scenic_layer_index <= scenic_layers_.size()); if (scenic_layer_index == scenic_layers_.size()) { ScenicLayer new_layer{ - .layer_node = scenic::EntityNode(session_->get()), - .image = - ScenicImage{ - .shape_node = scenic::ShapeNode(session_->get()), - .material = scenic::Material(session_->get()), - }, - // We'll set hit regions later. - .hit_regions = {}, + .shape_node = scenic::ShapeNode(session_->get()), + .material = scenic::Material(session_->get()), }; - new_layer.layer_node.SetLabel("Flutter::Layer"); - new_layer.layer_node.AddChild(new_layer.image.shape_node); - new_layer.image.shape_node.SetMaterial(new_layer.image.material); + new_layer.shape_node.SetMaterial(new_layer.material); scenic_layers_.emplace_back(std::move(new_layer)); } @@ -515,50 +491,25 @@ void GfxExternalViewEmbedder::SubmitFrame( embedded_views_height; auto& scenic_layer = scenic_layers_[scenic_layer_index]; auto& scenic_rect = found_rects->second[rect_index]; - auto& image = scenic_layer.image; - image.shape_node.SetLabel("Flutter::Layer::Image"); - image.shape_node.SetShape(scenic_rect); - image.shape_node.SetTranslation( + scenic_layer.shape_node.SetLabel("Flutter::Layer"); + scenic_layer.shape_node.SetShape(scenic_rect); + scenic_layer.shape_node.SetTranslation( layer->second.surface_size.width() * 0.5f, layer->second.surface_size.height() * 0.5f, -layer_elevation); - image.material.SetColor(SK_AlphaOPAQUE, SK_AlphaOPAQUE, SK_AlphaOPAQUE, - layer_opacity); - image.material.SetTexture(surface_for_layer->GetImageId()); - - // We'll set hit regions expliclty on a separate ShapeNode, so the image - // itself should be unhittable and semantically invisible. - image.shape_node.SetHitTestBehavior( - fuchsia::ui::gfx::HitTestBehavior::kSuppress); - image.shape_node.SetSemanticVisibility(false); + scenic_layer.material.SetColor(SK_AlphaOPAQUE, SK_AlphaOPAQUE, + SK_AlphaOPAQUE, layer_opacity); + scenic_layer.material.SetTexture(surface_for_layer->GetImageId()); + + // Only the first (i.e. the bottom-most) layer should receive input. + // TODO: Workaround for invisible overlays stealing input. Remove when + // the underlying bug is fixed. + const fuchsia::ui::gfx::HitTestBehavior layer_hit_test_behavior = + first_layer ? fuchsia::ui::gfx::HitTestBehavior::kDefault + : fuchsia::ui::gfx::HitTestBehavior::kSuppress; + scenic_layer.shape_node.SetHitTestBehavior(layer_hit_test_behavior); // Attach the ScenicLayer to the main scene graph. - layer_tree_node_.AddChild(scenic_layer.layer_node); - - // Compute the set of non-overlapping set of bounding boxes for the - // painted content in this layer. - { - FML_CHECK(layer->second.rtree); - std::list intersection_rects = - layer->second.rtree->searchNonOverlappingDrawnRects( - SkRect::Make(layer->second.surface_size)); - - // SkRect joined_rect = SkRect::MakeEmpty(); - for (const SkRect& rect : intersection_rects) { - auto paint_bounds = - scenic::Rectangle(session_->get(), rect.width(), rect.height()); - auto hit_region = scenic::ShapeNode(session_->get()); - hit_region.SetLabel("Flutter::Layer::HitRegion"); - hit_region.SetShape(paint_bounds); - hit_region.SetTranslation(rect.centerX(), rect.centerY(), - -layer_elevation); - hit_region.SetHitTestBehavior( - fuchsia::ui::gfx::HitTestBehavior::kDefault); - hit_region.SetSemanticVisibility(true); - - scenic_layer.layer_node.AddChild(hit_region); - scenic_layer.hit_regions.push_back(std::move(hit_region)); - } - } + layer_tree_node_.AddChild(scenic_layer.shape_node); } // Reset for the next pass: @@ -576,11 +527,7 @@ void GfxExternalViewEmbedder::SubmitFrame( session_->Present(); } - // Flush pending skia operations. - // NOTE: This operation MUST occur AFTER the `Present() ` call above. We - // pipeline the Skia rendering work with scenic IPC, and scenic will delay - // internally until Skia is finished. So, doing this work before calling - // `Present()` would adversely affect performance. + // Render the recorded SkPictures into the surfaces. { TRACE_EVENT0("flutter", "RasterizeSurfaces"); @@ -601,10 +548,13 @@ void GfxExternalViewEmbedder::SubmitFrame( const auto& layer = frame_layers_.find(surface_index.first); FML_CHECK(layer != frame_layers_.end()); + sk_sp picture = + layer->second.recorder->finishRecordingAsPicture(); + FML_CHECK(picture != nullptr); canvas->setMatrix(SkMatrix::I()); canvas->clear(SK_ColorTRANSPARENT); - canvas->drawPicture(layer->second.picture); + canvas->drawPicture(picture); canvas->flush(); } } @@ -686,16 +636,7 @@ void GfxExternalViewEmbedder::Reset() { // Clear images on all layers so they aren't cached unnecessarily. for (auto& layer : scenic_layers_) { - layer.image.material.SetTexture(0); - - // Detach hit regions; otherwise, they may persist across frames - // incorrectly. - for (auto& hit_region : layer.hit_regions) { - hit_region.Detach(); - } - - // Remove cached hit regions so that we don't recreate stale ones. - layer.hit_regions.clear(); + layer.material.SetTexture(0); } } diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h index 81b061776973b..1e0a5e3eab67d 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h @@ -17,7 +17,6 @@ #include #include "flutter/flow/embedded_views.h" -#include "flutter/flow/rtree.h" #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #include "flutter/shell/common/canvas_spy.h" @@ -139,29 +138,18 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { struct EmbedderLayer { EmbedderLayer(const SkISize& frame_size, - std::optional view_params, - flutter::RTreeFactory rtree_factory) - : rtree(rtree_factory.getInstance()), - embedded_view_params(std::move(view_params)), + std::optional view_params) + : embedded_view_params(std::move(view_params)), recorder(std::make_unique()), canvas_spy(std::make_unique( - recorder->beginRecording(SkRect::Make(frame_size), - &rtree_factory))), - surface_size(frame_size), - picture(nullptr) {} - - // Records paint operations applied to this layer's `SkCanvas`. - // These records are used to determine which portions of this layer - // contain content. The embedder propagates this information to scenic, so - // that scenic can accurately decide which portions of this layer may - // interact with input. - sk_sp rtree; + recorder->beginRecording(frame_size.width(), + frame_size.height()))), + surface_size(frame_size) {} std::optional embedded_view_params; std::unique_ptr recorder; std::unique_ptr canvas_spy; SkISize surface_size; - sk_sp picture; }; using EmbedderLayerId = std::optional; constexpr static EmbedderLayerId kRootLayerId = EmbedderLayerId{}; @@ -184,34 +172,11 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { bool pending_focusable = true; }; - // GFX resources required to render a composited flutter layer (i.e. an - // SkPicture). - struct ScenicImage { + struct ScenicLayer { scenic::ShapeNode shape_node; scenic::Material material; }; - // All resources required to represent a flutter layer in the GFX scene - // graph. The structure of the subgraph for a particular layer is: - // - // layer_node - // / \ - // image node hit regions (zero or more) - // - // NOTE: `hit_regions` must be cleared before submitting each new frame; - // otherwise, we will report stale hittable geometry to scenic. - struct ScenicLayer { - // Root of the subtree containing the scenic resources for this layer. - scenic::EntityNode layer_node; - - // Scenic resources used to render this layer's image. - ScenicImage image; - - // Scenic resources that specify which parts of this layer are responsive - // to input. - std::vector hit_regions; - }; - std::shared_ptr session_; std::shared_ptr surface_producer_; diff --git a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc index f99c54fb1904a..58690960d03cb 100644 --- a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc @@ -149,6 +149,18 @@ class FakeSurfaceProducer : public SurfaceProducer { uint32_t buffer_id_{1}; }; +struct FakeCompositorLayer { + enum class LayerType : uint32_t { + Image, + View, + }; + + std::shared_ptr layer_root; + + LayerType layer_type{LayerType::Image}; + size_t layer_index{0}; +}; + std::string GetCurrentTestName() { return ::testing::UnitTest::GetInstance()->current_test_info()->name(); } @@ -241,28 +253,12 @@ void ExpectRootSceneGraph( EXPECT_EQ(scene_graph.resource_map.size(), 3u); } -/// Verifies the scene subgraph for a particular flutter embedder layer. -/// -/// ARGUMENTS -/// -/// scenic_node: The root of the layer's scenic subgraph. -/// -/// layer_size: The expected dimensions of the layer's image. -/// -/// flutter_layer_index: This layer's 0-indexed position in the list of -/// flutter layers present in this frame, sorted in paint order. -/// -/// paint_regions: List of non-overlapping rects, in canvas coordinate space, -/// where content was drawn. For each "paint region" present in the frame, the -/// embedder reports a corresponding "hit region" to scenic as a hittable -/// ShapeNode. ShapeNodes are centered at (0, 0), by default, so they must be -/// translated to match the locations of the corresopnding paint regions. -void ExpectImageCompositorLayer(const FakeResource& scenic_node, - const SkISize layer_size, - size_t flutter_layer_index, - std::vector paint_regions) { +void ExpectImageCompositorLayer(const FakeCompositorLayer& layer, + const SkISize layer_size) { const SkSize float_layer_size = SkSize::Make(layer_size.width(), layer_size.height()); + const size_t flutter_layer_index = + (layer.layer_index + 1) / 2; // Integer division const float views_under_layer_depth = flutter_layer_index * GfxExternalViewEmbedder::kScenicZElevationForPlatformView; @@ -270,50 +266,27 @@ void ExpectImageCompositorLayer(const FakeResource& scenic_node, flutter_layer_index * GfxExternalViewEmbedder::kScenicZElevationBetweenLayers + views_under_layer_depth; + const bool layer_hit_testable = (flutter_layer_index == 0) + ? FakeNode::kIsHitTestable + : FakeNode::kIsNotHitTestable; const float layer_opacity = (flutter_layer_index == 0) ? GfxExternalViewEmbedder::kBackgroundLayerOpacity / 255.f : GfxExternalViewEmbedder::kOverlayLayerOpacity / 255.f; - + EXPECT_EQ(layer.layer_type, FakeCompositorLayer::LayerType::Image); + EXPECT_EQ(layer.layer_index % 2, 0u); EXPECT_THAT( - scenic_node, - FieldsAre( - _, "Flutter::Layer", FakeResource::kDefaultEmptyEventMask, - VariantWith(FieldsAre( - FieldsAre( - // Verify children separately below, since the - // expected number of children may vary across - // different test cases that call this method. - _, FakeNode::kDefaultZeroRotation, FakeNode::kDefaultOneScale, - FakeNode::kDefaultZeroTranslation, - FakeNode::kDefaultZeroAnchor, FakeNode::kIsHitTestable, - FakeNode::kIsSemanticallyVisible), - _)))); - - const auto* layer_node_state = - std::get_if(&scenic_node.state); - ASSERT_TRUE(layer_node_state); - - const auto& layer_node_children = layer_node_state->node_state.children; - - // The layer entity node should have a child node for the image, and - // separate children for each of the hit regions. - ASSERT_EQ(layer_node_children.size(), paint_regions.size() + 1); - - // Verify image node. - EXPECT_THAT( - layer_node_children[0], + layer.layer_root, Pointee(FieldsAre( - _, "Flutter::Layer::Image", FakeResource::kDefaultEmptyEventMask, + _, "Flutter::Layer", FakeResource::kDefaultEmptyEventMask, VariantWith(FieldsAre( FieldsAre(IsEmpty(), FakeNode::kDefaultZeroRotation, FakeNode::kDefaultOneScale, std::array{float_layer_size.width() / 2.f, float_layer_size.height() / 2.f, -layer_depth}, - FakeNode::kDefaultZeroAnchor, - FakeNode::kIsNotHitTestable, - FakeNode::kIsNotSemanticallyVisible), + FakeNode::kDefaultZeroAnchor, layer_hit_testable, + FakeNode::kIsSemanticallyVisible), Pointee( FieldsAre(_, "", FakeResource::kDefaultEmptyEventMask, VariantWith( @@ -332,39 +305,13 @@ void ExpectImageCompositorLayer(const FakeResource& scenic_node, IsNull())))), std::array{1.f, 1.f, 1.f, layer_opacity}))))))))); - - // Verify hit regions. - for (size_t i = 0; i < paint_regions.size(); ++i) { - ASSERT_LT(i, layer_node_children.size()); - const auto& paint_region = paint_regions[i]; - EXPECT_THAT( - layer_node_children[i + 1], - Pointee(FieldsAre( - _, "Flutter::Layer::HitRegion", - FakeResource::kDefaultEmptyEventMask, - VariantWith(FieldsAre( - FieldsAre(IsEmpty(), FakeNode::kDefaultZeroRotation, - FakeNode::kDefaultOneScale, - std::array{ - paint_region.x() + paint_region.width() / 2.f, - paint_region.y() + paint_region.height() / 2.f, - -layer_depth}, - FakeNode::kDefaultZeroAnchor, - FakeNode::kIsHitTestable, - FakeNode::kIsSemanticallyVisible), - Pointee(FieldsAre( - _, "", FakeResource::kDefaultEmptyEventMask, - VariantWith(FieldsAre( - VariantWith(FieldsAre( - paint_region.width(), paint_region.height())))))), - IsNull()))))); - } } -void ExpectViewCompositorLayer(const FakeResource& scenic_node, +void ExpectViewCompositorLayer(const FakeCompositorLayer& layer, const fuchsia::ui::views::ViewToken& view_token, - const flutter::EmbeddedViewParams& view_params, - size_t flutter_layer_index) { + const flutter::EmbeddedViewParams& view_params) { + const size_t flutter_layer_index = + (layer.layer_index + 1) / 2; // Integer division const float views_under_layer_depth = flutter_layer_index > 0 ? (flutter_layer_index - 1) * @@ -374,9 +321,11 @@ void ExpectViewCompositorLayer(const FakeResource& scenic_node, flutter_layer_index * GfxExternalViewEmbedder::kScenicZElevationBetweenLayers + views_under_layer_depth; + EXPECT_EQ(layer.layer_type, FakeCompositorLayer::LayerType::View); + EXPECT_EQ(layer.layer_index % 2, 1u); EXPECT_THAT( - scenic_node, - FieldsAre( + layer.layer_root, + Pointee(FieldsAre( _, _ /*"Flutter::PlatformView::OpacityMutator" */, FakeResource::kDefaultEmptyEventMask, VariantWith(FieldsAre( @@ -423,10 +372,10 @@ void ExpectViewCompositorLayer(const FakeResource& scenic_node, FakeNode::kDefaultZeroTranslation, FakeNode::kDefaultZeroAnchor, FakeNode::kIsHitTestable, FakeNode::kIsSemanticallyVisible), - FakeOpacityNode::kDefaultOneOpacity)))); + FakeOpacityNode::kDefaultOneOpacity))))); } -std::vector ExtractLayersFromSceneGraph( +std::vector ExtractLayersFromSceneGraph( const FakeSceneGraph& scene_graph) { AssertRootSceneGraph(scene_graph, false); @@ -438,12 +387,20 @@ std::vector ExtractLayersFromSceneGraph( auto* layer_tree_state = std::get_if( &metrics_watcher_state->node_state.children[0]->state); - std::vector scenic_layers; + std::vector layers; for (auto& layer_resource : layer_tree_state->node_state.children) { - scenic_layers.push_back(*layer_resource); + const size_t layer_index = layers.size(); + const FakeCompositorLayer::LayerType layer_type = + (layer_index % 2 == 0) ? FakeCompositorLayer::LayerType::Image + : FakeCompositorLayer::LayerType::View; + layers.emplace_back(FakeCompositorLayer{ + .layer_root = layer_resource, + .layer_type = layer_type, + .layer_index = layer_index, + }); } - return scenic_layers; + return layers; } void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder, @@ -571,7 +528,6 @@ class GfxExternalViewEmbedderTest std::shared_ptr fake_surface_producer_; }; -// Tests the trivial case where flutter does not present any content to scenic. TEST_F(GfxExternalViewEmbedderTest, RootScene) { const std::string debug_name = GetCurrentTestName(); auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); @@ -602,7 +558,6 @@ TEST_F(GfxExternalViewEmbedderTest, RootScene) { view_holder_token, view_ref); } -// Tests the case where flutter renders a single image. TEST_F(GfxExternalViewEmbedderTest, SimpleScene) { const std::string debug_name = GetCurrentTestName(); auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); @@ -624,34 +579,29 @@ TEST_F(GfxExternalViewEmbedderTest, SimpleScene) { // Draw the scene. The scene graph shouldn't change yet. const SkISize frame_size = SkISize::Make(512, 512); - SkRect paint_region; DrawSimpleFrame( - external_view_embedder, frame_size, 1.f, - [&paint_region](SkCanvas* canvas) { + external_view_embedder, frame_size, 1.f, [](SkCanvas* canvas) { const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(), canvas->imageInfo().height()); SkPaint rect_paint; rect_paint.setColor(SK_ColorGREEN); - - paint_region = SkRect::MakeXYWH( - canvas_size.width() / 4.f, canvas_size.height() / 2.f, - canvas_size.width() / 32.f, canvas_size.height() / 32.f); - - canvas->drawRect(paint_region, rect_paint); + canvas->translate(canvas_size.width() / 4.f, + canvas_size.height() / 2.f); + canvas->drawRect(SkRect::MakeWH(canvas_size.width() / 32.f, + canvas_size.height() / 32.f), + rect_paint); }); ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, view_holder_token, view_ref); // Pump the message loop. The scene updates should propogate to Scenic. loop().RunUntilIdle(); - std::vector scenic_layers = + std::vector compositor_layers = ExtractLayersFromSceneGraph(fake_session().SceneGraph()); - EXPECT_EQ(scenic_layers.size(), 1u); - ExpectImageCompositorLayer(scenic_layers[0], frame_size, - /* flutter layer index = */ 0, {paint_region}); + EXPECT_EQ(compositor_layers.size(), 1u); + ExpectImageCompositorLayer(compositor_layers[0], frame_size); } -// Tests the case where flutter embeds a platform view on top of an image layer. TEST_F(GfxExternalViewEmbedderTest, SceneWithOneView) { const std::string debug_name = GetCurrentTestName(); auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); @@ -683,51 +633,42 @@ TEST_F(GfxExternalViewEmbedderTest, SceneWithOneView) { // Draw the scene. The scene graph shouldn't change yet. const SkISize frame_size = SkISize::Make(512, 512); - - SkRect main_surface_paint_region, overlay_paint_region; - DrawFrameWithView( external_view_embedder, frame_size, 1.f, child_view_id, child_view_params, - [&main_surface_paint_region](SkCanvas* canvas) { + [](SkCanvas* canvas) { const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(), canvas->imageInfo().height()); - - main_surface_paint_region = SkRect::MakeXYWH( - canvas_size.width() / 4.f, canvas_size.width() / 2.f, - canvas_size.width() / 32.f, canvas_size.height() / 32.f); - SkPaint rect_paint; rect_paint.setColor(SK_ColorGREEN); - canvas->drawRect(main_surface_paint_region, rect_paint); + canvas->translate(canvas_size.width() / 4.f, + canvas_size.height() / 2.f); + canvas->drawRect(SkRect::MakeWH(canvas_size.width() / 32.f, + canvas_size.height() / 32.f), + rect_paint); }, - [&overlay_paint_region](SkCanvas* canvas) { + [](SkCanvas* canvas) { const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(), canvas->imageInfo().height()); - overlay_paint_region = SkRect::MakeXYWH( - canvas_size.width() * 3.f / 4.f, canvas_size.height() / 2.f, - canvas_size.width() / 32.f, canvas_size.height() / 32.f); - SkPaint rect_paint; rect_paint.setColor(SK_ColorRED); - canvas->drawRect(overlay_paint_region, rect_paint); + canvas->translate(canvas_size.width() * 3.f / 4.f, + canvas_size.height() / 2.f); + canvas->drawRect(SkRect::MakeWH(canvas_size.width() / 32.f, + canvas_size.height() / 32.f), + rect_paint); }); ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, view_holder_token, view_ref); // Pump the message loop. The scene updates should propagate to Scenic. loop().RunUntilIdle(); - std::vector scenic_layers = + std::vector compositor_layers = ExtractLayersFromSceneGraph(fake_session().SceneGraph()); - EXPECT_EQ(scenic_layers.size(), 3u); - ExpectImageCompositorLayer(scenic_layers[0], frame_size, - /* flutter layer index = */ 0, - {main_surface_paint_region}); - ExpectViewCompositorLayer(scenic_layers[1], child_view_token, - child_view_params, - /* flutter layer index = */ 1); - ExpectImageCompositorLayer(scenic_layers[2], frame_size, - /* flutter layer index = */ 1, - {overlay_paint_region}); + EXPECT_EQ(compositor_layers.size(), 3u); + ExpectImageCompositorLayer(compositor_layers[0], frame_size); + ExpectViewCompositorLayer(compositor_layers[1], child_view_token, + child_view_params); + ExpectImageCompositorLayer(compositor_layers[2], frame_size); // Destroy the view. external_view_embedder.DestroyView(child_view_id, [](scenic::ResourceId) {}); @@ -736,127 +677,4 @@ TEST_F(GfxExternalViewEmbedderTest, SceneWithOneView) { loop().RunUntilIdle(); } -// Tests the case where flutter renders an image with two non-overlapping pieces -// of content. In this case, the embedder should report two separate hit regions -// to scenic. -TEST_F(GfxExternalViewEmbedderTest, SimpleSceneDisjointHitRegions) { - const std::string debug_name = GetCurrentTestName(); - auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); - auto view_ref_pair = scenic::ViewRefPair::New(); - fuchsia::ui::views::ViewRef view_ref; - view_ref_pair.view_ref.Clone(&view_ref); - - // Create the `GfxExternalViewEmbedder` and pump the message loop until - // the initial scene graph is setup. - GfxExternalViewEmbedder external_view_embedder( - debug_name, std::move(view_token), std::move(view_ref_pair), - session_connection(), fake_surface_producer()); - loop().RunUntilIdle(); - fake_session().FireOnFramePresentedEvent( - MakeFramePresentedInfoForOnePresent(0, 0)); - loop().RunUntilIdle(); - ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, - view_holder_token, view_ref); - - // Draw the scene. The scene graph shouldn't change yet. - SkRect paint_region_1, paint_region_2; - const SkISize frame_size = SkISize::Make(512, 512); - DrawSimpleFrame( - external_view_embedder, frame_size, 1.f, - [&paint_region_1, &paint_region_2](SkCanvas* canvas) { - const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(), - canvas->imageInfo().height()); - - paint_region_1 = SkRect::MakeXYWH( - canvas_size.width() / 4.f, canvas_size.height() / 2.f, - canvas_size.width() / 32.f, canvas_size.height() / 32.f); - - SkPaint rect_paint; - rect_paint.setColor(SK_ColorGREEN); - canvas->drawRect(paint_region_1, rect_paint); - - paint_region_2 = SkRect::MakeXYWH( - canvas_size.width() * 3.f / 4.f, canvas_size.height() / 2.f, - canvas_size.width() / 32.f, canvas_size.height() / 32.f); - - rect_paint.setColor(SK_ColorRED); - canvas->drawRect(paint_region_2, rect_paint); - }); - ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, - view_holder_token, view_ref); - - // Pump the message loop. The scene updates should propogate to Scenic. - loop().RunUntilIdle(); - std::vector scenic_layers = - ExtractLayersFromSceneGraph(fake_session().SceneGraph()); - EXPECT_EQ(scenic_layers.size(), 1u); - ExpectImageCompositorLayer(scenic_layers[0], frame_size, - /* flutter layer index = */ 0, - {paint_region_1, paint_region_2}); -} - -// Tests the case where flutter renders an image with two overlapping pieces of -// content. In this case, the embedder should report a single joint hit region -// to scenic. -TEST_F(GfxExternalViewEmbedderTest, SimpleSceneOverlappingHitRegions) { - const std::string debug_name = GetCurrentTestName(); - auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); - auto view_ref_pair = scenic::ViewRefPair::New(); - fuchsia::ui::views::ViewRef view_ref; - view_ref_pair.view_ref.Clone(&view_ref); - - // Create the `GfxExternalViewEmbedder` and pump the message loop until - // the initial scene graph is setup. - GfxExternalViewEmbedder external_view_embedder( - debug_name, std::move(view_token), std::move(view_ref_pair), - session_connection(), fake_surface_producer()); - loop().RunUntilIdle(); - fake_session().FireOnFramePresentedEvent( - MakeFramePresentedInfoForOnePresent(0, 0)); - loop().RunUntilIdle(); - ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, - view_holder_token, view_ref); - - // Draw the scene. The scene graph shouldn't change yet. - SkRect joined_paint_region = SkRect::MakeEmpty(); - const SkISize frame_size = SkISize::Make(512, 512); - DrawSimpleFrame( - external_view_embedder, frame_size, 1.f, - [&joined_paint_region](SkCanvas* canvas) { - const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(), - canvas->imageInfo().height()); - - auto paint_region_1 = SkRect::MakeXYWH( - canvas_size.width() / 4.f, canvas_size.height() / 4.f, - canvas_size.width() / 2.f, canvas_size.height() / 2.f); - SkPaint rect_paint; - rect_paint.setColor(SK_ColorGREEN); - canvas->drawRect(paint_region_1, rect_paint); - - auto paint_region_2 = SkRect::MakeXYWH( - canvas_size.width() * 3.f / 8.f, canvas_size.height() / 4.f, - canvas_size.width() / 2.f, canvas_size.height() / 2.f); - rect_paint.setColor(SK_ColorRED); - canvas->drawRect(paint_region_2, rect_paint); - - joined_paint_region.join(paint_region_1); - joined_paint_region.join(paint_region_2); - }); - ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name, - view_holder_token, view_ref); - - EXPECT_EQ(joined_paint_region.x(), 128.f); - EXPECT_EQ(joined_paint_region.y(), 128.f); - EXPECT_EQ(joined_paint_region.width(), 320.f); - EXPECT_EQ(joined_paint_region.height(), 256.f); - // Pump the message loop. The scene updates should propogate to Scenic. - loop().RunUntilIdle(); - std::vector scenic_layers = - ExtractLayersFromSceneGraph(fake_session().SceneGraph()); - EXPECT_EQ(scenic_layers.size(), 1u); - ExpectImageCompositorLayer(scenic_layers[0], frame_size, - /* flutter layer index = */ 0, - {joined_paint_region}); -} - } // namespace flutter_runner::testing