From dfff522046e832f82c5cf3880dbd9bca6e608ef6 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 3 May 2023 13:28:53 -0700 Subject: [PATCH] Remove physical model layer (flutter/engine#41593) Removes the physical model layer and associated engine code. This was already deprecated and removed in the framework. By removing it in the engine, we can also remove the need for layer tree diff/paint/preroll to have the device pixel ratio. This will simplify some of the multi-view work Fixes https://github.com/flutter/flutter/issues/125720 --- .../flutter/ci/licenses_golden/excluded_files | 1 - .../ci/licenses_golden/licenses_flutter | 4 - engine/src/flutter/flow/BUILD.gn | 3 - engine/src/flutter/flow/compositor_context.cc | 4 +- engine/src/flutter/flow/diff_context.cc | 2 - engine/src/flutter/flow/diff_context.h | 4 - .../checkerboard_layertree_unittests.cc | 67 --- engine/src/flutter/flow/layers/layer.h | 2 - .../flow/layers/layer_raster_cache_item.cc | 1 - engine/src/flutter/flow/layers/layer_tree.cc | 4 - .../flow/layers/layer_tree_unittests.cc | 2 - .../performance_overlay_layer_unittests.cc | 1 - .../flow/layers/physical_shape_layer.cc | 124 ----- .../flow/layers/physical_shape_layer.h | 42 -- .../layers/physical_shape_layer_unittests.cc | 509 ------------------ .../flutter/flow/testing/diff_context_test.cc | 2 +- engine/src/flutter/flow/testing/layer_test.h | 4 - .../flutter/flow/testing/mock_raster_cache.cc | 2 - .../flutter/flow/testing/mock_raster_cache.h | 2 - engine/src/flutter/lib/ui/compositing.dart | 56 -- .../lib/ui/compositing/scene_builder.cc | 20 - .../lib/ui/compositing/scene_builder.h | 7 - engine/src/flutter/lib/ui/dart_ui.cc | 1 - .../flutter/lib/web_ui/lib/compositing.dart | 14 - .../lib/src/engine/canvaskit/layer.dart | 79 --- .../engine/canvaskit/layer_scene_builder.dart | 18 - .../lib/web_ui/lib/src/engine/html/clip.dart | 262 --------- .../lib/src/engine/html/scene_builder.dart | 32 -- .../lib/web_ui/lib/src/engine/shadow.dart | 4 +- .../skwasm/skwasm_impl/scene_builder.dart | 14 - .../test/canvaskit/canvas_golden_test.dart | 135 ----- .../engine/surface/scene_builder_test.dart | 16 - .../test/engine/surface/surface_test.dart | 21 - .../compositing/color_filter_golden_test.dart | 48 +- .../compositing/compositing_golden_test.dart | 231 -------- .../web_ui/test/html/shadow_golden_test.dart | 20 - .../common/persistent_cache_unittests.cc | 162 ------ .../flutter/shell/common/shell_unittests.cc | 2 - .../testing/dart/compositing_test.dart | 4 - 39 files changed, 5 insertions(+), 1921 deletions(-) delete mode 100644 engine/src/flutter/flow/layers/physical_shape_layer.cc delete mode 100644 engine/src/flutter/flow/layers/physical_shape_layer.h delete mode 100644 engine/src/flutter/flow/layers/physical_shape_layer_unittests.cc diff --git a/engine/src/flutter/ci/licenses_golden/excluded_files b/engine/src/flutter/ci/licenses_golden/excluded_files index 00385d59ee..76f59a6106 100644 --- a/engine/src/flutter/ci/licenses_golden/excluded_files +++ b/engine/src/flutter/ci/licenses_golden/excluded_files @@ -67,7 +67,6 @@ ../../../flutter/flow/layers/offscreen_surface_unittests.cc ../../../flutter/flow/layers/opacity_layer_unittests.cc ../../../flutter/flow/layers/performance_overlay_layer_unittests.cc -../../../flutter/flow/layers/physical_shape_layer_unittests.cc ../../../flutter/flow/layers/platform_view_layer_unittests.cc ../../../flutter/flow/layers/shader_mask_layer_unittests.cc ../../../flutter/flow/layers/texture_layer_unittests.cc diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 6631d202a9..ffcb36dbe7 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -819,8 +819,6 @@ ORIGIN: ../../../flutter/flow/layers/opacity_layer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/opacity_layer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/performance_overlay_layer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/performance_overlay_layer.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/flow/layers/physical_shape_layer.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/flow/layers/physical_shape_layer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/platform_view_layer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/platform_view_layer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/shader_mask_layer.cc + ../../../flutter/LICENSE @@ -3415,8 +3413,6 @@ FILE: ../../../flutter/flow/layers/opacity_layer.cc FILE: ../../../flutter/flow/layers/opacity_layer.h FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.h -FILE: ../../../flutter/flow/layers/physical_shape_layer.cc -FILE: ../../../flutter/flow/layers/physical_shape_layer.h FILE: ../../../flutter/flow/layers/platform_view_layer.cc FILE: ../../../flutter/flow/layers/platform_view_layer.h FILE: ../../../flutter/flow/layers/shader_mask_layer.cc diff --git a/engine/src/flutter/flow/BUILD.gn b/engine/src/flutter/flow/BUILD.gn index f996f0707e..efda895393 100644 --- a/engine/src/flutter/flow/BUILD.gn +++ b/engine/src/flutter/flow/BUILD.gn @@ -56,8 +56,6 @@ source_set("flow") { "layers/opacity_layer.h", "layers/performance_overlay_layer.cc", "layers/performance_overlay_layer.h", - "layers/physical_shape_layer.cc", - "layers/physical_shape_layer.h", "layers/platform_view_layer.cc", "layers/platform_view_layer.h", "layers/shader_mask_layer.cc", @@ -162,7 +160,6 @@ if (enable_unittests) { "layers/offscreen_surface_unittests.cc", "layers/opacity_layer_unittests.cc", "layers/performance_overlay_layer_unittests.cc", - "layers/physical_shape_layer_unittests.cc", "layers/platform_view_layer_unittests.cc", "layers/shader_mask_layer_unittests.cc", "layers/texture_layer_unittests.cc", diff --git a/engine/src/flutter/flow/compositor_context.cc b/engine/src/flutter/flow/compositor_context.cc index cb119669d6..c6817195e9 100644 --- a/engine/src/flutter/flow/compositor_context.cc +++ b/engine/src/flutter/flow/compositor_context.cc @@ -16,9 +16,7 @@ std::optional FrameDamage::ComputeClipRect( bool has_raster_cache) { if (layer_tree.root_layer()) { PaintRegionMap empty_paint_region_map; - DiffContext context(layer_tree.frame_size(), - layer_tree.device_pixel_ratio(), - layer_tree.paint_region_map(), + DiffContext context(layer_tree.frame_size(), layer_tree.paint_region_map(), prev_layer_tree_ ? prev_layer_tree_->paint_region_map() : empty_paint_region_map, has_raster_cache); diff --git a/engine/src/flutter/flow/diff_context.cc b/engine/src/flutter/flow/diff_context.cc index 5310ef9939..0176279d84 100644 --- a/engine/src/flutter/flow/diff_context.cc +++ b/engine/src/flutter/flow/diff_context.cc @@ -8,14 +8,12 @@ namespace flutter { DiffContext::DiffContext(SkISize frame_size, - double frame_device_pixel_ratio, PaintRegionMap& this_frame_paint_region_map, const PaintRegionMap& last_frame_paint_region_map, bool has_raster_cache) : clip_tracker_(DisplayListMatrixClipTracker(kGiantRect, SkMatrix::I())), rects_(std::make_shared>()), frame_size_(frame_size), - frame_device_pixel_ratio_(frame_device_pixel_ratio), this_frame_paint_region_map_(this_frame_paint_region_map), last_frame_paint_region_map_(last_frame_paint_region_map), has_raster_cache_(has_raster_cache) {} diff --git a/engine/src/flutter/flow/diff_context.h b/engine/src/flutter/flow/diff_context.h index f4f0895542..60c36a14ba 100644 --- a/engine/src/flutter/flow/diff_context.h +++ b/engine/src/flutter/flow/diff_context.h @@ -43,7 +43,6 @@ using PaintRegionMap = std::map; class DiffContext { public: explicit DiffContext(SkISize frame_size, - double device_pixel_aspect_ratio, PaintRegionMap& this_frame_paint_region_map, const PaintRegionMap& last_frame_paint_region_map, bool has_raster_cache); @@ -141,8 +140,6 @@ class DiffContext { int horizontal_clip_alignment = 0, int vertical_clip_alignment = 0) const; - double frame_device_pixel_ratio() const { return frame_device_pixel_ratio_; }; - // Adds the region to current damage. Used for removed layers, where instead // of diffing the layer its paint region is direcly added to damage. void AddDamage(const PaintRegion& damage); @@ -234,7 +231,6 @@ class DiffContext { std::shared_ptr> rects_; State state_; SkISize frame_size_; - double frame_device_pixel_ratio_; std::vector state_stack_; std::vector filter_bounds_adjustment_stack_; diff --git a/engine/src/flutter/flow/layers/checkerboard_layertree_unittests.cc b/engine/src/flutter/flow/layers/checkerboard_layertree_unittests.cc index 7917b5eff3..e82b83e42f 100644 --- a/engine/src/flutter/flow/layers/checkerboard_layertree_unittests.cc +++ b/engine/src/flutter/flow/layers/checkerboard_layertree_unittests.cc @@ -5,7 +5,6 @@ #include "flutter/flow/layers/clip_path_layer.h" #include "flutter/flow/layers/clip_rect_layer.h" #include "flutter/flow/layers/clip_rrect_layer.h" -#include "flutter/flow/layers/physical_shape_layer.h" #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" @@ -221,72 +220,6 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) { MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); } -TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) { - constexpr float initial_elevation = 20.0f; - const SkRect paint_bounds = SkRect::MakeXYWH(0, 0, 8, 8); - SkPath layer_path = - SkPath().addRect(paint_bounds).addOval(paint_bounds.makeInset(0.1, 0.1)); - auto layer = std::make_shared( - SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path, - Clip::antiAliasWithSaveLayer); - - layer->Preroll(preroll_context()); - // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and - // their shadows , so we do not do any painting there. - EXPECT_EQ(layer->paint_bounds(), - DlCanvas::ComputeShadowBounds(layer_path, initial_elevation, 1.0f, - SkMatrix())); - EXPECT_TRUE(layer->needs_painting(paint_context())); - EXPECT_EQ(layer->elevation(), initial_elevation); - - const DlPaint clip_paint; - DlPaint layer_paint; - layer_paint.setColor(SK_ColorGREEN); - layer_paint.setAntiAlias(true); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevation, false, 1}}, - MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipPathData{layer_path, ClipOp::kIntersect, - MockCanvas::kSoft_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint, - nullptr, 2}}, - MockCanvas::DrawCall{2, MockCanvas::DrawPaintData{layer_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); - - mock_canvas().reset_draw_calls(); - - layer->Paint(checkerboard_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevation, false, 1}}, - MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipPathData{layer_path, ClipOp::kIntersect, - MockCanvas::kSoft_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint, - nullptr, 2}}, - MockCanvas::DrawCall{2, MockCanvas::DrawPaintData{layer_paint}}, - // start DrawCheckerboard calls - MockCanvas::DrawCall{2, - MockCanvas::DrawRectData{layer->paint_bounds(), - checkerboard_paint()}}, - // end DrawCheckerboard calls - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - #endif } // namespace testing } // namespace flutter diff --git a/engine/src/flutter/flow/layers/layer.h b/engine/src/flutter/flow/layers/layer.h index b4c703cffa..f1f1056a5e 100644 --- a/engine/src/flutter/flow/layers/layer.h +++ b/engine/src/flutter/flow/layers/layer.h @@ -63,7 +63,6 @@ struct PrerollContext { const Stopwatch& raster_time; const Stopwatch& ui_time; std::shared_ptr texture_registry; - const float frame_device_pixel_ratio = 1.0f; // These allow us to track properties like elevation, opacity, and the // presence of a platform view during Preroll. @@ -114,7 +113,6 @@ struct PaintContext { const Stopwatch& ui_time; std::shared_ptr texture_registry; const RasterCache* raster_cache; - const float frame_device_pixel_ratio = 1.0f; // Snapshot store to collect leaf layer snapshots. The store is non-null // only when leaf layer tracing is enabled. diff --git a/engine/src/flutter/flow/layers/layer_raster_cache_item.cc b/engine/src/flutter/flow/layers/layer_raster_cache_item.cc index 6d130d2299..75b116e4c2 100644 --- a/engine/src/flutter/flow/layers/layer_raster_cache_item.cc +++ b/engine/src/flutter/flow/layers/layer_raster_cache_item.cc @@ -118,7 +118,6 @@ bool Rasterize(RasterCacheItem::CacheState cache_state, .ui_time = paint_context.ui_time, .texture_registry = paint_context.texture_registry, .raster_cache = paint_context.raster_cache, - .frame_device_pixel_ratio = paint_context.frame_device_pixel_ratio, // clang-format on }; diff --git a/engine/src/flutter/flow/layers/layer_tree.cc b/engine/src/flutter/flow/layers/layer_tree.cc index d01b243ab3..1ad6b64c18 100644 --- a/engine/src/flutter/flow/layers/layer_tree.cc +++ b/engine/src/flutter/flow/layers/layer_tree.cc @@ -64,7 +64,6 @@ bool LayerTree::Preroll(CompositorContext::ScopedFrame& frame, .raster_time = frame.context().raster_time(), .ui_time = frame.context().ui_time(), .texture_registry = frame.context().texture_registry(), - .frame_device_pixel_ratio = device_pixel_ratio_, .raster_cached_entries = &raster_cache_items_, .display_list_enabled = frame.display_list_builder() != nullptr, // clang-format on @@ -141,7 +140,6 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, .ui_time = frame.context().ui_time(), .texture_registry = frame.context().texture_registry(), .raster_cache = cache, - .frame_device_pixel_ratio = device_pixel_ratio_, .layer_snapshot_store = snapshot_store, .enable_leaf_layer_tracing = enable_leaf_layer_tracing_, .aiks_context = frame.aiks_context(), @@ -182,7 +180,6 @@ sk_sp LayerTree::Flatten( .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, .texture_registry = texture_registry, - .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on }; @@ -199,7 +196,6 @@ sk_sp LayerTree::Flatten( .ui_time = unused_stopwatch, .texture_registry = texture_registry, .raster_cache = nullptr, - .frame_device_pixel_ratio = device_pixel_ratio_, .layer_snapshot_store = nullptr, .enable_leaf_layer_tracing = false, // clang-format on diff --git a/engine/src/flutter/flow/layers/layer_tree_unittests.cc b/engine/src/flutter/flow/layers/layer_tree_unittests.cc index ea655b5b44..b63fa59d99 100644 --- a/engine/src/flutter/flow/layers/layer_tree_unittests.cc +++ b/engine/src/flutter/flow/layers/layer_tree_unittests.cc @@ -216,7 +216,6 @@ TEST_F(LayerTreeTest, PrerollContextInitialization) { EXPECT_EQ(&context.raster_time, &mock_raster_time); EXPECT_EQ(&context.ui_time, &mock_ui_time); EXPECT_EQ(context.texture_registry.get(), mock_registry.get()); - EXPECT_EQ(context.frame_device_pixel_ratio, 1.0f); EXPECT_EQ(context.has_platform_view, false); EXPECT_EQ(context.has_texture_layer, false); @@ -252,7 +251,6 @@ TEST_F(LayerTreeTest, PaintContextInitialization) { EXPECT_EQ(context.texture_registry.get(), mock_registry.get()); EXPECT_EQ(context.raster_cache, nullptr); EXPECT_EQ(context.state_stack.checkerboard_func(), nullptr); - EXPECT_EQ(context.frame_device_pixel_ratio, 1.0f); EXPECT_EQ(context.enable_leaf_layer_tracing, false); EXPECT_EQ(context.layer_snapshot_store, nullptr); diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc b/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc index 86049c4f0c..9ef2b48cca 100644 --- a/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc +++ b/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc @@ -74,7 +74,6 @@ static void TestPerformanceOverlayLayerGold(int refresh_rate) { .ui_time = mock_stopwatch, .texture_registry = nullptr, .raster_cache = nullptr, - .frame_device_pixel_ratio = 1.0f, // clang-format on }; diff --git a/engine/src/flutter/flow/layers/physical_shape_layer.cc b/engine/src/flutter/flow/layers/physical_shape_layer.cc deleted file mode 100644 index c23711453b..0000000000 --- a/engine/src/flutter/flow/layers/physical_shape_layer.cc +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/flow/layers/physical_shape_layer.h" - -#include "flutter/flow/paint_utils.h" - -namespace flutter { - -PhysicalShapeLayer::PhysicalShapeLayer(DlColor color, - DlColor shadow_color, - float elevation, - const SkPath& path, - Clip clip_behavior) - : color_(color), - shadow_color_(shadow_color), - elevation_(elevation), - path_(path), - clip_behavior_(clip_behavior) {} - -void PhysicalShapeLayer::Diff(DiffContext* context, const Layer* old_layer) { - DiffContext::AutoSubtreeRestore subtree(context); - auto* prev = static_cast(old_layer); - if (!context->IsSubtreeDirty()) { - FML_DCHECK(prev); - if (color_ != prev->color_ || shadow_color_ != prev->shadow_color_ || - elevation_ != prev->elevation() || path_ != prev->path_ || - clip_behavior_ != prev->clip_behavior_) { - context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer)); - } - } - - SkRect bounds; - if (elevation_ == 0) { - bounds = path_.getBounds(); - } else { - bounds = DlCanvas::ComputeShadowBounds(path_, elevation_, - context->frame_device_pixel_ratio(), - context->GetTransform3x3()); - } - - context->AddLayerBounds(bounds); - - // Only push cull rect if there is clip. - if (clip_behavior_ == Clip::none || context->PushCullRect(bounds)) { - DiffChildren(context, prev); - } - context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); -} - -void PhysicalShapeLayer::Preroll(PrerollContext* context) { - Layer::AutoPrerollSaveLayerState save = - Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); - - SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, &child_paint_bounds); - context->renderable_state_flags = - UsesSaveLayer() ? Layer::kSaveLayerRenderFlags : 0; - - SkRect paint_bounds; - if (elevation_ == 0) { - paint_bounds = path_.getBounds(); - } else { - // We will draw the shadow in Paint(), so add some margin to the paint - // bounds to leave space for the shadow. - paint_bounds = DlCanvas::ComputeShadowBounds( - path_, elevation_, context->frame_device_pixel_ratio, - context->state_stack.transform_3x3()); - } - - if (clip_behavior_ == Clip::none) { - paint_bounds.join(child_paint_bounds); - } - - set_paint_bounds(paint_bounds); -} - -void PhysicalShapeLayer::Paint(PaintContext& context) const { - FML_DCHECK(needs_painting(context)); - - if (elevation_ != 0) { - context.canvas->DrawShadow(path_, shadow_color_, elevation_, - SkColorGetA(color_) != 0xff, - context.frame_device_pixel_ratio); - } - - // Call drawPath without clip if possible for better performance. - DlPaint paint; - paint.setColor(color_); - paint.setAntiAlias(true); - if (clip_behavior_ != Clip::antiAliasWithSaveLayer) { - context.canvas->DrawPath(path_, paint); - } - - auto mutator = context.state_stack.save(); - switch (clip_behavior_) { - case Clip::hardEdge: - mutator.clipPath(path_, false); - break; - case Clip::antiAlias: - mutator.clipPath(path_, true); - break; - case Clip::antiAliasWithSaveLayer: { - TRACE_EVENT0("flutter", "Canvas::saveLayer"); - mutator.clipPath(path_, true); - mutator.saveLayer(paint_bounds()); - } break; - case Clip::none: - break; - } - - if (UsesSaveLayer()) { - // If we want to avoid the bleeding edge artifact - // (https://github.com/flutter/flutter/issues/18057#issue-328003931) - // using saveLayer, we have to call drawPaint instead of drawPath as - // anti-aliased drawPath will always have such artifacts. - context.canvas->DrawPaint(paint); - } - - PaintChildren(context); -} - -} // namespace flutter diff --git a/engine/src/flutter/flow/layers/physical_shape_layer.h b/engine/src/flutter/flow/layers/physical_shape_layer.h deleted file mode 100644 index c14317676b..0000000000 --- a/engine/src/flutter/flow/layers/physical_shape_layer.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ -#define FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ - -#include "flutter/flow/layers/container_layer.h" - -namespace flutter { - -class PhysicalShapeLayer : public ContainerLayer { - public: - PhysicalShapeLayer(DlColor color, - DlColor shadow_color, - float elevation, - const SkPath& path, - Clip clip_behavior); - - void Diff(DiffContext* context, const Layer* old_layer) override; - - void Preroll(PrerollContext* context) override; - - void Paint(PaintContext& context) const override; - - bool UsesSaveLayer() const { - return clip_behavior_ == Clip::antiAliasWithSaveLayer; - } - - float elevation() const { return elevation_; } - - private: - DlColor color_; - DlColor shadow_color_; - float elevation_ = 0.0f; - SkPath path_; - Clip clip_behavior_; -}; - -} // namespace flutter - -#endif // FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ diff --git a/engine/src/flutter/flow/layers/physical_shape_layer_unittests.cc b/engine/src/flutter/flow/layers/physical_shape_layer_unittests.cc deleted file mode 100644 index 6c97b45578..0000000000 --- a/engine/src/flutter/flow/layers/physical_shape_layer_unittests.cc +++ /dev/null @@ -1,509 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/flow/layers/physical_shape_layer.h" - -#include "flutter/flow/testing/diff_context_test.h" -#include "flutter/flow/testing/layer_test.h" -#include "flutter/flow/testing/mock_layer.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" - -#include "third_party/skia/include/core/SkSurface.h" - -namespace flutter { -namespace testing { - -using PhysicalShapeLayerTest = LayerTest; - -using ClipOp = DlCanvas::ClipOp; - -#ifndef NDEBUG -TEST_F(PhysicalShapeLayerTest, PaintingEmptyLayerDies) { - auto layer = - std::make_shared(DlColor::kBlack(), DlColor::kBlack(), - 0.0f, // elevation - SkPath(), Clip::none); - - layer->Preroll(preroll_context()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_EQ(layer->child_paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting(paint_context())); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(context\\)"); -} - -TEST_F(PhysicalShapeLayerTest, PaintBeforePrerollDies) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_layer = std::make_shared(child_path, DlPaint()); - auto layer = - std::make_shared(DlColor::kBlack(), DlColor::kBlack(), - 0.0f, // elevation - SkPath(), Clip::none); - layer->Add(mock_layer); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(context\\)"); -} -#endif - -TEST_F(PhysicalShapeLayerTest, NonEmptyLayer) { - SkPath layer_path; - layer_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::none); - layer->Preroll(preroll_context()); - EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds()); - EXPECT_EQ(layer->child_paint_bounds(), SkRect::MakeEmpty()); - EXPECT_TRUE(layer->needs_painting(paint_context())); - - DlPaint layer_paint; - layer_paint.setColor(DlColor::kGreen()); - layer_paint.setAntiAlias(true); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}})); -} - -TEST_F(PhysicalShapeLayerTest, ChildrenLargerThanPathClip) { - const SkRect layer_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkRect child_bounds1 = SkRect::MakeLTRB(4, 0, 12, 12); - const SkRect child_bounds2 = SkRect::MakeLTRB(3, 2, 5, 15); - SkPath layer_path = - SkPath().addRect(layer_bounds).addOval(layer_bounds.makeInset(0.1, 0.1)); - SkPath child1_path = SkPath() - .addRect(child_bounds1) - .addOval(child_bounds1.makeInset(0.1, 0.1)); - SkPath child2_path = SkPath() - .addRect(child_bounds2) - .addOval(child_bounds2.makeInset(0.1, 0.1)); - auto child1 = - std::make_shared(DlColor::kRed(), DlColor::kBlack(), - 0.0f, // elevation - child1_path, Clip::none); - auto child2 = - std::make_shared(DlColor::kBlue(), DlColor::kBlack(), - 0.0f, // elevation - child2_path, Clip::none); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::hardEdge); - layer->Add(child1); - layer->Add(child2); - - SkRect child_paint_bounds = SkRect::MakeEmpty(); - layer->Preroll(preroll_context()); - child_paint_bounds.join(child1->paint_bounds()); - child_paint_bounds.join(child2->paint_bounds()); - EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds()); - EXPECT_NE(layer->paint_bounds(), child_paint_bounds); - EXPECT_EQ(layer->child_paint_bounds(), child_paint_bounds); - EXPECT_TRUE(layer->needs_painting(paint_context())); - - DlPaint layer_paint; - layer_paint.setColor(DlColor::kGreen()); - layer_paint.setAntiAlias(true); - DlPaint child1_paint; - child1_paint.setColor(DlColor::kRed()); - child1_paint.setAntiAlias(true); - DlPaint child2_paint; - child2_paint.setColor(DlColor::kBlue()); - child2_paint.setAntiAlias(true); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({ - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipPathData{layer_path, ClipOp::kIntersect}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child1_path, child1_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}, - })); - DisplayListBuilder expected_builder; - { // layer::Paint() - expected_builder.DrawPath(layer_path, - DlPaint(DlColor::kGreen()).setAntiAlias(true)); - expected_builder.Save(); - { - expected_builder.ClipPath(layer_path, ClipOp::kIntersect, false); - { // child1::Paint() - expected_builder.DrawPath(child1_path, - DlPaint(DlColor::kRed()).setAntiAlias(true)); - } - // child2::Paint() is not called due to layer cullling - // This is the expected and intended behavior. - } - expected_builder.Restore(); - } - layer->Paint(display_list_paint_context()); - EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); -} - -TEST_F(PhysicalShapeLayerTest, ChildrenLargerThanPathNoClip) { - SkPath layer_path; - layer_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkPath child1_path; - child1_path.addRect(4, 0, 12, 12).close(); - SkPath child2_path; - child2_path.addRect(3, 2, 5, 15).close(); - auto child1 = - std::make_shared(DlColor::kRed(), DlColor::kBlack(), - 0.0f, // elevation - child1_path, Clip::none); - auto child2 = - std::make_shared(DlColor::kBlue(), DlColor::kBlack(), - 0.0f, // elevation - child2_path, Clip::none); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::none); - layer->Add(child1); - layer->Add(child2); - - layer->Preroll(preroll_context()); - SkRect child_bounds = child1->paint_bounds(); - child_bounds.join(child2->paint_bounds()); - SkRect total_bounds = child_bounds; - total_bounds.join(layer_path.getBounds()); - EXPECT_NE(layer->paint_bounds(), layer_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), total_bounds); - EXPECT_EQ(layer->child_paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting(paint_context())); - - DlPaint layer_paint; - layer_paint.setColor(DlColor::kGreen()); - layer_paint.setAntiAlias(true); - DlPaint child1_paint; - child1_paint.setColor(DlColor::kRed()); - child1_paint.setAntiAlias(true); - DlPaint child2_paint; - child2_paint.setColor(DlColor::kBlue()); - child2_paint.setAntiAlias(true); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child1_path, child1_paint}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child2_path, child2_paint}}})); -} - -TEST_F(PhysicalShapeLayerTest, ElevationSimple) { - constexpr float initial_elevation = 20.0f; - SkPath layer_path; - layer_path.addRect(0, 0, 8, 8).close(); - auto layer = std::make_shared( - DlColor::kGreen(), DlColor::kBlack(), initial_elevation, layer_path, - Clip::none); - - layer->Preroll(preroll_context()); - // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and - // their shadows , so we do not do any painting there. - EXPECT_EQ(layer->paint_bounds(), - DlCanvas::ComputeShadowBounds(layer_path, initial_elevation, 1.0f, - SkMatrix())); - EXPECT_TRUE(layer->needs_painting(paint_context())); - EXPECT_EQ(layer->elevation(), initial_elevation); - - DlPaint layer_paint; - layer_paint.setColor(DlColor::kGreen()); - layer_paint.setAntiAlias(true); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevation, false, 1}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}})); -} - -TEST_F(PhysicalShapeLayerTest, ElevationComplex) { - // The layer tree should look like this: - // layers[0] +1.0f = 1.0f - // | \ - // | \ - // | \ - // | layers[2] +3.0f = 4.0f - // | | - // | layers[3] +4.0f = 8.0f - // | - // | - // layers[1] + 2.0f = 3.0f - constexpr float initial_elevations[4] = {1.0f, 2.0f, 3.0f, 4.0f}; - SkPath layer_path; - layer_path.addRect(0, 0, 80, 80).close(); - - std::shared_ptr layers[4]; - for (int i = 0; i < 4; i += 1) { - layers[i] = std::make_shared( - DlColor::kBlack(), DlColor::kBlack(), initial_elevations[i], layer_path, - Clip::none); - } - layers[0]->Add(layers[1]); - layers[0]->Add(layers[2]); - layers[2]->Add(layers[3]); - - layers[0]->Preroll(preroll_context()); - for (int i = 0; i < 4; i += 1) { - // On Fuchsia, the system compositor handles all elevated - // PhysicalShapeLayers and their shadows , so we do not do any painting - // there. - SkRect paint_bounds = DlCanvas::ComputeShadowBounds( - layer_path, initial_elevations[i], 1.0f /* pixel_ratio */, SkMatrix()); - - // Without clipping the children will be painted as well - for (auto layer : layers[i]->layers()) { - paint_bounds.join(layer->paint_bounds()); - } - EXPECT_EQ(layers[i]->paint_bounds(), paint_bounds); - EXPECT_TRUE(layers[i]->needs_painting(paint_context())); - } - - DlPaint layer_paint; - layer_paint.setColor(DlColor::kBlack()); - layer_paint.setAntiAlias(true); - layers[0]->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevations[0], false, 1}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevations[1], false, 1}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevations[2], false, 1}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawShadowData{layer_path, DlColor::kBlack(), - initial_elevations[3], false, 1}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}})); -} - -TEST_F(PhysicalShapeLayerTest, ShadowNotDependsCtm) { - constexpr SkScalar elevations[] = {1, 2, 3, 4, 5, 10}; - constexpr SkScalar scales[] = {0.5, 1, 1.5, 2, 3, 5}; - constexpr SkScalar translates[] = {0, 1, -1, 0.5, 2, 10}; - - SkPath path; - path.addRect(0, 0, 8, 8).close(); - - for (SkScalar elevation : elevations) { - SkRect baseline_bounds = - DlCanvas::ComputeShadowBounds(path, elevation, 1.0f, SkMatrix()); - for (SkScalar scale : scales) { - for (SkScalar translate_x : translates) { - for (SkScalar translate_y : translates) { - SkMatrix ctm; - ctm.setScaleTranslate(scale, scale, translate_x, translate_y); - SkRect bounds = - DlCanvas::ComputeShadowBounds(path, elevation, scale, ctm); - EXPECT_FLOAT_EQ(bounds.fLeft, baseline_bounds.fLeft); - EXPECT_FLOAT_EQ(bounds.fTop, baseline_bounds.fTop); - EXPECT_FLOAT_EQ(bounds.fRight, baseline_bounds.fRight); - EXPECT_FLOAT_EQ(bounds.fBottom, baseline_bounds.fBottom); - } - } - } - } -} - -static int RasterizedDifferenceInPixels( - const std::function& actual_draw_function, - const std::function& expected_draw_function, - const SkSize& canvas_size) { - sk_sp actual_surface = - SkSurface::MakeRasterN32Premul(canvas_size.width(), canvas_size.height()); - sk_sp expected_surface = - SkSurface::MakeRasterN32Premul(canvas_size.width(), canvas_size.height()); - - actual_surface->getCanvas()->drawColor(SK_ColorWHITE); - expected_surface->getCanvas()->drawColor(SK_ColorWHITE); - - actual_draw_function(actual_surface->getCanvas()); - expected_draw_function(expected_surface->getCanvas()); - - SkPixmap actual_pixels; - EXPECT_TRUE(actual_surface->peekPixels(&actual_pixels)); - - SkPixmap expected_pixels; - EXPECT_TRUE(expected_surface->peekPixels(&expected_pixels)); - - int different_pixels = 0; - for (int y = 0; y < canvas_size.height(); y++) { - const uint32_t* actual_row = actual_pixels.addr32(0, y); - const uint32_t* expected_row = expected_pixels.addr32(0, y); - for (int x = 0; x < canvas_size.width(); x++) { - if (actual_row[x] != expected_row[x]) { - different_pixels++; - } - } - } - return different_pixels; -} - -TEST_F(PhysicalShapeLayerTest, ShadowNotDependsPathSize) { - constexpr SkRect test_cases[][2] = { - {{20, -100, 80, 80}, {20, -1000, 80, 80}}, - {{20, 20, 80, 200}, {20, 20, 80, 2000}}, - }; - - for (const SkRect* test_case : test_cases) { - EXPECT_EQ(RasterizedDifferenceInPixels( - [=](SkCanvas* canvas) { - SkPath path; - path.addRect(test_case[0]).close(); - DlSkCanvasAdapter(canvas).DrawShadow( - path, DlColor::kBlack(), 1.0f, false, 1.0f); - }, - [=](SkCanvas* canvas) { - SkPath path; - path.addRect(test_case[1]).close(); - DlSkCanvasAdapter(canvas).DrawShadow( - path, DlColor::kBlack(), 1.0f, false, 1.0f); - }, - SkSize::Make(100, 100)), - 0); - } -} - -static bool ReadbackResult(PrerollContext* context, - Clip clip_behavior, - const std::shared_ptr& child, - bool before) { - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath layer_path = SkPath().addRect(layer_bounds); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, clip_behavior); - if (child != nullptr) { - layer->Add(child); - } - context->surface_needs_readback = before; - layer->Preroll(context); - return context->surface_needs_readback; -} - -TEST_F(PhysicalShapeLayerTest, Readback) { - PrerollContext* context = preroll_context(); - SkPath path; - DlPaint paint; - - const Clip hard = Clip::hardEdge; - const Clip soft = Clip::antiAlias; - const Clip save_layer = Clip::antiAliasWithSaveLayer; - - std::shared_ptr nochild; - auto reader = std::make_shared(path, paint); - reader->set_fake_reads_surface(true); - auto nonreader = std::make_shared(path, paint); - - // No children, no prior readback -> no readback after - EXPECT_FALSE(ReadbackResult(context, hard, nochild, false)); - EXPECT_FALSE(ReadbackResult(context, soft, nochild, false)); - EXPECT_FALSE(ReadbackResult(context, save_layer, nochild, false)); - - // No children, prior readback -> readback after - EXPECT_TRUE(ReadbackResult(context, hard, nochild, true)); - EXPECT_TRUE(ReadbackResult(context, soft, nochild, true)); - EXPECT_TRUE(ReadbackResult(context, save_layer, nochild, true)); - - // Non readback child, no prior readback -> no readback after - EXPECT_FALSE(ReadbackResult(context, hard, nonreader, false)); - EXPECT_FALSE(ReadbackResult(context, soft, nonreader, false)); - EXPECT_FALSE(ReadbackResult(context, save_layer, nonreader, false)); - - // Non readback child, prior readback -> readback after - EXPECT_TRUE(ReadbackResult(context, hard, nonreader, true)); - EXPECT_TRUE(ReadbackResult(context, soft, nonreader, true)); - EXPECT_TRUE(ReadbackResult(context, save_layer, nonreader, true)); - - // Readback child, no prior readback -> readback after unless SaveLayer - EXPECT_TRUE(ReadbackResult(context, hard, reader, false)); - EXPECT_TRUE(ReadbackResult(context, soft, reader, false)); - EXPECT_FALSE(ReadbackResult(context, save_layer, reader, false)); - - // Readback child, prior readback -> readback after - EXPECT_TRUE(ReadbackResult(context, hard, reader, true)); - EXPECT_TRUE(ReadbackResult(context, soft, reader, true)); - EXPECT_TRUE(ReadbackResult(context, save_layer, reader, true)); -} - -TEST_F(PhysicalShapeLayerTest, OpacityInheritance) { - SkPath layer_path; - layer_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::none); - - PrerollContext* context = preroll_context(); - context->renderable_state_flags = 0; - layer->Preroll(context); - EXPECT_EQ(context->renderable_state_flags, 0); -} - -using PhysicalShapeLayerDiffTest = DiffContextTest; - -TEST_F(PhysicalShapeLayerDiffTest, NoClipPaintRegion) { - MockLayerTree tree1; - const SkPath layer_path = SkPath().addRect(SkRect::MakeXYWH(0, 0, 100, 100)); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::none); - - const SkPath layer_path2 = - SkPath().addRect(SkRect::MakeXYWH(200, 200, 200, 200)); - auto layer2 = std::make_shared(layer_path2); - layer->Add(layer2); - tree1.root()->Add(layer); - - auto damage = DiffLayerTree(tree1, MockLayerTree()); - EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(0, 0, 400, 400)); -} - -TEST_F(PhysicalShapeLayerDiffTest, ClipPaintRegion) { - MockLayerTree tree1; - const SkPath layer_path = SkPath().addRect(SkRect::MakeXYWH(0, 0, 100, 100)); - auto layer = - std::make_shared(DlColor::kGreen(), DlColor::kBlack(), - 0.0f, // elevation - layer_path, Clip::hardEdge); - - const SkPath layer_path2 = - SkPath().addRect(SkRect::MakeXYWH(200, 200, 200, 200)); - auto layer2 = std::make_shared(layer_path2); - layer->Add(layer2); - tree1.root()->Add(layer); - - auto damage = DiffLayerTree(tree1, MockLayerTree()); - EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(0, 0, 100, 100)); -} - -} // namespace testing -} // namespace flutter diff --git a/engine/src/flutter/flow/testing/diff_context_test.cc b/engine/src/flutter/flow/testing/diff_context_test.cc index 9860c76688..20153a0140 100644 --- a/engine/src/flutter/flow/testing/diff_context_test.cc +++ b/engine/src/flutter/flow/testing/diff_context_test.cc @@ -20,7 +20,7 @@ Damage DiffContextTest::DiffLayerTree(MockLayerTree& layer_tree, bool use_raster_cache) { FML_CHECK(layer_tree.size() == old_layer_tree.size()); - DiffContext dc(layer_tree.size(), 1, layer_tree.paint_region_map(), + DiffContext dc(layer_tree.size(), layer_tree.paint_region_map(), old_layer_tree.paint_region_map(), use_raster_cache); dc.PushCullRect( SkRect::MakeIWH(layer_tree.size().width(), layer_tree.size().height())); diff --git a/engine/src/flutter/flow/testing/layer_test.h b/engine/src/flutter/flow/testing/layer_test.h index 455e74b842..70e26670a8 100644 --- a/engine/src/flutter/flow/testing/layer_test.h +++ b/engine/src/flutter/flow/testing/layer_test.h @@ -56,7 +56,6 @@ class LayerTestBase : public CanvasTestBase { .raster_time = raster_time_, .ui_time = ui_time_, .texture_registry = texture_registry_, - .frame_device_pixel_ratio = 1.0f, .has_platform_view = false, .raster_cached_entries = &cacheable_items_, // clang-format on @@ -71,7 +70,6 @@ class LayerTestBase : public CanvasTestBase { .ui_time = ui_time_, .texture_registry = texture_registry_, .raster_cache = nullptr, - .frame_device_pixel_ratio = 1.0f, // clang-format on }, display_list_builder_(kDlBounds), @@ -85,7 +83,6 @@ class LayerTestBase : public CanvasTestBase { .ui_time = ui_time_, .texture_registry = texture_registry_, .raster_cache = nullptr, - .frame_device_pixel_ratio = 1.0f, // clang-format on }, checkerboard_context_{ @@ -98,7 +95,6 @@ class LayerTestBase : public CanvasTestBase { .ui_time = ui_time_, .texture_registry = texture_registry_, .raster_cache = nullptr, - .frame_device_pixel_ratio = 1.0f, // clang-format on } { use_null_raster_cache(); diff --git a/engine/src/flutter/flow/testing/mock_raster_cache.cc b/engine/src/flutter/flow/testing/mock_raster_cache.cc index fd6ea7ec7d..9effd6af12 100644 --- a/engine/src/flutter/flow/testing/mock_raster_cache.cc +++ b/engine/src/flutter/flow/testing/mock_raster_cache.cc @@ -100,7 +100,6 @@ PrerollContextHolder GetSamplePrerollContextHolder( .raster_time = *raster_time, .ui_time = *ui_time, .texture_registry = nullptr, - .frame_device_pixel_ratio = 1.0f, .has_platform_view = false, .has_texture_layer = false, .raster_cached_entries = &raster_cache_items_, @@ -128,7 +127,6 @@ PaintContextHolder GetSamplePaintContextHolder( .ui_time = *ui_time, .texture_registry = nullptr, .raster_cache = raster_cache, - .frame_device_pixel_ratio = 1.0f, }, // clang-format on srgb}; diff --git a/engine/src/flutter/flow/testing/mock_raster_cache.h b/engine/src/flutter/flow/testing/mock_raster_cache.h index beb42d2676..392914f5b2 100644 --- a/engine/src/flutter/flow/testing/mock_raster_cache.h +++ b/engine/src/flutter/flow/testing/mock_raster_cache.h @@ -85,7 +85,6 @@ class MockRasterCache : public RasterCache { .raster_time = raster_time_, .ui_time = ui_time_, .texture_registry = texture_registry_, - .frame_device_pixel_ratio = 1.0f, .has_platform_view = false, .has_texture_layer = false, .raster_cached_entries = &raster_cache_items_ @@ -103,7 +102,6 @@ class MockRasterCache : public RasterCache { .ui_time = ui_time_, .texture_registry = texture_registry_, .raster_cache = nullptr, - .frame_device_pixel_ratio = 1.0f, // clang-format on }; }; diff --git a/engine/src/flutter/lib/ui/compositing.dart b/engine/src/flutter/lib/ui/compositing.dart index f20ecff734..e9700d49bd 100644 --- a/engine/src/flutter/lib/ui/compositing.dart +++ b/engine/src/flutter/lib/ui/compositing.dart @@ -212,15 +212,6 @@ class ShaderMaskEngineLayer extends _EngineLayerWrapper { ShaderMaskEngineLayer._(super.nativeLayer) : super._(); } -/// An opaque handle to a physical shape engine layer. -/// -/// Instances of this class are created by [SceneBuilder.pushPhysicalShape]. -/// -/// {@macro dart.ui.sceneBuilder.oldLayerCompatibility} -class PhysicalShapeEngineLayer extends _EngineLayerWrapper { - PhysicalShapeEngineLayer._(super.nativeLayer) : super._(); -} - /// Builds a [Scene] containing the given visuals. /// /// A [Scene] can then be rendered using [FlutterView.render]. @@ -604,53 +595,6 @@ class SceneBuilder extends NativeFieldWrapperClass1 { int filterQualityIndex, EngineLayer? oldLayer); - /// Pushes a physical layer operation for an arbitrary shape onto the - /// operation stack. - /// - /// By default, the layer's content will not be clipped (clip = [Clip.none]). - /// If clip equals [Clip.hardEdge], [Clip.antiAlias], or [Clip.antiAliasWithSaveLayer], - /// then the content is clipped to the given shape defined by [path]. - /// - /// If [elevation] is greater than 0.0, then a shadow is drawn around the layer. - /// [shadowColor] defines the color of the shadow if present and [color] defines the - /// color of the layer background. - /// - /// {@macro dart.ui.sceneBuilder.oldLayer} - /// - /// {@macro dart.ui.sceneBuilder.oldLayerVsRetained} - /// - /// See [pop] for details about the operation stack, and [Clip] for different clip modes. - @Deprecated( - 'Use a clip and canvas operations directly (See RenderPhysicalModel). ' - 'This feature was deprecated after v3.1.0-0.0.pre.', - ) - PhysicalShapeEngineLayer pushPhysicalShape({ - required Path path, - required double elevation, - required Color color, - Color? shadowColor, - Clip clipBehavior = Clip.none, - PhysicalShapeEngineLayer? oldLayer, - }) { - assert(_debugCheckCanBeUsedAsOldLayer(oldLayer, 'pushPhysicalShape')); - final EngineLayer engineLayer = EngineLayer._(); - _pushPhysicalShape(engineLayer, path, elevation, color.value, shadowColor?.value ?? 0xFF000000, - clipBehavior.index, oldLayer?._nativeLayer); - final PhysicalShapeEngineLayer layer = PhysicalShapeEngineLayer._(engineLayer); - assert(_debugPushLayer(layer)); - return layer; - } - - @Native, Handle, Pointer, Double, Int32, Int32, Int32, Handle)>(symbol: 'SceneBuilder::pushPhysicalShape') - external void _pushPhysicalShape( - EngineLayer outEngineLayer, - Path path, - double elevation, - int color, - int shadowColor, - int clipBehavior, - EngineLayer? oldLayer); - /// Ends the effect of the most recently pushed operation. /// /// Internally the scene builder maintains a stack of operations. Each of the diff --git a/engine/src/flutter/lib/ui/compositing/scene_builder.cc b/engine/src/flutter/lib/ui/compositing/scene_builder.cc index 63ac03c92c..9f6d58de31 100644 --- a/engine/src/flutter/lib/ui/compositing/scene_builder.cc +++ b/engine/src/flutter/lib/ui/compositing/scene_builder.cc @@ -16,7 +16,6 @@ #include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/layers/opacity_layer.h" #include "flutter/flow/layers/performance_overlay_layer.h" -#include "flutter/flow/layers/physical_shape_layer.h" #include "flutter/flow/layers/platform_view_layer.h" #include "flutter/flow/layers/shader_mask_layer.h" #include "flutter/flow/layers/texture_layer.h" @@ -203,25 +202,6 @@ void SceneBuilder::pushShaderMask(Dart_Handle layer_handle, } } -void SceneBuilder::pushPhysicalShape(Dart_Handle layer_handle, - const CanvasPath* path, - double elevation, - int color, - int shadow_color, - int clipBehavior, - const fml::RefPtr& oldLayer) { - auto layer = std::make_shared( - static_cast(color), static_cast(shadow_color), - static_cast(elevation), path->path(), - static_cast(clipBehavior)); - PushLayer(layer); - EngineLayer::MakeRetained(layer_handle, layer); - - if (oldLayer && oldLayer->Layer()) { - layer->AssignOldLayer(oldLayer->Layer().get()); - } -} - void SceneBuilder::addRetained(const fml::RefPtr& retainedLayer) { AddLayer(retainedLayer->Layer()); } diff --git a/engine/src/flutter/lib/ui/compositing/scene_builder.h b/engine/src/flutter/lib/ui/compositing/scene_builder.h index f2de29c480..97fcbf7e94 100644 --- a/engine/src/flutter/lib/ui/compositing/scene_builder.h +++ b/engine/src/flutter/lib/ui/compositing/scene_builder.h @@ -90,13 +90,6 @@ class SceneBuilder : public RefCountedDartWrappable { int blendMode, int filterQualityIndex, const fml::RefPtr& oldLayer); - void pushPhysicalShape(Dart_Handle layer_handle, - const CanvasPath* path, - double elevation, - int color, - int shadowColor, - int clipBehavior, - const fml::RefPtr& oldLayer); void addRetained(const fml::RefPtr& retainedLayer); diff --git a/engine/src/flutter/lib/ui/dart_ui.cc b/engine/src/flutter/lib/ui/dart_ui.cc index 57242c11ac..c32420065e 100644 --- a/engine/src/flutter/lib/ui/dart_ui.cc +++ b/engine/src/flutter/lib/ui/dart_ui.cc @@ -286,7 +286,6 @@ typedef CanvasPath Path; V(SceneBuilder, pushImageFilter, 4) \ V(SceneBuilder, pushOffset, 5) \ V(SceneBuilder, pushOpacity, 6) \ - V(SceneBuilder, pushPhysicalShape, 8) \ V(SceneBuilder, pushShaderMask, 10) \ V(SceneBuilder, pushTransformHandle, 4) \ V(SceneBuilder, setCheckerboardOffscreenLayers, 2) \ diff --git a/engine/src/flutter/lib/web_ui/lib/compositing.dart b/engine/src/flutter/lib/web_ui/lib/compositing.dart index d3f0acddd6..050a5425e7 100644 --- a/engine/src/flutter/lib/web_ui/lib/compositing.dart +++ b/engine/src/flutter/lib/web_ui/lib/compositing.dart @@ -30,8 +30,6 @@ abstract class BackdropFilterEngineLayer implements EngineLayer {} abstract class ShaderMaskEngineLayer implements EngineLayer {} -abstract class PhysicalShapeEngineLayer implements EngineLayer {} - abstract class SceneBuilder { factory SceneBuilder() => engine.renderer.createSceneBuilder(); @@ -86,18 +84,6 @@ abstract class SceneBuilder { ShaderMaskEngineLayer? oldLayer, FilterQuality filterQuality = FilterQuality.low, }); - @Deprecated( - 'Use a clip and canvas operations directly (See RenderPhysicalModel). ' - 'This feature was deprecated after v3.1.0-0.0.pre.', - ) - PhysicalShapeEngineLayer pushPhysicalShape({ - required Path path, - required double elevation, - required Color color, - Color? shadowColor, - Clip clipBehavior = Clip.none, - PhysicalShapeEngineLayer? oldLayer, - }); void addRetained(EngineLayer retainedLayer); void pop(); void addPerformanceOverlay(int enabledOptions, Rect bounds); diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer.dart index 640b3712e3..b357465e76 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer.dart @@ -12,7 +12,6 @@ import 'painting.dart'; import 'path.dart'; import 'picture.dart'; import 'raster_cache.dart'; -import 'util.dart'; /// A layer to be composed into a scene. /// @@ -482,84 +481,6 @@ class PictureLayer extends Layer { } } -/// A layer representing a physical shape. -/// -/// The shape clips its children to a given [Path], and casts a shadow based -/// on the given elevation. -class PhysicalShapeEngineLayer extends ContainerLayer - implements ui.PhysicalShapeEngineLayer { - PhysicalShapeEngineLayer( - this._elevation, - this._color, - this._shadowColor, - this._path, - this._clipBehavior, - ); - - final double _elevation; - final ui.Color _color; - final ui.Color? _shadowColor; // ignore: use_late_for_private_fields_and_variables - final CkPath _path; - final ui.Clip _clipBehavior; - - @override - void preroll(PrerollContext prerollContext, Matrix4 matrix) { - prerollChildren(prerollContext, matrix); - paintBounds = computeSkShadowBounds( - _path, _elevation, ui.window.devicePixelRatio, matrix); - } - - @override - void paint(PaintContext paintContext) { - assert(needsPainting); - - if (_elevation != 0) { - drawShadow(paintContext.leafNodesCanvas!, _path, _shadowColor!, - _elevation, _color.alpha != 0xff); - } - - final CkPaint paint = CkPaint()..color = _color; - if (_clipBehavior != ui.Clip.antiAliasWithSaveLayer) { - paintContext.leafNodesCanvas!.drawPath(_path, paint); - } - - final int saveCount = paintContext.internalNodesCanvas.save(); - switch (_clipBehavior) { - case ui.Clip.hardEdge: - paintContext.internalNodesCanvas.clipPath(_path, false); - case ui.Clip.antiAlias: - paintContext.internalNodesCanvas.clipPath(_path, true); - case ui.Clip.antiAliasWithSaveLayer: - paintContext.internalNodesCanvas.clipPath(_path, true); - paintContext.internalNodesCanvas.saveLayer(paintBounds, null); - case ui.Clip.none: - break; - } - - if (_clipBehavior == ui.Clip.antiAliasWithSaveLayer) { - // If we want to avoid the bleeding edge artifact - // (https://github.com/flutter/flutter/issues/18057#issue-328003931) - // using saveLayer, we have to call drawPaint instead of drawPath as - // anti-aliased drawPath will always have such artifacts. - paintContext.leafNodesCanvas!.drawPaint(paint); - } - paint.dispose(); - - paintChildren(paintContext); - - paintContext.internalNodesCanvas.restoreToCount(saveCount); - } - - /// Draws a shadow on the given [canvas] for the given [path]. - /// - /// The blur of the shadow is decided by the [elevation], and the - /// shadow is painted with the given [color]. - static void drawShadow(CkCanvas canvas, CkPath path, ui.Color color, - double elevation, bool transparentOccluder) { - canvas.drawShadow(path, color, elevation, transparentOccluder); - } -} - /// A layer which contains a [ui.ColorFilter]. class ColorFilterEngineLayer extends ContainerLayer implements ui.ColorFilterEngineLayer { diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart index e1f71752e6..9048c857a5 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart @@ -177,24 +177,6 @@ class LayerSceneBuilder implements ui.SceneBuilder { return pushLayer(OpacityEngineLayer(alpha, offset)); } - @override - PhysicalShapeEngineLayer pushPhysicalShape({ - required ui.Path path, - required double elevation, - required ui.Color color, - ui.Color? shadowColor, - ui.Clip clipBehavior = ui.Clip.none, - ui.EngineLayer? oldLayer, - }) { - return pushLayer(PhysicalShapeEngineLayer( - elevation, - color, - shadowColor, - path as CkPath, - clipBehavior, - )); - } - @override ShaderMaskEngineLayer pushShaderMask( ui.Shader shader, diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/html/clip.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/html/clip.dart index cc2303b7a1..d713a48f86 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/html/clip.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/html/clip.dart @@ -5,12 +5,8 @@ import 'package:ui/ui.dart' as ui; import '../dom.dart'; -import '../shadow.dart'; import '../svg.dart'; import '../util.dart'; -import 'dom_canvas.dart'; -import 'painting.dart'; -import 'path/path.dart'; import 'path_to_svg_clip.dart'; import 'surface.dart'; import 'surface_stats.dart'; @@ -190,264 +186,6 @@ class PersistedClipRRect extends PersistedContainerSurface bool get isClipping => true; } -class PersistedPhysicalShape extends PersistedContainerSurface - with _DomClip - implements ui.PhysicalShapeEngineLayer { - PersistedPhysicalShape(PersistedPhysicalShape? super.oldLayer, this.path, - this.elevation, int color, int shadowColor, this.clipBehavior) - : color = ui.Color(color), - shadowColor = ui.Color(shadowColor), - pathBounds = path.getBounds(); - - final SurfacePath path; - final ui.Rect pathBounds; - final double elevation; - final ui.Color color; - final ui.Color shadowColor; - final ui.Clip clipBehavior; - DomElement? _clipElement; - DomElement? _svgElement; - - @override - void recomputeTransformAndClip() { - transform = parent!.transform; - - if (clipBehavior != ui.Clip.none) { - final ui.RRect? roundRect = path.toRoundedRect(); - if (roundRect != null) { - localClipBounds = roundRect.outerRect; - } else { - final ui.Rect? rect = path.toRect(); - if (rect != null) { - localClipBounds = rect; - } else { - localClipBounds = null; - } - } - } else { - localClipBounds = null; - } - projectedClip = null; - } - - void _applyColor() { - rootElement!.style.backgroundColor = color.toCssString(); - } - - @override - DomElement createElement() { - return super.createElement()..setAttribute('clip-type', 'physical-shape'); - } - - @override - void discard() { - super.discard(); - _clipElement?.remove(); - _clipElement = null; - _svgElement?.remove(); - _svgElement = null; - } - - @override - void apply() { - _applyShape(); - } - - void _applyShape() { - _applyColor(); - // Handle special case of round rect physical shape mapping to - // rounded div. - final ui.RRect? roundRect = path.toRoundedRect(); - if (roundRect != null) { - final String borderRadius = - '${roundRect.tlRadiusX}px ${roundRect.trRadiusX}px ' - '${roundRect.brRadiusX}px ${roundRect.blRadiusX}px'; - final DomCSSStyleDeclaration style = rootElement!.style; - style - ..left = '${roundRect.left}px' - ..top = '${roundRect.top}px' - ..width = '${roundRect.width}px' - ..height = '${roundRect.height}px' - ..borderRadius = borderRadius; - childContainer!.style - ..left = '${-roundRect.left}px' - ..top = '${-roundRect.top}px'; - if (clipBehavior != ui.Clip.none) { - style.overflow = 'hidden'; - } - applyCssShadow(rootElement, pathBounds, elevation, shadowColor); - return; - } else { - final ui.Rect? rect = path.toRect(); - if (rect != null) { - final DomCSSStyleDeclaration style = rootElement!.style; - style - ..left = '${rect.left}px' - ..top = '${rect.top}px' - ..width = '${rect.width}px' - ..height = '${rect.height}px' - ..borderRadius = ''; - childContainer!.style - ..left = '${-rect.left}px' - ..top = '${-rect.top}px'; - if (clipBehavior != ui.Clip.none) { - style.overflow = 'hidden'; - } - applyCssShadow(rootElement, pathBounds, elevation, shadowColor); - return; - } else { - final ui.Rect? ovalRect = path.toCircle(); - if (ovalRect != null) { - final double rx = ovalRect.width / 2.0; - final double ry = ovalRect.height / 2.0; - final String borderRadius = - rx == ry ? '${rx}px ' : '${rx}px ${ry}px '; - final DomCSSStyleDeclaration style = rootElement!.style; - final double left = ovalRect.left; - final double top = ovalRect.top; - style - ..left = '${left}px' - ..top = '${top}px' - ..width = '${rx * 2}px' - ..height = '${ry * 2}px' - ..borderRadius = borderRadius; - childContainer!.style - ..left = '${-left}px' - ..top = '${-top}px'; - if (clipBehavior != ui.Clip.none) { - style.overflow = 'hidden'; - } - applyCssShadow(rootElement, pathBounds, elevation, shadowColor); - return; - } - } - } - - /// If code reaches this point, we have a path we want to clip against and - /// potentially have a shadow due to material surface elevation. - /// - /// When there is no shadow we can simply clip a div with a background - /// color using a svg clip path. - /// - /// Otherwise we need to paint svg element for the path and clip - /// contents against same path for shadow to work since box-shadow doesn't - /// take clip-path into account. - /// - /// Webkit has a bug when applying clip-path on an element that has - /// position: absolute and transform - /// (https://bugs.webkit.org/show_bug.cgi?id=141731). - /// To place clipping rectangle correctly - /// we size the inner container to cover full pathBounds instead of sizing - /// to clipping rect bounds (which is the case for elevation == 0.0 where - /// we shift outer/inner clip area instead to position clip-path). - final SVGSVGElement svgClipPath = elevation == 0.0 - ? pathToSvgClipPath(path, - offsetX: -pathBounds.left, - offsetY: -pathBounds.top, - scaleX: 1.0 / pathBounds.width, - scaleY: 1.0 / pathBounds.height) - : pathToSvgClipPath(path, - scaleX: 1.0 / pathBounds.right, - scaleY: 1.0 / pathBounds.bottom); - - /// If apply is called multiple times (without update), remove prior - /// svg clip and render elements. - _clipElement?.remove(); - _svgElement?.remove(); - _clipElement = svgClipPath; - rootElement!.append(_clipElement!); - if (elevation == 0.0) { - setClipPath(rootElement!, createSvgClipUrl()); - final DomCSSStyleDeclaration rootElementStyle = rootElement!.style; - rootElementStyle - ..overflow = '' - ..left = '${pathBounds.left}px' - ..top = '${pathBounds.top}px' - ..width = '${pathBounds.width}px' - ..height = '${pathBounds.height}px' - ..borderRadius = ''; - childContainer!.style - ..left = '-${pathBounds.left}px' - ..top = '-${pathBounds.top}px'; - return; - } - - setClipPath(childContainer!, createSvgClipUrl()); - final DomCSSStyleDeclaration rootElementStyle = rootElement!.style; - rootElementStyle - ..overflow = '' - ..left = '${pathBounds.left}px' - ..top = '${pathBounds.top}px' - ..width = '${pathBounds.width}px' - ..height = '${pathBounds.height}px' - ..borderRadius = ''; - childContainer!.style - ..left = '-${pathBounds.left}px' - ..top = '-${pathBounds.top}px' - ..width = '${pathBounds.right}px' - ..height = '${pathBounds.bottom}px'; - - final ui.Rect pathBounds2 = path.getBounds(); - _svgElement = pathToSvgElement( - path, - SurfacePaintData() - ..style = ui.PaintingStyle.fill - ..color = color.value); - - /// Render element behind the clipped content. - rootElement!.insertBefore(_svgElement!, childContainer); - - final SurfaceShadowData shadow = computeShadow(pathBounds, elevation)!; - final ui.Color boxShadowColor = toShadowColor(shadowColor); - _svgElement!.style - ..filter = 'drop-shadow(${shadow.offset.dx}px ${shadow.offset.dy}px ' - '${shadow.blurWidth}px ' - 'rgba(${boxShadowColor.red}, ${boxShadowColor.green}, ' - '${boxShadowColor.blue}, ${boxShadowColor.alpha / 255}))' - ..transform = 'translate(-${pathBounds2.left}px, -${pathBounds2.top}px)'; - - rootElement!.style.backgroundColor = ''; - } - - @override - void update(PersistedPhysicalShape oldSurface) { - super.update(oldSurface); - final bool pathChanged = oldSurface.path != path; - if (pathChanged) { - localClipBounds = null; - } - if (pathChanged || - oldSurface.elevation != elevation || - oldSurface.shadowColor != shadowColor || - oldSurface.color != color) { - oldSurface._clipElement?.remove(); - oldSurface._clipElement = null; - oldSurface._svgElement?.remove(); - oldSurface._svgElement = null; - _clipElement?.remove(); - _clipElement = null; - _svgElement?.remove(); - _svgElement = null; - // Reset style on prior element since we may have switched between - // rect/rrect and arbitrary path. - setClipPath(rootElement!, ''); - _applyShape(); - } else { - // Reuse clipElement from prior surface. - _clipElement = oldSurface._clipElement; - if (_clipElement != null) { - rootElement!.append(_clipElement!); - } - oldSurface._clipElement = null; - _svgElement = oldSurface._svgElement; - if (_svgElement != null) { - rootElement!.insertBefore(_svgElement!, childContainer); - } - oldSurface._svgElement = null; - } - } -} - /// A surface that clips it's children. class PersistedClipPath extends PersistedContainerSurface implements ui.ClipPathEngineLayer { diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/html/scene_builder.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/html/scene_builder.dart index 40270dfaf6..e596165748 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/html/scene_builder.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/html/scene_builder.dart @@ -19,7 +19,6 @@ import 'color_filter.dart'; import 'image_filter.dart'; import 'offset.dart'; import 'opacity.dart'; -import 'path/path.dart'; import 'path_to_svg_clip.dart'; import 'picture.dart'; import 'platform_view.dart'; @@ -264,37 +263,6 @@ class SurfaceSceneBuilder implements ui.SceneBuilder { shader, maskRect, blendMode, filterQuality)); } - /// Pushes a physical layer operation for an arbitrary shape onto the - /// operation stack. - /// - /// By default, the layer's content will not be clipped (clip = [Clip.none]). - /// If clip equals [Clip.hardEdge], [Clip.antiAlias], or [Clip.antiAliasWithSaveLayer], - /// then the content is clipped to the given shape defined by [path]. - /// - /// If [elevation] is greater than 0.0, then a shadow is drawn around the layer. - /// [shadowColor] defines the color of the shadow if present and [color] defines the - /// color of the layer background. - /// - /// See [pop] for details about the operation stack, and [Clip] for different clip modes. - @override - ui.PhysicalShapeEngineLayer pushPhysicalShape({ - required ui.Path path, - required double elevation, - required ui.Color color, - ui.Color? shadowColor, - ui.Clip clipBehavior = ui.Clip.none, - ui.PhysicalShapeEngineLayer? oldLayer, - }) { - return _pushSurface(PersistedPhysicalShape( - oldLayer as PersistedPhysicalShape?, - path as SurfacePath, - elevation, - color.value, - shadowColor?.value ?? 0xFF000000, - clipBehavior, - )); - } - /// Add a retained engine layer subtree from previous frames. /// /// All the engine layers that are in the subtree of the retained layer will diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/shadow.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/shadow.dart index a4a79244ed..7096d18f25 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/shadow.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/shadow.dart @@ -11,13 +11,13 @@ import 'dom.dart'; /// How far is the light source from the surface of the UI. /// -/// Must be kept in sync with `flow/layers/physical_shape_layer.cc`. +/// Originally based on the constant in `flow/layers/physical_shape_layer.cc`. const double kLightHeight = 600.0; /// The radius of the light source. The positive radius creates a penumbra in /// the shadow, which we express using a blur effect. /// -/// Must be kept in sync with `flow/layers/physical_shape_layer.cc`. +/// Originally based on the constant in `flow/layers/physical_shape_layer.cc`. const double kLightRadius = 800.0; /// The X offset of the list source relative to the center of the shape. diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/scene_builder.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/scene_builder.dart index e2cc62508b..f1ce1e0ff1 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/scene_builder.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/scene_builder.dart @@ -164,20 +164,6 @@ class SkwasmSceneBuilder implements ui.SceneBuilder { OpacityLayer(), OpacityOperation(alpha, offset), ); - - @override - ui.PhysicalShapeEngineLayer pushPhysicalShape({ - required ui.Path path, - required double elevation, - required ui.Color color, - ui.Color? shadowColor, - ui.Clip clipBehavior = ui.Clip.none, - ui.PhysicalShapeEngineLayer? oldLayer - }) { - // TODO(jacksongardner): implement pushPhysicalShape - throw UnimplementedError(); - } - @override ui.ShaderMaskEngineLayer pushShaderMask( ui.Shader shader, diff --git a/engine/src/flutter/lib/web_ui/test/canvaskit/canvas_golden_test.dart b/engine/src/flutter/lib/web_ui/test/canvaskit/canvas_golden_test.dart index 74485512d4..d82401ede8 100644 --- a/engine/src/flutter/lib/web_ui/test/canvaskit/canvas_golden_test.dart +++ b/engine/src/flutter/lib/web_ui/test/canvaskit/canvas_golden_test.dart @@ -54,141 +54,6 @@ void testMain() { ); }); - // Regression test for https://github.com/flutter/flutter/issues/51237 - // Draws a grid of shadows at different offsets. Prior to directional - // light the shadows would shift depending on the offset. With directional - // light the cells in the grid must look identical. - test('uses directional shadows', () async { - const ui.Rect region = ui.Rect.fromLTRB(0, 0, 820, 420); - final CkPicture picture = paintPicture(region, (CkCanvas canvas) { - final CkPath shape = CkPath() - ..addRect(const ui.Rect.fromLTRB(0, 0, 40, 40)); - final CkPaint shapePaint = CkPaint() - ..style = ui.PaintingStyle.stroke - ..strokeWidth = 1 - ..color = const ui.Color(0xFF009900); - final CkPaint shadowBoundsPaint = CkPaint() - ..style = ui.PaintingStyle.stroke - ..strokeWidth = 1 - ..color = const ui.Color(0xFF000099); - canvas.translate(20, 20); - - for (int row = 0; row < 5; row += 1) { - canvas.save(); - for (int col = 0; col < 10; col += 1) { - final double elevation = 2 * (col % 5).toDouble(); - canvas.drawShadow(shape, const ui.Color(0xFFFF0000), elevation, true); - canvas.drawPath(shape, shapePaint); - - final PhysicalShapeEngineLayer psl = PhysicalShapeEngineLayer( - elevation, - const ui.Color(0xFF000000), - const ui.Color(0xFF000000), - shape, - ui.Clip.antiAlias, - ); - psl.preroll( - PrerollContext( - RasterCache(), - HtmlViewEmbedder.instance, - ), - Matrix4.identity(), - ); - canvas.drawRect(psl.paintBounds, shadowBoundsPaint); - - final CkParagraph p = makeSimpleText('$elevation'); - p.layout(const ui.ParagraphConstraints(width: 1000)); - canvas.drawParagraph( - p, ui.Offset(20 - p.maxIntrinsicWidth / 2, 20 - p.height / 2)); - canvas.translate(80, 0); - } - canvas.restore(); - canvas.translate(0, 80); - } - }); - await matchPictureGolden('canvaskit_directional_shadows.png', picture, - region: region); - }); - - test('computes shadow bounds correctly with parent transforms', () async { - const double rectSize = 50; - const double halfSize = rectSize / 2; - const double padding = 110; - const ui.Rect region = ui.Rect.fromLTRB( - 0, - 0, - (rectSize + padding) * 3 + padding, - (rectSize + padding) * 2 + padding, - ); - late List physicalShapeLayers; - - LayerTree buildTestScene({required bool paintShadowBounds}) { - final Iterator? shadowBounds = - paintShadowBounds ? physicalShapeLayers.iterator : null; - physicalShapeLayers = []; - - final LayerSceneBuilder builder = LayerSceneBuilder(); - builder.pushOffset(padding + halfSize, padding + halfSize); - - final CkPath shape = CkPath() - ..addRect( - const ui.Rect.fromLTRB(-halfSize, -halfSize, halfSize, halfSize)); - final CkPaint shadowBoundsPaint = CkPaint() - ..style = ui.PaintingStyle.stroke - ..strokeWidth = 1 - ..color = const ui.Color(0xFF000099); - - for (int row = 0; row < 2; row += 1) { - for (int col = 0; col < 3; col += 1) { - builder.pushOffset( - col * (rectSize + padding), row * (rectSize + padding)); - builder.pushTransform(Float64List.fromList( - Matrix4.rotationZ(row * math.pi / 4).storage)); - final double scale = 1 / (1 + col); - builder.pushTransform(Float64List.fromList( - Matrix4.diagonal3Values(scale, scale, 1).storage)); - physicalShapeLayers.add(builder.pushPhysicalShape( - path: shape, - elevation: 6, - color: const ui.Color(0xFF009900), - shadowColor: const ui.Color(0xFF000000), - )); - if (shadowBounds != null) { - shadowBounds.moveNext(); - final ui.Rect bounds = shadowBounds.current.paintBounds; - builder.addPicture( - ui.Offset.zero, - paintPicture(region, (CkCanvas canvas) { - canvas.drawRect(bounds, shadowBoundsPaint); - })); - } - builder.pop(); - builder.pop(); - builder.pop(); - builder.pop(); - } - } - builder.pop(); - return builder.build().layerTree; - } - - // Render the scene once without painting the shadow bounds just to - // preroll the scene to compute the shadow bounds. - buildTestScene(paintShadowBounds: false).rootLayer.preroll( - PrerollContext( - RasterCache(), - HtmlViewEmbedder.instance, - ), - Matrix4.identity(), - ); - - // Render again, this time with the shadow bounds. - final LayerTree layerTree = buildTestScene(paintShadowBounds: true); - - CanvasKitRenderer.instance.rasterizer.draw(layerTree); - await matchGoldenFile('canvaskit_shadow_bounds.png', region: region); - }); - test('text styles - default', () async { await testTextStyle('default'); }); diff --git a/engine/src/flutter/lib/web_ui/test/engine/surface/scene_builder_test.dart b/engine/src/flutter/lib/web_ui/test/engine/surface/scene_builder_test.dart index 11581017ed..375a5887a6 100644 --- a/engine/src/flutter/lib/web_ui/test/engine/surface/scene_builder_test.dart +++ b/engine/src/flutter/lib/web_ui/test/engine/surface/scene_builder_test.dart @@ -93,22 +93,6 @@ void testMain() { return ''''''; }); }); - - test('pushPhysicalShape implements surface lifecycle', () { - testLayerLifeCycle((ui.SceneBuilder sceneBuilder, ui.EngineLayer? oldLayer) { - final ui.Path path = ui.Path()..addRect(const ui.Rect.fromLTRB(10, 20, 30, 40)); - return sceneBuilder.pushPhysicalShape( - path: path, - elevation: 2, - color: const ui.Color.fromRGBO(0, 0, 0, 1), - shadowColor: const ui.Color.fromRGBO(0, 0, 0, 1), - oldLayer: oldLayer as ui.PhysicalShapeEngineLayer?, - ); - }, () { - return ''''''; - }); - }); - test('pushBackdropFilter implements surface lifecycle', () { testLayerLifeCycle((ui.SceneBuilder sceneBuilder, ui.EngineLayer? oldLayer) { return sceneBuilder.pushBackdropFilter( diff --git a/engine/src/flutter/lib/web_ui/test/engine/surface/surface_test.dart b/engine/src/flutter/lib/web_ui/test/engine/surface/surface_test.dart index 4b78dec4f7..ac807c8656 100644 --- a/engine/src/flutter/lib/web_ui/test/engine/surface/surface_test.dart +++ b/engine/src/flutter/lib/web_ui/test/engine/surface/surface_test.dart @@ -362,22 +362,6 @@ void testMain() { expect( opacityLayer2.rootElement, element); // adopts old surface's element }); - - // Regression test for https://github.com/flutter/flutter/issues/60461 - // - // During retained match many to many, build can be called on existing - // PersistedPhysicalShape multiple times when not matched. - test('Can call apply multiple times on existing PersistedPhysicalShape' - 'when using arbitrary path', - () { - final SceneBuilder builder1 = SceneBuilder(); - final Path path = Path(); - path.addPolygon(const [Offset(50, 0), Offset(100, 80), Offset(20, 40)], true); - final PersistedPhysicalShape shape = builder1.pushPhysicalShape(path: path, - color: const Color(0xFF00FF00), elevation: 1) as PersistedPhysicalShape; - builder1.build(); - expect(() => shape.apply(), returnsNormally); - }); }); final Map layerFactories = { @@ -406,11 +390,6 @@ void testMain() { ); return builder.pushShaderMask(shader, shaderBounds, BlendMode.srcOver); }, - 'PhysicalShapeEngineLayer': (SurfaceSceneBuilder builder) => builder.pushPhysicalShape( - path: Path()..addRect(const Rect.fromLTRB(0, 0, 10, 10)), - elevation: 3, - color: const Color(0xAABBCCDD), - ), }; // Regression test for https://github.com/flutter/flutter/issues/104305 diff --git a/engine/src/flutter/lib/web_ui/test/html/compositing/color_filter_golden_test.dart b/engine/src/flutter/lib/web_ui/test/html/compositing/color_filter_golden_test.dart index 3da07d2fc5..a522d59684 100644 --- a/engine/src/flutter/lib/web_ui/test/html/compositing/color_filter_golden_test.dart +++ b/engine/src/flutter/lib/web_ui/test/html/compositing/color_filter_golden_test.dart @@ -6,7 +6,7 @@ import 'dart:js_util' as js_util; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' hide PhysicalShapeEngineLayer; +import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart'; import 'package:web_engine_tester/golden_tester.dart'; @@ -83,35 +83,6 @@ Future testMain() async { domDocument.body!.append(builder.build().webOnlyRootElement!); await matchGoldenFile('color_filter_mode.png', region: region); }); - - /// Regression test for https://github.com/flutter/flutter/issues/59451. - /// - /// Picture with overlay blend inside a physical shape. Should show image - /// at 0,0. In the filed issue it was leaving a gap on top. - test('Should render image with color filter without gap', () async { - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - final Path path = Path(); - path.addRRect(RRect.fromRectAndRadius( - const Rect.fromLTRB(0, 0, 400, 400), const Radius.circular(2))); - final PhysicalShapeEngineLayer oldLayer = builder.pushPhysicalShape( - path: path, color: const Color(0xFFFFFFFF), elevation: 0); - final Picture circles1 = _drawTestPictureWithImage( - const ColorFilter.mode(Color(0x3C4043), BlendMode.overlay)); - builder.addPicture(const Offset(10, 0), circles1); - builder.pop(); - builder.build(); - - final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder(); - builder2.pushPhysicalShape( - path: path, color: const Color(0xFFFFFFFF), elevation: 0, oldLayer: oldLayer); - builder2.addPicture(const Offset(10, 0), circles1); - builder2.pop(); - - domDocument.body!.append(builder2.build().webOnlyRootElement!); - - await matchGoldenFile('color_filter_blendMode_overlay.png', - region: region); - }); } Picture _drawTestPictureWithCircles(double offsetX, double offsetY) { @@ -142,23 +113,6 @@ Picture _drawTestPictureWithCircles(double offsetX, double offsetY) { return recorder.endRecording(); } -Picture _drawTestPictureWithImage(ColorFilter filter) { - final EnginePictureRecorder recorder = - PictureRecorder() as EnginePictureRecorder; - final RecordingCanvas canvas = - recorder.beginRecording(const Rect.fromLTRB(0, 0, 400, 400)); - final Image testImage = createTestImage(); - canvas.drawImageRect( - testImage, - const Rect.fromLTWH(0, 0, 200, 150), - const Rect.fromLTWH(0, 0, 300, 300), - (Paint() - ..style = PaintingStyle.fill - ..colorFilter = filter - ..color = const Color.fromRGBO(0, 0, 255, 1)) as SurfacePaint); - return recorder.endRecording(); -} - Picture _drawBackground() { final EnginePictureRecorder recorder = PictureRecorder() as EnginePictureRecorder; diff --git a/engine/src/flutter/lib/web_ui/test/html/compositing/compositing_golden_test.dart b/engine/src/flutter/lib/web_ui/test/html/compositing/compositing_golden_test.dart index 451c468a22..bc86da523b 100644 --- a/engine/src/flutter/lib/web_ui/test/html/compositing/compositing_golden_test.dart +++ b/engine/src/flutter/lib/web_ui/test/html/compositing/compositing_golden_test.dart @@ -128,237 +128,6 @@ Future testMain() async { await matchGoldenFile('compositing_shifted_clip_rrect.png', region: region); }); - test('pushPhysicalShape', () async { - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - builder.pushPhysicalShape( - path: ui.Path()..addRect(const ui.Rect.fromLTRB(10, 10, 60, 60)), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color.fromRGBO(0, 0, 0, 0.3), - elevation: 0, - ); - _drawTestPicture(builder); - builder.pop(); - - builder.pushOffset(70, 0); - builder.pushPhysicalShape( - path: ui.Path() - ..addRRect(ui.RRect.fromLTRBR(10, 10, 60, 60, const ui.Radius.circular(5))), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color.fromRGBO(0, 0, 0, 0.3), - elevation: 0, - ); - _drawTestPicture(builder); - builder.pop(); - builder.pop(); - - domDocument.body!.append(builder.build().webOnlyRootElement!); - - await matchGoldenFile('compositing_shifted_physical_shape_clip.png', - region: region); - }); - - test('pushPhysicalShape clipOp.none', () async { - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - builder.pushPhysicalShape( - path: ui.Path()..addRect(const ui.Rect.fromLTRB(10, 10, 60, 60)), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color.fromRGBO(0, 0, 0, 0.3), - elevation: 0, - ); - _drawTestPicture(builder); - builder.pop(); - - builder.pushOffset(70, 0); - builder.pushPhysicalShape( - path: ui.Path() - ..addRRect(ui.RRect.fromLTRBR(10, 10, 60, 60, const ui.Radius.circular(5))), - color: const ui.Color.fromRGBO(0, 0, 0, 0.3), - elevation: 0, - ); - _drawTestPicture(builder); - builder.pop(); - builder.pop(); - - domDocument.body!.append(builder.build().webOnlyRootElement!); - - await matchGoldenFile('compositing_shifted_physical_shape_clipnone.png', - region: region); - }); - - test('pushPhysicalShape with path and elevation', () async { - final ui.Path cutCornersButton = ui.Path() - ..moveTo(15, 10) - ..lineTo(60, 10) - ..lineTo(60, 60) - ..lineTo(15, 60) - ..lineTo(10, 55) - ..lineTo(10, 15); - - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - builder.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFFA0FFFF), - elevation: 2, - ); - _drawTestPicture(builder); - builder.pop(); - - builder.pushOffset(70, 0); - builder.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFFA0FFFF), - elevation: 8, - ); - _drawTestPicture(builder); - builder.pop(); - builder.pop(); - - builder.pushOffset(140, 0); - builder.pushPhysicalShape( - path: ui.Path()..addOval(const ui.Rect.fromLTRB(10, 10, 60, 60)), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFFA0FFFF), - elevation: 4, - ); - _drawTestPicture(builder); - builder.pop(); - builder.pop(); - - builder.pushOffset(210, 0); - builder.pushPhysicalShape( - path: ui.Path() - ..addRRect(ui.RRect.fromRectAndRadius( - const ui.Rect.fromLTRB(10, 10, 60, 60), const ui.Radius.circular(10.0))), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFFA0FFFF), - elevation: 4, - ); - _drawTestPicture(builder); - builder.pop(); - builder.pop(); - - domDocument.body!.append(builder.build().webOnlyRootElement!); - - await matchGoldenFile('compositing_physical_shape_path.png', - region: region); - }); - - test('pushPhysicalShape should update across frames', () async { - final ui.Path cutCornersButton = ui.Path() - ..moveTo(15, 10) - ..lineTo(60, 10) - ..lineTo(60, 60) - ..lineTo(15, 60) - ..lineTo(10, 55) - ..lineTo(10, 15); - - /// Start with shape that has elevation and red color. - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - final ui.PhysicalShapeEngineLayer oldShapeLayer = builder.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFFFF0000), - elevation: 2, - ); - _drawTestPicture(builder); - builder.pop(); - - final DomElement viewElement = builder.build().webOnlyRootElement!; - domDocument.body!.append(viewElement); - await matchGoldenFile('compositing_physical_update_1.png', region: region); - viewElement.remove(); - - /// Update color to green. - final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder(); - final ui.PhysicalShapeEngineLayer oldShapeLayer2 = builder2.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFF00FF00), - elevation: 2, - oldLayer: oldShapeLayer, - ); - _drawTestPicture(builder2); - builder2.pop(); - - final DomElement viewElement2 = builder2.build().webOnlyRootElement!; - domDocument.body!.append(viewElement2); - await matchGoldenFile('compositing_physical_update_2.png', region: region); - viewElement2.remove(); - - /// Update elevation. - final SurfaceSceneBuilder builder3 = SurfaceSceneBuilder(); - final ui.PhysicalShapeEngineLayer oldShapeLayer3 = builder3.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFF00FF00), - elevation: 6, - oldLayer: oldShapeLayer2, - ); - _drawTestPicture(builder3); - builder3.pop(); - - final DomElement viewElement3 = builder3.build().webOnlyRootElement!; - domDocument.body!.append(viewElement3); - await matchGoldenFile('compositing_physical_update_3.png', - region: region); - viewElement3.remove(); - - /// Update shape from arbitrary path to rect. - final SurfaceSceneBuilder builder4 = SurfaceSceneBuilder(); - final ui.PhysicalShapeEngineLayer oldShapeLayer4 = builder4.pushPhysicalShape( - path: ui.Path()..addOval(const ui.Rect.fromLTRB(10, 10, 60, 60)), - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFF00FF00), - elevation: 6, - oldLayer: oldShapeLayer3, - ); - _drawTestPicture(builder4); - builder4.pop(); - - final DomElement viewElement4 = builder4.build().webOnlyRootElement!; - domDocument.body!.append(viewElement4); - await matchGoldenFile('compositing_physical_update_4.png', region: region); - viewElement4.remove(); - - /// Update shape back to arbitrary path. - final SurfaceSceneBuilder builder5 = SurfaceSceneBuilder(); - final ui.PhysicalShapeEngineLayer oldShapeLayer5 = builder5.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFF00FF00), - elevation: 6, - oldLayer: oldShapeLayer4, - ); - _drawTestPicture(builder5); - builder5.pop(); - - final DomElement viewElement5 = builder5.build().webOnlyRootElement!; - domDocument.body!.append(viewElement5); - await matchGoldenFile('compositing_physical_update_3.png', - region: region); - viewElement5.remove(); - - /// Update shadow color. - final SurfaceSceneBuilder builder6 = SurfaceSceneBuilder(); - builder6.pushPhysicalShape( - path: cutCornersButton, - clipBehavior: ui.Clip.hardEdge, - color: const ui.Color(0xFF00FF00), - shadowColor: const ui.Color(0xFFFF0000), - elevation: 6, - oldLayer: oldShapeLayer5, - ); - _drawTestPicture(builder6); - builder6.pop(); - - final DomElement viewElement6 = builder6.build().webOnlyRootElement!; - domDocument.body!.append(viewElement6); - await matchGoldenFile('compositing_physical_update_5.png', region: region); - viewElement6.remove(); - }); - test('pushImageFilter blur', () async { final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); builder.pushImageFilter( diff --git a/engine/src/flutter/lib/web_ui/test/html/shadow_golden_test.dart b/engine/src/flutter/lib/web_ui/test/html/shadow_golden_test.dart index 4ca020c030..7d9e1e0430 100644 --- a/engine/src/flutter/lib/web_ui/test/html/shadow_golden_test.dart +++ b/engine/src/flutter/lib/web_ui/test/html/shadow_golden_test.dart @@ -56,22 +56,6 @@ Future testMain() async { builder.addPicture(Offset.zero, recorder.endRecording()); } - void paintPhysicalShapeShadow(double elevation, Offset offset) { - final SurfacePath path = SurfacePath() - ..addRect(const Rect.fromLTRB(0, 0, 20, 20)); - builder.pushOffset(offset.dx, offset.dy); - builder.pushPhysicalShape( - path: path, - elevation: elevation, - shadowColor: _kShadowColor, - color: const Color.fromARGB(255, 255, 255, 255), - ); - builder.pop(); // physical shape - paintShapeOutline(); - paintShadowBounds(path, elevation); - builder.pop(); // offset - } - void paintBitmapCanvasShadow( double elevation, Offset offset, bool transparentOccluder) { final SurfacePath path = SurfacePath() @@ -135,10 +119,6 @@ Future testMain() async { builder.pushOffset(10, 20); - for (int i = 0; i < 10; i++) { - paintPhysicalShapeShadow(i.toDouble(), Offset(50.0 * i, 0)); - } - for (int i = 0; i < 10; i++) { paintBitmapCanvasShadow(i.toDouble(), Offset(50.0 * i, 60), false); } diff --git a/engine/src/flutter/shell/common/persistent_cache_unittests.cc b/engine/src/flutter/shell/common/persistent_cache_unittests.cc index c1d27bfa77..d58b929994 100644 --- a/engine/src/flutter/shell/common/persistent_cache_unittests.cc +++ b/engine/src/flutter/shell/common/persistent_cache_unittests.cc @@ -9,7 +9,6 @@ #include "flutter/assets/directory_asset_bundle.h" #include "flutter/flow/layers/container_layer.h" #include "flutter/flow/layers/layer.h" -#include "flutter/flow/layers/physical_shape_layer.h" #include "flutter/fml/command_line.h" #include "flutter/fml/file.h" #include "flutter/fml/log_settings.h" @@ -25,167 +24,6 @@ namespace testing { using PersistentCacheTest = ShellTest; -static void WaitForIO(Shell* shell) { - std::promise io_task_finished; - shell->GetTaskRunners().GetIOTaskRunner()->PostTask( - [&io_task_finished]() { io_task_finished.set_value(true); }); - io_task_finished.get_future().wait(); -} - -static void WaitForRaster(Shell* shell) { - std::promise raster_task_finished; - shell->GetTaskRunners().GetRasterTaskRunner()->PostTask( - [&raster_task_finished]() { raster_task_finished.set_value(true); }); - raster_task_finished.get_future().wait(); -} - -TEST_F(PersistentCacheTest, CacheSkSLWorks) { - // Create a temp dir to store the persistent cache - fml::ScopedTemporaryDirectory dir; - PersistentCache::SetCacheDirectoryPath(dir.path()); - PersistentCache::ResetCacheForProcess(); - - auto settings = CreateSettingsForFixture(); - settings.cache_sksl = true; - settings.dump_skp_on_shader_compilation = true; - - fml::AutoResetWaitableEvent first_frame_latch; - settings.frame_rasterized_callback = - [&first_frame_latch](const FrameTiming& t) { - first_frame_latch.Signal(); - }; - - auto sksl_config = RunConfiguration::InferFromSettings(settings); - sksl_config.SetEntrypoint("emptyMain"); - std::unique_ptr shell = CreateShell(settings); - PlatformViewNotifyCreated(shell.get()); - RunEngine(shell.get(), std::move(sksl_config)); - - // Initially, we should have no SkSL cache - auto cache = PersistentCache::GetCacheForProcess()->LoadSkSLs(); - ASSERT_EQ(cache.size(), 0u); - - // Draw something to trigger shader compilations. - LayerTreeBuilder builder = [](const std::shared_ptr& root) { - SkPath path; - path.addCircle(50, 50, 20); - auto physical_shape_layer = std::make_shared( - SK_ColorRED, SK_ColorBLUE, 1.0f, path, Clip::antiAlias); - root->Add(physical_shape_layer); - }; - PumpOneFrame(shell.get(), 100, 100, builder); - first_frame_latch.Wait(); - WaitForIO(shell.get()); - - // Some skp should be dumped due to shader compilations. - int skp_count = 0; - fml::FileVisitor skp_visitor = [&skp_count](const fml::UniqueFD& directory, - const std::string& filename) { - if (filename.size() >= 4 && - filename.substr(filename.size() - 4, 4) == ".skp") { - skp_count += 1; - } - return true; - }; - fml::VisitFilesRecursively(dir.fd(), skp_visitor); - ASSERT_GT(skp_count, 0); - - // SkSL cache should be generated by the last run. - cache = PersistentCache::GetCacheForProcess()->LoadSkSLs(); - ASSERT_GT(cache.size(), 0u); - - // Run the engine again with cache_sksl = false and check that the previously - // generated SkSL cache is used for precompile. - PersistentCache::ResetCacheForProcess(); - settings.cache_sksl = false; - settings.dump_skp_on_shader_compilation = true; - auto normal_config = RunConfiguration::InferFromSettings(settings); - normal_config.SetEntrypoint("emptyMain"); - DestroyShell(std::move(shell)); - shell = CreateShell(settings); - PlatformViewNotifyCreated(shell.get()); - RunEngine(shell.get(), std::move(normal_config)); - first_frame_latch.Reset(); - PumpOneFrame(shell.get(), 100, 100, builder); - first_frame_latch.Wait(); - WaitForIO(shell.get()); - -// Shader precompilation from SkSL is not implemented on the Skia Vulkan -// backend so don't run the second half of this test on Vulkan. This can get -// removed if SkSL precompilation is implemented in the Skia Vulkan backend. -#if !defined(SHELL_ENABLE_VULKAN) - // To check that all shaders are precompiled, verify that no new skp is dumped - // due to shader compilations. - int old_skp_count = skp_count; - skp_count = 0; - fml::VisitFilesRecursively(dir.fd(), skp_visitor); - ASSERT_EQ(skp_count, old_skp_count); -#endif // !defined(SHELL_ENABLE_VULKAN) - - // Remove all files generated - fml::RemoveFilesInDirectory(dir.fd()); - DestroyShell(std::move(shell)); -} - -TEST_F(PersistentCacheTest, CanPrecompileMetalShaders) { -#if !SHELL_ENABLE_METAL - GTEST_SKIP(); -#endif // !SHELL_ENABLE_METAL - fml::ScopedTemporaryDirectory dir; - PersistentCache::SetCacheDirectoryPath(dir.path()); - PersistentCache::ResetCacheForProcess(); - - auto settings = CreateSettingsForFixture(); - settings.cache_sksl = true; - settings.dump_skp_on_shader_compilation = true; - - fml::AutoResetWaitableEvent first_frame_latch; - settings.frame_rasterized_callback = - [&first_frame_latch](const FrameTiming& t) { - first_frame_latch.Signal(); - }; - - auto sksl_config = RunConfiguration::InferFromSettings(settings); - sksl_config.SetEntrypoint("emptyMain"); - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kMetalBackend // - ); - PlatformViewNotifyCreated(shell.get()); - RunEngine(shell.get(), std::move(sksl_config)); - - // Initially, we should have no SkSL cache - { - auto empty_cache = PersistentCache::GetCacheForProcess()->LoadSkSLs(); - ASSERT_EQ(empty_cache.size(), 0u); - } - - // Draw something to trigger shader compilations. - LayerTreeBuilder builder = [](const std::shared_ptr& root) { - SkPath path; - path.addCircle(50, 50, 20); - auto physical_shape_layer = std::make_shared( - SK_ColorRED, SK_ColorBLUE, 1.0f, path, Clip::antiAlias); - root->Add(physical_shape_layer); - }; - PumpOneFrame(shell.get(), 100, 100, builder); - first_frame_latch.Wait(); - WaitForRaster(shell.get()); - WaitForIO(shell.get()); - - // Assert that SkSLs have been generated. - auto filled_cache = PersistentCache::GetCacheForProcess()->LoadSkSLs(); - ASSERT_GT(filled_cache.size(), 0u); - - // Remove all files generated. - fml::RemoveFilesInDirectory(dir.fd()); - DestroyShell(std::move(shell)); -} - static void CheckTextSkData(const sk_sp& data, const std::string& expected) { std::string data_string(reinterpret_cast(data->bytes()), diff --git a/engine/src/flutter/shell/common/shell_unittests.cc b/engine/src/flutter/shell/common/shell_unittests.cc index d85750e70d..60c119ac96 100644 --- a/engine/src/flutter/shell/common/shell_unittests.cc +++ b/engine/src/flutter/shell/common/shell_unittests.cc @@ -2418,7 +2418,6 @@ TEST_F(ShellTest, OnServiceProtocolEstimateRasterCacheMemoryWorks) { .ui_time = ui_time, .texture_registry = nullptr, .raster_cache = &raster_cache, - .frame_device_pixel_ratio = 1.0f, // clang-format on }; @@ -2433,7 +2432,6 @@ TEST_F(ShellTest, OnServiceProtocolEstimateRasterCacheMemoryWorks) { .raster_time = raster_time, .ui_time = ui_time, .texture_registry = nullptr, - .frame_device_pixel_ratio = 1.0f, .has_platform_view = false, .has_texture_layer = false, .raster_cached_entries = &raster_cache_items, diff --git a/engine/src/flutter/testing/dart/compositing_test.dart b/engine/src/flutter/testing/dart/compositing_test.dart index c5113d14cf..a2f95cdba0 100644 --- a/engine/src/flutter/testing/dart/compositing_test.dart +++ b/engine/src/flutter/testing/dart/compositing_test.dart @@ -402,10 +402,6 @@ void main() { oldLayer: oldLayer as ShaderMaskEngineLayer?, ); }); - testNoSharing((SceneBuilder builder, EngineLayer? oldLayer) { - // ignore: deprecated_member_use - return builder.pushPhysicalShape(path: Path(), color: const Color.fromARGB(0, 0, 0, 0), oldLayer: oldLayer as PhysicalShapeEngineLayer?, elevation: 0.0); - }); testNoSharing((SceneBuilder builder, EngineLayer? oldLayer) { return builder.pushColorFilter( const ColorFilter.mode(