diff --git a/BUILD.gn b/BUILD.gn index 419ae849544a1..361a5c6f0e2f6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -95,10 +95,7 @@ group("flutter") { # Fuchsia currently only supports a subset of our unit tests if (is_fuchsia) { - public_deps += [ - "$flutter_root/flow:flow_tests", - "$flutter_root/fml:fml_tests", - ] + public_deps += [ "$flutter_root/fml:fml_tests" ] } } diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index f57b00086d432..c296ebe416fbd 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -30,33 +30,24 @@ FILE: ../../../flutter/flow/instrumentation.cc FILE: ../../../flutter/flow/instrumentation.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h -FILE: ../../../flutter/flow/layers/backdrop_filter_layer_unittests.cc FILE: ../../../flutter/flow/layers/child_scene_layer.cc FILE: ../../../flutter/flow/layers/child_scene_layer.h FILE: ../../../flutter/flow/layers/clip_path_layer.cc FILE: ../../../flutter/flow/layers/clip_path_layer.h -FILE: ../../../flutter/flow/layers/clip_path_layer_unittests.cc FILE: ../../../flutter/flow/layers/clip_rect_layer.cc FILE: ../../../flutter/flow/layers/clip_rect_layer.h -FILE: ../../../flutter/flow/layers/clip_rect_layer_unittests.cc FILE: ../../../flutter/flow/layers/clip_rrect_layer.cc FILE: ../../../flutter/flow/layers/clip_rrect_layer.h -FILE: ../../../flutter/flow/layers/clip_rrect_layer_unittests.cc FILE: ../../../flutter/flow/layers/color_filter_layer.cc FILE: ../../../flutter/flow/layers/color_filter_layer.h -FILE: ../../../flutter/flow/layers/color_filter_layer_unittests.cc FILE: ../../../flutter/flow/layers/container_layer.cc FILE: ../../../flutter/flow/layers/container_layer.h -FILE: ../../../flutter/flow/layers/container_layer_unittests.cc FILE: ../../../flutter/flow/layers/layer.cc FILE: ../../../flutter/flow/layers/layer.h FILE: ../../../flutter/flow/layers/layer_tree.cc FILE: ../../../flutter/flow/layers/layer_tree.h -FILE: ../../../flutter/flow/layers/layer_tree_unittests.cc -FILE: ../../../flutter/flow/layers/layer_unittests.cc FILE: ../../../flutter/flow/layers/opacity_layer.cc FILE: ../../../flutter/flow/layers/opacity_layer.h -FILE: ../../../flutter/flow/layers/opacity_layer_unittests.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.h FILE: ../../../flutter/flow/layers/performance_overlay_layer_unittests.cc @@ -65,19 +56,14 @@ FILE: ../../../flutter/flow/layers/physical_shape_layer.h FILE: ../../../flutter/flow/layers/physical_shape_layer_unittests.cc FILE: ../../../flutter/flow/layers/picture_layer.cc FILE: ../../../flutter/flow/layers/picture_layer.h -FILE: ../../../flutter/flow/layers/picture_layer_unittests.cc FILE: ../../../flutter/flow/layers/platform_view_layer.cc FILE: ../../../flutter/flow/layers/platform_view_layer.h -FILE: ../../../flutter/flow/layers/platform_view_layer_unittests.cc FILE: ../../../flutter/flow/layers/shader_mask_layer.cc FILE: ../../../flutter/flow/layers/shader_mask_layer.h -FILE: ../../../flutter/flow/layers/shader_mask_layer_unittests.cc FILE: ../../../flutter/flow/layers/texture_layer.cc FILE: ../../../flutter/flow/layers/texture_layer.h -FILE: ../../../flutter/flow/layers/texture_layer_unittests.cc FILE: ../../../flutter/flow/layers/transform_layer.cc FILE: ../../../flutter/flow/layers/transform_layer.h -FILE: ../../../flutter/flow/layers/transform_layer_unittests.cc FILE: ../../../flutter/flow/matrix_decomposition.cc FILE: ../../../flutter/flow/matrix_decomposition.h FILE: ../../../flutter/flow/matrix_decomposition_unittests.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 50981bb316e16..c2f0c98415a3e 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,8 +4,8 @@ if (is_fuchsia) { import("//build/fuchsia/sdk.gni") - import("$flutter_root/tools/fuchsia/fuchsia_archive.gni") } + import("$flutter_root/testing/testing.gni") source_set("flow") { @@ -102,26 +102,6 @@ test_fixtures("flow_fixtures") { fixtures = [] } -source_set("flow_testing") { - testonly = true - - sources = [ - "testing/layer_test.h", - "testing/mock_layer.cc", - "testing/mock_layer.h", - "testing/mock_texture.cc", - "testing/mock_texture.h", - "testing/skia_gpu_object_layer_test.cc", - "testing/skia_gpu_object_layer_test.h", - ] - - public_deps = [ - ":flow", - "$flutter_root/testing:skia", - "//third_party/googletest:gtest", - ] -} - executable("flow_unittests") { testonly = true @@ -129,75 +109,22 @@ executable("flow_unittests") { "flow_run_all_unittests.cc", "flow_test_utils.cc", "flow_test_utils.h", - "layers/backdrop_filter_layer_unittests.cc", - "layers/clip_path_layer_unittests.cc", - "layers/clip_rect_layer_unittests.cc", - "layers/clip_rrect_layer_unittests.cc", - "layers/color_filter_layer_unittests.cc", - "layers/container_layer_unittests.cc", - "layers/layer_tree_unittests.cc", - "layers/layer_unittests.cc", - "layers/opacity_layer_unittests.cc", "layers/performance_overlay_layer_unittests.cc", "layers/physical_shape_layer_unittests.cc", - "layers/picture_layer_unittests.cc", - "layers/platform_view_layer_unittests.cc", - "layers/shader_mask_layer_unittests.cc", - "layers/texture_layer_unittests.cc", - "layers/transform_layer_unittests.cc", "matrix_decomposition_unittests.cc", "mutators_stack_unittests.cc", "raster_cache_unittests.cc", "skia_gpu_object_unittests.cc", - "testing/mock_layer_unittests.cc", - "testing/mock_texture_unittests.cc", "texture_unittests.cc", ] deps = [ ":flow", ":flow_fixtures", - ":flow_testing", "$flutter_root/fml", - "$flutter_root/testing:skia", "$flutter_root/testing:testing_lib", "//third_party/dart/runtime:libdart_jit", # for tracing "//third_party/googletest:gtest", "//third_party/skia", ] } - -if (is_fuchsia) { - fuchsia_archive("flow_tests") { - testonly = true - - deps = [ - ":flow_unittests", - ] - - binary = "flow_unittests" - - libraries = common_libs - - meta_dir = "$flutter_root/testing/fuchsia/meta" - cmx_file = "$meta_dir/fuchsia_test.cmx" - - resources = [ - { - path = rebase_path( - "$flutter_root/testing/resources/performance_overlay_gold_60fps.png") - dest = "flutter/testing/resources/performance_overlay_gold_60fps.png" - }, - { - path = rebase_path( - "$flutter_root/testing/resources/performance_overlay_gold_90fps.png") - dest = "flutter/testing/resources/performance_overlay_gold_90fps.png" - }, - { - path = rebase_path( - "$flutter_root/testing/resources/performance_overlay_gold_120fps.png") - dest = "flutter/testing/resources/performance_overlay_gold_120fps.png" - }, - ] - } -} diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 030eb88c8a06d..919ee83a8bb86 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -143,7 +143,6 @@ class MutatorsStack { // Returns an iterator pointing to the bottom of the stack. const std::vector>::const_reverse_iterator Bottom() const; - bool is_empty() const { return vector_.empty(); } bool operator==(const MutatorsStack& other) const { if (vector_.size() != other.vector_.size()) { @@ -157,26 +156,10 @@ class MutatorsStack { return true; } - bool operator==(const std::vector& other) const { - if (vector_.size() != other.size()) { - return false; - } - for (size_t i = 0; i < vector_.size(); i++) { - if (*vector_[i] != other[i]) { - return false; - } - } - return true; - } - bool operator!=(const MutatorsStack& other) const { return !operator==(other); } - bool operator!=(const std::vector& other) const { - return !operator==(other); - } - private: std::vector> vector_; }; // MutatorsStack diff --git a/flow/flow_run_all_unittests.cc b/flow/flow_run_all_unittests.cc index 39963730172ee..4cf0ba3d7fcdf 100644 --- a/flow/flow_run_all_unittests.cc +++ b/flow/flow_run_all_unittests.cc @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "flutter/fml/build_config.h" #include "flutter/fml/command_line.h" #include "flutter/fml/logging.h" #include "gtest/gtest.h" @@ -24,14 +23,8 @@ int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); fml::CommandLine cmd = fml::CommandLineFromArgcArgv(argc, argv); - -#if defined(OS_FUCHSIA) - flutter::SetGoldenDir(cmd.GetOptionValueWithDefault( - "golden-dir", "/pkg/data/flutter/testing/resources")); -#else flutter::SetGoldenDir( cmd.GetOptionValueWithDefault("golden-dir", "flutter/testing/resources")); -#endif flutter::SetFontFile(cmd.GetOptionValueWithDefault( "font-file", "flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf")); diff --git a/flow/layers/backdrop_filter_layer.cc b/flow/layers/backdrop_filter_layer.cc index c69b7fcb3d8d1..573db97f191a2 100644 --- a/flow/layers/backdrop_filter_layer.cc +++ b/flow/layers/backdrop_filter_layer.cc @@ -7,9 +7,9 @@ namespace flutter { BackdropFilterLayer::BackdropFilterLayer(sk_sp filter) - : filter_(std::move(filter)) { - set_layer_reads_surface(filter_.get() != nullptr); -} + : filter_(std::move(filter)) {} + +BackdropFilterLayer::~BackdropFilterLayer() = default; void BackdropFilterLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "BackdropFilterLayer::Paint"); diff --git a/flow/layers/backdrop_filter_layer.h b/flow/layers/backdrop_filter_layer.h index 732a1ac27e89a..ede9ceeef41f8 100644 --- a/flow/layers/backdrop_filter_layer.h +++ b/flow/layers/backdrop_filter_layer.h @@ -14,6 +14,7 @@ namespace flutter { class BackdropFilterLayer : public ContainerLayer { public: BackdropFilterLayer(sk_sp filter); + ~BackdropFilterLayer() override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/backdrop_filter_layer_unittests.cc b/flow/layers/backdrop_filter_layer_unittests.cc deleted file mode 100644 index b0582300da91f..0000000000000 --- a/flow/layers/backdrop_filter_layer_unittests.cc +++ /dev/null @@ -1,184 +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/backdrop_filter_layer.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/SkImageFilter.h" -#include "third_party/skia/include/effects/SkImageFilters.h" - -namespace flutter { -namespace testing { - -using BackdropFilterLayerTest = LayerTest; - -TEST_F(BackdropFilterLayerTest, EmptyLayer) { - auto layer = std::make_shared(sk_sp()); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(BackdropFilterLayerTest, PaintBeforePreroll) { - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(sk_sp()); - layer->Add(mock_layer); - - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(BackdropFilterLayerTest, EmptyFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(nullptr); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, SkPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(BackdropFilterLayerTest, SimpleFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto layer_filter = SkImageFilters::Paint(SkPaint(SkColors::kMagenta)); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_filter); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, SkPaint(), - layer_filter, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(BackdropFilterLayerTest, MultipleChildren) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter = SkImageFilters::Paint(SkPaint(SkColors::kMagenta)); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(layer_filter); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), children_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), - layer_filter, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(BackdropFilterLayerTest, Nested) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter1 = SkImageFilters::Paint(SkPaint(SkColors::kMagenta)); - auto layer_filter2 = SkImageFilters::Paint(SkPaint(SkColors::kDkGray)); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer1 = std::make_shared(layer_filter1); - auto layer2 = std::make_shared(layer_filter2); - layer2->Add(mock_layer2); - layer1->Add(mock_layer1); - layer1->Add(layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer1->paint_bounds(), children_bounds); - EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - layer1->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), - layer_filter1, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{child_path2.getBounds(), - SkPaint(), layer_filter2, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index acc6f17dd5433..d08c19b34eeb9 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -15,9 +15,10 @@ namespace flutter { ClipPathLayer::ClipPathLayer(const SkPath& clip_path, Clip clip_behavior) : clip_path_(clip_path), clip_behavior_(clip_behavior) { FML_DCHECK(clip_behavior != Clip::none); - set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer); } +ClipPathLayer::~ClipPathLayer() = default; + void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkRect previous_cull_rect = context->cull_rect; SkRect clip_path_bounds = clip_path_.getBounds(); diff --git a/flow/layers/clip_path_layer.h b/flow/layers/clip_path_layer.h index c21e53c34e76e..fd4d56f0db7f0 100644 --- a/flow/layers/clip_path_layer.h +++ b/flow/layers/clip_path_layer.h @@ -12,6 +12,7 @@ namespace flutter { class ClipPathLayer : public ContainerLayer { public: ClipPathLayer(const SkPath& clip_path, Clip clip_behavior = Clip::antiAlias); + ~ClipPathLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; diff --git a/flow/layers/clip_path_layer_unittests.cc b/flow/layers/clip_path_layer_unittests.cc deleted file mode 100644 index 68b5fe9b48bad..0000000000000 --- a/flow/layers/clip_path_layer_unittests.cc +++ /dev/null @@ -1,194 +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/clip_path_layer.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" - -namespace flutter { -namespace testing { - -using ClipPathLayerTest = LayerTest; - -TEST_F(ClipPathLayerTest, ClipNone) { - EXPECT_DEATH_IF_SUPPORTED( - auto clip = std::make_shared(SkPath(), Clip::none), - "clip_behavior != Clip::none"); -} - -TEST_F(ClipPathLayerTest, EmptyLayer) { - auto layer = std::make_shared(SkPath(), Clip::hardEdge); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipPathLayerTest, PaintBeforePreroll) { - 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(layer_path, Clip::hardEdge); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipPathLayerTest, CulledLayer) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPath layer_path = SkPath().addRect(layer_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(layer_path, Clip::hardEdge); - layer->Add(mock_layer); - - preroll_context()->cull_rect = kEmptyRect; // Cull everything - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(mock_layer->needs_painting()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect); - EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix()); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipPathLayerTest, ChildOutsideBounds) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPath layer_path = SkPath().addRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_path, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipPathLayerTest, FullyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPath layer_path = SkPath().addRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_path, Clip::hardEdge); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipPathLayerTest, PartiallyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 4.0, 5.5); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPath layer_path = SkPath().addRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_path, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index 141ad8a009694..de7590624e408 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -9,9 +9,10 @@ namespace flutter { ClipRectLayer::ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior) : clip_rect_(clip_rect), clip_behavior_(clip_behavior) { FML_DCHECK(clip_behavior != Clip::none); - set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer); } +ClipRectLayer::~ClipRectLayer() = default; + void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkRect previous_cull_rect = context->cull_rect; if (context->cull_rect.intersect(clip_rect_)) { diff --git a/flow/layers/clip_rect_layer.h b/flow/layers/clip_rect_layer.h index 50eef22a46e2f..76c5a3f01c873 100644 --- a/flow/layers/clip_rect_layer.h +++ b/flow/layers/clip_rect_layer.h @@ -12,6 +12,7 @@ namespace flutter { class ClipRectLayer : public ContainerLayer { public: ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior); + ~ClipRectLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/clip_rect_layer_unittests.cc b/flow/layers/clip_rect_layer_unittests.cc deleted file mode 100644 index c5ee39f2e02e8..0000000000000 --- a/flow/layers/clip_rect_layer_unittests.cc +++ /dev/null @@ -1,192 +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/clip_rect_layer.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" - -namespace flutter { -namespace testing { - -using ClipRectLayerTest = LayerTest; - -TEST_F(ClipRectLayerTest, ClipNone) { - EXPECT_DEATH_IF_SUPPORTED( - auto clip = std::make_shared(kEmptyRect, Clip::none), - "clip_behavior != Clip::none"); -} - -TEST_F(ClipRectLayerTest, EmptyLayer) { - auto layer = std::make_shared(kEmptyRect, Clip::hardEdge); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRectLayerTest, PaintBeforePreroll) { - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - auto layer = std::make_shared(layer_bounds, Clip::hardEdge); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRectLayerTest, CulledLayer) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(layer_bounds, Clip::hardEdge); - layer->Add(mock_layer); - - preroll_context()->cull_rect = kEmptyRect; // Cull everything - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(mock_layer->needs_painting()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect); - EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix()); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRectLayerTest, ChildOutsideBounds) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_bounds, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_bounds)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipRectLayerTest, FullyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_bounds, Clip::hardEdge); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_bounds)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipRectLayerTest, PartiallyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 4.0, 5.5); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_bounds, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_bounds)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index dd4fdd09f03d4..9899a1658732d 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -9,9 +9,10 @@ namespace flutter { ClipRRectLayer::ClipRRectLayer(const SkRRect& clip_rrect, Clip clip_behavior) : clip_rrect_(clip_rrect), clip_behavior_(clip_behavior) { FML_DCHECK(clip_behavior != Clip::none); - set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer); } +ClipRRectLayer::~ClipRRectLayer() = default; + void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkRect previous_cull_rect = context->cull_rect; SkRect clip_rrect_bounds = clip_rrect_.getBounds(); diff --git a/flow/layers/clip_rrect_layer.h b/flow/layers/clip_rrect_layer.h index ce1cca2b568de..53f74f30a0776 100644 --- a/flow/layers/clip_rrect_layer.h +++ b/flow/layers/clip_rrect_layer.h @@ -12,6 +12,7 @@ namespace flutter { class ClipRRectLayer : public ContainerLayer { public: ClipRRectLayer(const SkRRect& clip_rrect, Clip clip_behavior); + ~ClipRRectLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; diff --git a/flow/layers/clip_rrect_layer_unittests.cc b/flow/layers/clip_rrect_layer_unittests.cc deleted file mode 100644 index 4eb506eec5ecc..0000000000000 --- a/flow/layers/clip_rrect_layer_unittests.cc +++ /dev/null @@ -1,197 +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/clip_rrect_layer.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" - -namespace flutter { -namespace testing { - -using ClipRRectLayerTest = LayerTest; - -TEST_F(ClipRRectLayerTest, ClipNone) { - const SkRRect layer_rrect = SkRRect::MakeEmpty(); - EXPECT_DEATH_IF_SUPPORTED( - auto clip = std::make_shared(layer_rrect, Clip::none), - "clip_behavior != Clip::none"); -} - -TEST_F(ClipRRectLayerTest, EmptyLayer) { - const SkRRect layer_rrect = SkRRect::MakeEmpty(); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRRectLayerTest, PaintBeforePreroll) { - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRRectLayerTest, CulledLayer) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - layer->Add(mock_layer); - - preroll_context()->cull_rect = kEmptyRect; // Cull everything - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(mock_layer->needs_painting()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect); - EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix()); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ClipRRectLayerTest, ChildOutsideBounds) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipRRectLayerTest, FullyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ClipRRectLayerTest, PartiallyContainedChild) { - const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 4.0, 5.5); - const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); - const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - layer->Add(mock_layer); - - SkRect intersect_bounds = layer_bounds; - SkRect child_intersect_bounds = layer_bounds; - intersect_bounds.intersect(cull_bounds); - child_intersect_bounds.intersect(child_bounds); - preroll_context()->cull_rect = cull_bounds; // Cull child - - layer->Preroll(preroll_context(), initial_matrix); - EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched - EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); - EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/color_filter_layer.cc b/flow/layers/color_filter_layer.cc index d37c938784dc4..f838b0612b2e5 100644 --- a/flow/layers/color_filter_layer.cc +++ b/flow/layers/color_filter_layer.cc @@ -7,9 +7,9 @@ namespace flutter { ColorFilterLayer::ColorFilterLayer(sk_sp filter) - : filter_(std::move(filter)) { - set_renders_to_save_layer(true); -} + : filter_(std::move(filter)) {} + +ColorFilterLayer::~ColorFilterLayer() = default; void ColorFilterLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "ColorFilterLayer::Paint"); diff --git a/flow/layers/color_filter_layer.h b/flow/layers/color_filter_layer.h index 628c5b17f6e1c..cf1de4cb610fc 100644 --- a/flow/layers/color_filter_layer.h +++ b/flow/layers/color_filter_layer.h @@ -14,6 +14,7 @@ namespace flutter { class ColorFilterLayer : public ContainerLayer { public: ColorFilterLayer(sk_sp filter); + ~ColorFilterLayer() override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/color_filter_layer_unittests.cc b/flow/layers/color_filter_layer_unittests.cc deleted file mode 100644 index d85dadb642a7b..0000000000000 --- a/flow/layers/color_filter_layer_unittests.cc +++ /dev/null @@ -1,197 +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/color_filter_layer.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/SkColorFilter.h" -#include "third_party/skia/include/effects/SkColorMatrixFilter.h" - -namespace flutter { -namespace testing { - -using ColorFilterLayerTest = LayerTest; - -TEST_F(ColorFilterLayerTest, EmptyLayer) { - auto layer = std::make_shared(sk_sp()); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ColorFilterLayerTest, PaintBeforePreroll) { - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(sk_sp()); - layer->Add(mock_layer); - - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ColorFilterLayerTest, EmptyFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(nullptr); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setColorFilter(nullptr); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, filter_paint, - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ColorFilterLayerTest, SimpleFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto layer_filter = - SkColorMatrixFilter::MakeLightingFilter(SK_ColorGREEN, SK_ColorYELLOW); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_filter); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setColorFilter(layer_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, filter_paint, - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ColorFilterLayerTest, MultipleChildren) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter = - SkColorMatrixFilter::MakeLightingFilter(SK_ColorGREEN, SK_ColorYELLOW); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(layer_filter); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), children_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setColorFilter(layer_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, - filter_paint, nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ColorFilterLayerTest, Nested) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter1 = - SkColorMatrixFilter::MakeLightingFilter(SK_ColorGREEN, SK_ColorYELLOW); - auto layer_filter2 = - SkColorMatrixFilter::MakeLightingFilter(SK_ColorMAGENTA, SK_ColorBLUE); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer1 = std::make_shared(layer_filter1); - auto layer2 = std::make_shared(layer_filter2); - layer2->Add(mock_layer2); - layer1->Add(mock_layer1); - layer1->Add(layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer1->paint_bounds(), children_bounds); - EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - SkPaint filter_paint1, filter_paint2; - filter_paint1.setColorFilter(layer_filter1); - filter_paint2.setColorFilter(layer_filter2); - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, - filter_paint1, nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{child_path2.getBounds(), - filter_paint2, nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index 1c81262b549f7..d5c6a2a03a34a 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -6,44 +6,13 @@ namespace flutter { -ContainerLayer::ContainerLayer() - : child_needs_screen_readback_(false), renders_to_save_layer_(false) {} +ContainerLayer::ContainerLayer() {} + +ContainerLayer::~ContainerLayer() = default; void ContainerLayer::Add(std::shared_ptr layer) { - Layer* the_layer = layer.get(); - the_layer->set_parent(this); + layer->set_parent(this); layers_.push_back(std::move(layer)); - if (the_layer->tree_reads_surface()) { - NotifyChildReadback(the_layer); - } -} - -void ContainerLayer::ClearChildren() { - layers_.clear(); - if (child_needs_screen_readback_) { - child_needs_screen_readback_ = false; - UpdateTreeReadsSurface(); - } -} - -void ContainerLayer::set_renders_to_save_layer(bool value) { - if (renders_to_save_layer_ != value) { - renders_to_save_layer_ = value; - UpdateTreeReadsSurface(); - } -} - -void ContainerLayer::NotifyChildReadback(const Layer* layer) { - if (child_needs_screen_readback_ || !layer->tree_reads_surface()) { - return; - } - child_needs_screen_readback_ = true; - UpdateTreeReadsSurface(); -} - -bool ContainerLayer::ComputeTreeReadsSurface() const { - return layer_reads_surface() || - (!renders_to_save_layer_ && child_needs_screen_readback_); } void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { @@ -54,12 +23,6 @@ void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { set_paint_bounds(child_paint_bounds); } -void ContainerLayer::Paint(PaintContext& context) const { - FML_DCHECK(needs_painting()); - - PaintChildren(context); -} - void ContainerLayer::PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, SkRect* child_paint_bounds) { diff --git a/flow/layers/container_layer.h b/flow/layers/container_layer.h index 431bd12b8dda5..ef1c03328d1df 100644 --- a/flow/layers/container_layer.h +++ b/flow/layers/container_layer.h @@ -13,54 +13,34 @@ namespace flutter { class ContainerLayer : public Layer { public: ContainerLayer(); + ~ContainerLayer() override; void Add(std::shared_ptr layer); void Preroll(PrerollContext* context, const SkMatrix& matrix) override; - void Paint(PaintContext& context) const override; + #if defined(OS_FUCHSIA) void UpdateScene(SceneUpdateContext& context) override; #endif // defined(OS_FUCHSIA) const std::vector>& layers() const { return layers_; } - // Called when the layer, which must be a child of this container, - // changes its tree_reads_surface() result from false to true. - void NotifyChildReadback(const Layer* layer); - protected: void PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, SkRect* child_paint_bounds); void PaintChildren(PaintContext& context) const; - virtual bool ComputeTreeReadsSurface() const override; - #if defined(OS_FUCHSIA) void UpdateSceneChildren(SceneUpdateContext& context); #endif // defined(OS_FUCHSIA) - // Specify whether or not the container has its children render - // to a SaveLayer which will prevent many rendering anomalies - // from propagating to the parent - such as if the children - // read back from the surface on which they render, or if the - // children perform non-associative rendering. Those children - // will now be performing those operations on the SaveLayer - // rather than the layer that this container renders onto. - void set_renders_to_save_layer(bool value); - // For OpacityLayer to restructure to have a single child. - void ClearChildren(); + void ClearChildren() { layers_.clear(); } private: std::vector> layers_; - // child_needs_screen_readback_ is maintained even if the - // renders_to_save_layer_ property is set in case both - // parameters are dynamically and independently determined. - bool child_needs_screen_readback_; - bool renders_to_save_layer_; - FML_DISALLOW_COPY_AND_ASSIGN(ContainerLayer); }; diff --git a/flow/layers/container_layer_unittests.cc b/flow/layers/container_layer_unittests.cc deleted file mode 100644 index f4724b7c0949e..0000000000000 --- a/flow/layers/container_layer_unittests.cc +++ /dev/null @@ -1,200 +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/container_layer.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" - -namespace flutter { -namespace testing { - -using ContainerLayerTest = LayerTest; - -TEST_F(ContainerLayerTest, LayerWithParentHasPlatformView) { - auto layer = std::make_shared(); - - preroll_context()->has_platform_view = true; - EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), - "!context->has_platform_view"); -} - -TEST_F(ContainerLayerTest, EmptyLayer) { - auto layer = std::make_shared(); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ContainerLayerTest, PaintBeforePreroll) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(); - layer->Add(mock_layer); - - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ContainerLayerTest, Simple) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkPaint child_paint(SkColors::kGreen); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_FALSE(preroll_context()->has_platform_view); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), child_path.getBounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(mock_layer->needs_system_composite()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer->parent_cull_rect(), kGiantRect); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, child_paint}}})); -} - -TEST_F(ContainerLayerTest, Multiple) { - SkPath child_path1; - child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkPath child_path2; - child_path2.addRect(8.0f, 2.0f, 16.5f, 14.5f); - SkPaint child_paint1(SkColors::kGray); - SkPaint child_paint2(SkColors::kGreen); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - - auto mock_layer1 = std::make_shared( - child_path1, child_paint1, true /* fake_has_platform_view */); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect expected_total_bounds = child_path1.getBounds(); - expected_total_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); - EXPECT_TRUE(preroll_context()->has_platform_view); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), - kGiantRect); // Siblings are independent - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); -} - -TEST_F(ContainerLayerTest, MultipleWithEmpty) { - SkPath child_path1; - child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkPaint child_paint1(SkColors::kGray); - SkPaint child_paint2(SkColors::kGreen); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(SkPath(), child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_FALSE(preroll_context()->has_platform_view); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds()); - EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_FALSE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}})); -} - -TEST_F(ContainerLayerTest, NeedsSystemComposite) { - SkPath child_path1; - child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkPath child_path2; - child_path2.addRect(8.0f, 2.0f, 16.5f, 14.5f); - SkPaint child_paint1(SkColors::kGray); - SkPaint child_paint2(SkColors::kGreen); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - - auto mock_layer1 = std::make_shared( - child_path1, child_paint1, false /* fake_has_platform_view */, - true /* fake_needs_system_composite */); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect expected_total_bounds = child_path1.getBounds(); - expected_total_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); - EXPECT_FALSE(preroll_context()->has_platform_view); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_TRUE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_TRUE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/layer.cc b/flow/layers/layer.cc index 052b70fac9827..b729f582a0a9a 100644 --- a/flow/layers/layer.cc +++ b/flow/layers/layer.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/flow/layers/layer.h" -#include "flutter/flow/layers/container_layer.h" #include "flutter/flow/paint_utils.h" #include "third_party/skia/include/core/SkColorFilter.h" @@ -14,9 +13,7 @@ Layer::Layer() : parent_(nullptr), needs_system_composite_(false), paint_bounds_(SkRect::MakeEmpty()), - unique_id_(NextUniqueID()), - tree_reads_surface_(false), - layer_reads_surface_(false) {} + unique_id_(NextUniqueID()) {} Layer::~Layer() = default; @@ -29,28 +26,6 @@ uint64_t Layer::NextUniqueID() { return id; } -void Layer::set_layer_reads_surface(bool value) { - if (layer_reads_surface_ != value) { - layer_reads_surface_ = value; - UpdateTreeReadsSurface(); - } -} - -bool Layer::ComputeTreeReadsSurface() const { - return layer_reads_surface_; -} - -void Layer::UpdateTreeReadsSurface() { - bool new_tree_reads_surface = ComputeTreeReadsSurface(); - - if (tree_reads_surface_ != new_tree_reads_surface) { - tree_reads_surface_ = new_tree_reads_surface; - if (parent_ != nullptr) { - parent_->NotifyChildReadback(this); - } - } -} - void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {} #if defined(OS_FUCHSIA) diff --git a/flow/layers/layer.h b/flow/layers/layer.h index ef114b4c381c3..66944376e8ce8 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -145,47 +145,14 @@ class Layer { bool needs_painting() const { return !paint_bounds_.isEmpty(); } - // True iff the layer, or some descendant of the layer, performs an - // operation which depends on (i.e. must read back from) the surface - // on which it is rendered in any way beyond the functionality of - // BlendMode. This value has no setter as it is computed from other - // flags and properties on the layer. - // For an example see |BackdropFilterLayer|. - // - // See |UpdateTreeReadsSurface| - // See |set_layer_reads_surface| - // See |ContainerLayer::set_renders_to_save_layer| - // See |ContainerLayer::NotifyChildReadback| - bool tree_reads_surface() const { return tree_reads_surface_; } - uint64_t unique_id() const { return unique_id_; } - protected: - // Compute a new value for tree_reads_surface_ from all of the various - // properties of this layer. - // Used by |UpdateTreeReadsSurface| - virtual bool ComputeTreeReadsSurface() const; - - // Update the tree_reads_surface_ value and propagate changes to - // ancestors if needed. - // Uses |ComputeTreeReadsSurface| - void UpdateTreeReadsSurface(); - - // True iff the layer itself (not a child or other descendant) performs - // an operation which reads from the surface on which it is rendered. - bool layer_reads_surface() const { return layer_reads_surface_; } - - void set_layer_reads_surface(bool value); - private: ContainerLayer* parent_; bool needs_system_composite_; SkRect paint_bounds_; uint64_t unique_id_; - bool tree_reads_surface_; - bool layer_reads_surface_; - static uint64_t NextUniqueID(); FML_DISALLOW_COPY_AND_ASSIGN(Layer); diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index caa5531a79c06..f0e37c9bed565 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -17,6 +17,8 @@ LayerTree::LayerTree() checkerboard_raster_cache_images_(false), checkerboard_offscreen_layers_(false) {} +LayerTree::~LayerTree() = default; + void LayerTree::RecordBuildTime(fml::TimePoint start) { build_start_ = start; build_finish_ = fml::TimePoint::Now(); diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index d1a22be02c43e..124b8a85dea45 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -22,6 +22,8 @@ class LayerTree { public: LayerTree(); + ~LayerTree(); + void Preroll(CompositorContext::ScopedFrame& frame, bool ignore_raster_cache = false); @@ -41,10 +43,6 @@ class LayerTree { root_layer_ = std::move(root_layer); } - bool root_needs_screen_readback() const { - return root_layer_ && root_layer_->tree_reads_surface(); - } - const SkISize& frame_size() const { return frame_size_; } void set_frame_size(const SkISize& frame_size) { frame_size_ = frame_size; } diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc deleted file mode 100644 index e640e92c84b89..0000000000000 --- a/flow/layers/layer_tree_unittests.cc +++ /dev/null @@ -1,203 +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/layer_tree.h" - -#include "flutter/flow/compositor_context.h" -#include "flutter/flow/layers/container_layer.h" -#include "flutter/flow/testing/mock_layer.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/canvas_test.h" -#include "flutter/testing/mock_canvas.h" -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -class LayerTreeTest : public CanvasTest { - public: - void SetUp() override { - root_transform_ = SkMatrix::MakeTrans(1.0f, 1.0f); - scoped_frame_ = compositor_context_.AcquireFrame( - nullptr, &mock_canvas(), nullptr, root_transform_, false, nullptr); - } - - void TearDown() override { scoped_frame_ = nullptr; } - - LayerTree& layer_tree() { return layer_tree_; } - CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); } - const SkMatrix& root_transform() { return root_transform_; } - - private: - LayerTree layer_tree_; - CompositorContext compositor_context_; - SkMatrix root_transform_; - std::unique_ptr scoped_frame_; -}; - -TEST_F(LayerTreeTest, EmptyLayer) { - auto layer = std::make_shared(); - - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - - layer_tree().Paint(frame()); -} - -TEST_F(LayerTreeTest, PaintBeforePreroll) { - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - SkPath child_path; - child_path.addRect(child_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = std::make_shared(); - layer->Add(mock_layer); - - layer_tree().set_root_layer(layer); - EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(mock_layer->needs_painting()); - EXPECT_FALSE(layer->needs_painting()); - - layer_tree().Paint(frame()); - EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); -} - -TEST_F(LayerTreeTest, Simple) { - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kCyan); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(); - layer->Add(mock_layer); - - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), root_transform()); - - layer_tree().Paint(frame()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, child_paint}}})); -} - -TEST_F(LayerTreeTest, Multiple) { - const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f); - const SkPaint child_paint1(SkColors::kGray); - const SkPaint child_paint2(SkColors::kGreen); - auto mock_layer1 = std::make_shared( - child_path1, child_paint1, true /* fake_has_platform_view */); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect expected_total_bounds = child_path1.getBounds(); - expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer2->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), - kGiantRect); // Siblings are independent - - layer_tree().Paint(frame()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); -} - -TEST_F(LayerTreeTest, MultipleWithEmpty) { - const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f); - const SkPaint child_paint1(SkColors::kGray); - const SkPaint child_paint2(SkColors::kGreen); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(SkPath(), child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds()); - EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_FALSE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer2->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - - layer_tree().Paint(frame()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}})); -} - -TEST_F(LayerTreeTest, NeedsSystemComposite) { - const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f); - const SkPaint child_paint1(SkColors::kGray); - const SkPaint child_paint2(SkColors::kGreen); - auto mock_layer1 = std::make_shared( - child_path1, child_paint1, false /* fake_has_platform_view */, - true /* fake_needs_system_composite */); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect expected_total_bounds = child_path1.getBounds(); - expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_TRUE(mock_layer1->needs_system_composite()); - EXPECT_FALSE(mock_layer2->needs_system_composite()); - EXPECT_TRUE(layer->needs_system_composite()); - EXPECT_EQ(mock_layer1->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer2->parent_matrix(), root_transform()); - EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); - EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - - layer_tree().Paint(frame()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/layer_unittests.cc b/flow/layers/layer_unittests.cc deleted file mode 100644 index 360dba5acd5dc..0000000000000 --- a/flow/layers/layer_unittests.cc +++ /dev/null @@ -1,188 +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/backdrop_filter_layer.h" -#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/color_filter_layer.h" -#include "flutter/flow/layers/container_layer.h" -#include "flutter/flow/layers/opacity_layer.h" -#include "flutter/flow/layers/physical_shape_layer.h" -#include "flutter/flow/layers/shader_mask_layer.h" - -#include "third_party/skia/include/effects/SkBlurImageFilter.h" - -#include "gtest/gtest.h" - -namespace flutter { - -class ReadbackLayer : public ContainerLayer { - public: - ReadbackLayer(const bool reads, const bool saves) { - set_layer_reads_surface(reads); - set_renders_to_save_layer(saves); - } - ~ReadbackLayer() override = default; - - static std::shared_ptr Make(const bool reads, - const bool saves) { - return std::make_shared(reads, saves); - } - - void set_read(const bool reads) { set_layer_reads_surface(reads); } - - void Paint(PaintContext& context) const override {} -}; - -void TestLayerFlag(bool reads, bool saves) { - EXPECT_EQ(ReadbackLayer(reads, saves).tree_reads_surface(), reads); -} - -void TestChildFlag(bool child_reads, bool uses_save_layer, bool ret) { - ReadbackLayer parent = ReadbackLayer(false, uses_save_layer); - parent.Add(ReadbackLayer::Make(child_reads, false)); - EXPECT_EQ(parent.tree_reads_surface(), ret); -} - -TEST(Layer, ReadbackFalse) { - TestLayerFlag(false, false); - TestLayerFlag(false, true); -} - -TEST(Layer, ReadbackTrue) { - TestLayerFlag(true, false); - TestLayerFlag(true, true); -} - -TEST(Layer, NoReadbackNoSaveLayer) { - TestChildFlag(false, false, false); -} - -TEST(Layer, NoReadbackButSaveLayer) { - TestChildFlag(false, true, false); -} - -TEST(Layer, ReadbackNoSaveLayer) { - TestChildFlag(true, false, true); -} - -TEST(Layer, ReadbackButSaveLayer) { - TestChildFlag(true, true, false); -} - -TEST(Layer, AddedChildReadback) { - ReadbackLayer parent = ReadbackLayer(false, false); - EXPECT_FALSE(parent.tree_reads_surface()); - parent.Add(ReadbackLayer::Make(false, false)); - EXPECT_FALSE(parent.tree_reads_surface()); - parent.Add(ReadbackLayer::Make(true, false)); - EXPECT_TRUE(parent.tree_reads_surface()); -} - -TEST(Layer, ChildChangesToReadback) { - ReadbackLayer parent = ReadbackLayer(false, false); - EXPECT_FALSE(parent.tree_reads_surface()); - parent.Add(ReadbackLayer::Make(false, false)); - EXPECT_FALSE(parent.tree_reads_surface()); - std::shared_ptr child = ReadbackLayer::Make(false, false); - parent.Add(child); - EXPECT_FALSE(parent.tree_reads_surface()); - child->set_read(true); - EXPECT_TRUE(parent.tree_reads_surface()); -} - -TEST(Layer, BackdropFilterLayer) { - sk_sp filter = SkBlurImageFilter::Make( - 5.0f, 5.0f, nullptr, nullptr, SkBlurImageFilter::kClamp_TileMode); - EXPECT_TRUE(BackdropFilterLayer(filter).tree_reads_surface()); - filter.reset(); - EXPECT_FALSE(BackdropFilterLayer(filter).tree_reads_surface()); -} - -void TestClipRect(Clip clip_behavior, bool ret) { - ClipRectLayer layer = ClipRectLayer(SkRect::MakeWH(5, 5), clip_behavior); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_EQ(layer.tree_reads_surface(), ret); -} - -TEST(Layer, ClipRectSaveLayer) { - // TestClipRect(Clip::none, true); // ClipRectLayer asserts !Clip::none - TestClipRect(Clip::hardEdge, true); - TestClipRect(Clip::antiAlias, true); - TestClipRect(Clip::antiAliasWithSaveLayer, false); -} - -void TestClipRRect(Clip clip_behavior, bool ret) { - SkRRect r_rect = SkRRect::MakeRect(SkRect::MakeWH(5, 5)); - ClipRRectLayer layer = ClipRRectLayer(r_rect, clip_behavior); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_EQ(layer.tree_reads_surface(), ret); -} - -TEST(Layer, ClipRRectSaveLayer) { - // TestClipRRect(Clip::none, true); // ClipRRectLayer asserts !Clip::none - TestClipRRect(Clip::hardEdge, true); - TestClipRRect(Clip::antiAlias, true); - TestClipRRect(Clip::antiAliasWithSaveLayer, false); -} - -void TestClipPath(Clip clip_behavior, bool ret) { - SkPath path = SkPath(); - path.moveTo(0, 0); - path.lineTo(5, 0); - path.lineTo(0, 5); - path.close(); - ClipPathLayer layer = ClipPathLayer(path, clip_behavior); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_EQ(layer.tree_reads_surface(), ret); -} - -TEST(Layer, ClipPathSaveLayer) { - // TestClipPath(Clip::none, true); // ClipRRectLayer asserts !Clip::none - TestClipPath(Clip::hardEdge, true); - TestClipPath(Clip::antiAlias, true); - TestClipPath(Clip::antiAliasWithSaveLayer, false); -} - -TEST(Layer, ColorFilterSaveLayer) { - sk_sp filter = SkColorFilters::LinearToSRGBGamma(); - ColorFilterLayer layer = ColorFilterLayer(filter); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_FALSE(layer.tree_reads_surface()); -} - -TEST(Layer, OpacitySaveLayer) { - OpacityLayer layer = OpacityLayer(10, SkPoint::Make(0, 0)); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_FALSE(layer.tree_reads_surface()); -} - -void TestPhysicalShapeLayer(Clip clip_behavior, bool ret) { - SkPath path = SkPath(); - path.moveTo(0, 0); - path.lineTo(5, 0); - path.lineTo(0, 5); - path.close(); - PhysicalShapeLayer layer = PhysicalShapeLayer( - SK_ColorRED, SK_ColorBLUE, 1.0f, 100.0f, 10.0f, path, clip_behavior); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_EQ(layer.tree_reads_surface(), ret); -} - -TEST(Layer, PhysicalShapeSaveLayer) { - TestPhysicalShapeLayer(Clip::none, true); - TestPhysicalShapeLayer(Clip::hardEdge, true); - TestPhysicalShapeLayer(Clip::antiAlias, true); - TestPhysicalShapeLayer(Clip::antiAliasWithSaveLayer, false); -} - -TEST(Layer, ShaderMaskSaveLayer) { - ShaderMaskLayer layer = ShaderMaskLayer( - SkShaders::Empty(), SkRect::MakeWH(5, 5), SkBlendMode::kSrcOver); - layer.Add(ReadbackLayer::Make(true, false)); - EXPECT_FALSE(layer.tree_reads_surface()); -} - -} // namespace flutter diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index 6fd5f1692d809..6257700ffbddf 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -9,13 +9,9 @@ namespace flutter { OpacityLayer::OpacityLayer(int alpha, const SkPoint& offset) - : alpha_(alpha), offset_(offset) { - // This type of layer either renders via a SaveLayer or it renders - // from a raster cache image. In either case, it does not pass - // any rendering from a child through to the surface so it is - // effectively "renders to save layer" in all cases. - set_renders_to_save_layer(true); -} + : alpha_(alpha), offset_(offset) {} + +OpacityLayer::~OpacityLayer() = default; void OpacityLayer::EnsureSingleChild() { FML_DCHECK(layers().size() > 0); // OpacityLayer should never be a leaf diff --git a/flow/layers/opacity_layer.h b/flow/layers/opacity_layer.h index f1c18c51918e7..795d8841ba6ed 100644 --- a/flow/layers/opacity_layer.h +++ b/flow/layers/opacity_layer.h @@ -26,6 +26,7 @@ class OpacityLayer : public ContainerLayer { // to many leaf layers. Therefore we try to capture that offset here to stop // the propagation as repainting the OpacityLayer is expensive. OpacityLayer(int alpha, const SkPoint& offset); + ~OpacityLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc deleted file mode 100644 index 84b2221a2e3d0..0000000000000 --- a/flow/layers/opacity_layer_unittests.cc +++ /dev/null @@ -1,310 +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/opacity_layer.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" - -namespace flutter { -namespace testing { - -using OpacityLayerTest = LayerTest; - -TEST_F(OpacityLayerTest, LeafLayer) { - auto layer = - std::make_shared(SK_AlphaOPAQUE, SkPoint::Make(0.0f, 0.0f)); - - EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), - "layers\\(\\)\\.size\\(\\) > 0"); -} - -TEST_F(OpacityLayerTest, EmptyLayer) { - auto mock_layer = std::make_shared(SkPath()); - auto layer = - std::make_shared(SK_AlphaOPAQUE, SkPoint::Make(0.0f, 0.0f)); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(mock_layer->paint_bounds(), SkPath().getBounds()); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_FALSE(mock_layer->needs_painting()); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(OpacityLayerTest, PaintBeforePreroll) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_layer = std::make_shared(child_path); - auto layer = - std::make_shared(SK_AlphaOPAQUE, SkPoint::Make(0.0f, 0.0f)); - layer->Add(mock_layer); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(OpacityLayerTest, FullyOpaque) { - const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); - const SkPoint layer_offset = SkPoint::Make(0.5f, 1.5f); - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); - const SkMatrix layer_transform = - SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM( - SkMatrix::Concat(initial_transform, layer_transform)); -#endif - const SkPaint child_paint = SkPaint(SkColors::kGreen); - const SkRect expected_layer_bounds = - layer_transform.mapRect(child_path.getBounds()); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(SK_AlphaOPAQUE, layer_offset); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), - SkMatrix::Concat(initial_transform, layer_transform)); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_transform), Mutator(SK_AlphaOPAQUE)})); - - const SkPaint opacity_paint = SkPaint(SkColors::kBlack); // A = 1.0f - SkRect opacity_bounds; - expected_layer_bounds.makeOffset(-layer_offset.fX, -layer_offset.fY) - .roundOut(&opacity_bounds); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{integral_layer_transform}}, -#endif - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr, - 2}}, - MockCanvas::DrawCall{2, - MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -TEST_F(OpacityLayerTest, FullyTransparent) { - const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); - const SkPoint layer_offset = SkPoint::Make(0.5f, 1.5f); - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); - const SkMatrix layer_transform = - SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM( - SkMatrix::Concat(initial_transform, layer_transform)); -#endif - const SkPaint child_paint = SkPaint(SkColors::kGreen); - const SkRect expected_layer_bounds = - layer_transform.mapRect(child_path.getBounds()); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = - std::make_shared(SK_AlphaTRANSPARENT, layer_offset); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), - SkMatrix::Concat(initial_transform, layer_transform)); - EXPECT_EQ( - mock_layer->parent_mutators(), - std::vector({Mutator(layer_transform), Mutator(SK_AlphaTRANSPARENT)})); - - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{integral_layer_transform}}, -#endif - MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{2, - MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -TEST_F(OpacityLayerTest, HalfTransparent) { - const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); - const SkPoint layer_offset = SkPoint::Make(0.5f, 1.5f); - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); - const SkMatrix layer_transform = - SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM( - SkMatrix::Concat(initial_transform, layer_transform)); -#endif - const SkPaint child_paint = SkPaint(SkColors::kGreen); - const SkRect expected_layer_bounds = - layer_transform.mapRect(child_path.getBounds()); - const SkAlpha alpha_half = 255 / 2; - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(alpha_half, layer_offset); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), - SkMatrix::Concat(initial_transform, layer_transform)); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_transform), Mutator(alpha_half)})); - - const SkPaint opacity_paint = - SkPaint(SkColor4f::FromColor(SkColorSetA(SK_ColorBLACK, alpha_half))); - SkRect opacity_bounds; - expected_layer_bounds.makeOffset(-layer_offset.fX, -layer_offset.fY) - .roundOut(&opacity_bounds); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{integral_layer_transform}}, -#endif - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr, - 2}}, - MockCanvas::DrawCall{2, - MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -TEST_F(OpacityLayerTest, Nested) { - const SkPath child1_path = SkPath().addRect(SkRect::MakeWH(5.0f, 6.0f)); - const SkPath child2_path = SkPath().addRect(SkRect::MakeWH(2.0f, 7.0f)); - const SkPath child3_path = SkPath().addRect(SkRect::MakeWH(6.0f, 6.0f)); - const SkPoint layer1_offset = SkPoint::Make(0.5f, 1.5f); - const SkPoint layer2_offset = SkPoint::Make(2.5f, 0.5f); - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); - const SkMatrix layer1_transform = - SkMatrix::MakeTrans(layer1_offset.fX, layer1_offset.fY); - const SkMatrix layer2_transform = - SkMatrix::MakeTrans(layer2_offset.fX, layer2_offset.fY); -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - const SkMatrix integral_layer1_transform = RasterCache::GetIntegralTransCTM( - SkMatrix::Concat(initial_transform, layer1_transform)); - const SkMatrix integral_layer2_transform = RasterCache::GetIntegralTransCTM( - SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform), - layer2_transform)); -#endif - const SkPaint child1_paint = SkPaint(SkColors::kRed); - const SkPaint child2_paint = SkPaint(SkColors::kBlue); - const SkPaint child3_paint = SkPaint(SkColors::kGreen); - const SkAlpha alpha1 = 155; - const SkAlpha alpha2 = 224; - auto mock_layer1 = std::make_shared(child1_path, child1_paint); - auto mock_layer2 = std::make_shared(child2_path, child2_paint); - auto mock_layer3 = std::make_shared(child3_path, child3_paint); - auto layer1 = std::make_shared(alpha1, layer1_offset); - auto layer2 = std::make_shared(alpha2, layer2_offset); - layer2->Add(mock_layer2); - layer1->Add(mock_layer1); - layer1->Add(layer2); - layer1->Add(mock_layer3); // Ensure something is processed after recursion - - const SkRect expected_layer2_bounds = - layer2_transform.mapRect(child2_path.getBounds()); - SkRect expected_layer1_bounds = expected_layer2_bounds; - expected_layer1_bounds.join(child1_path.getBounds()); - expected_layer1_bounds.join(child3_path.getBounds()); - expected_layer1_bounds = layer1_transform.mapRect(expected_layer1_bounds); - layer1->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child1_path.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child2_path.getBounds()); - EXPECT_EQ(mock_layer3->paint_bounds(), child3_path.getBounds()); - EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds); - EXPECT_EQ(layer2->paint_bounds(), expected_layer2_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(mock_layer3->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), - SkMatrix::Concat(initial_transform, layer1_transform)); - // EXPECT_EQ(mock_layer1->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1)})); - EXPECT_EQ( - mock_layer2->parent_matrix(), - SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform), - layer2_transform)); - // EXPECT_EQ(mock_layer2->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1), - // Mutator(layer2_transform), Mutator(alpha2)})); - EXPECT_EQ(mock_layer3->parent_matrix(), - SkMatrix::Concat(initial_transform, layer1_transform)); - // EXPECT_EQ(mock_layer3->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1)})); - - const SkPaint opacity1_paint = - SkPaint(SkColor4f::FromColor(SkColorSetA(SK_ColorBLACK, alpha1))); - const SkPaint opacity2_paint = - SkPaint(SkColor4f::FromColor(SkColorSetA(SK_ColorBLACK, alpha2))); - SkRect opacity1_bounds, opacity2_bounds; - expected_layer1_bounds.makeOffset(-layer1_offset.fX, -layer1_offset.fY) - .roundOut(&opacity1_bounds); - expected_layer2_bounds.makeOffset(-layer2_offset.fX, -layer2_offset.fY) - .roundOut(&opacity2_bounds); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer1_transform}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{integral_layer1_transform}}, -#endif - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{opacity1_bounds, opacity1_paint, - nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child1_path, child1_paint}}, - MockCanvas::DrawCall{2, MockCanvas::SaveData{3}}, - MockCanvas::DrawCall{3, MockCanvas::ConcatMatrixData{layer2_transform}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 3, MockCanvas::SetMatrixData{integral_layer2_transform}}, -#endif - MockCanvas::DrawCall{ - 3, MockCanvas::SaveLayerData{opacity2_bounds, opacity2_paint, - nullptr, 4}}, - MockCanvas::DrawCall{ - 4, MockCanvas::DrawPathData{child2_path, child2_paint}}, - MockCanvas::DrawCall{4, MockCanvas::RestoreData{3}}, - MockCanvas::DrawCall{3, MockCanvas::RestoreData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child3_path, child3_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer1->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/performance_overlay_layer.cc b/flow/layers/performance_overlay_layer.cc index ef7b6f2c6194c..ebb279c966866 100644 --- a/flow/layers/performance_overlay_layer.cc +++ b/flow/layers/performance_overlay_layer.cc @@ -8,11 +8,26 @@ #include "flutter/flow/layers/performance_overlay_layer.h" #include "third_party/skia/include/core/SkFont.h" -#include "third_party/skia/include/core/SkTextBlob.h" namespace flutter { namespace { +void DrawStatisticsText(SkCanvas& canvas, + const std::string& string, + int x, + int y, + const std::string& font_path) { + SkFont font; + if (font_path != "") { + font = SkFont(SkTypeface::MakeFromFile(font_path.c_str())); + } + font.setSize(15); + SkPaint paint; + paint.setColor(SK_ColorGRAY); + canvas.drawSimpleText(string.c_str(), string.size(), SkTextEncoding::kUTF8, x, + y, font, paint); +} + void VisualizeStopWatch(SkCanvas& canvas, const Stopwatch& stopwatch, SkScalar x, @@ -32,39 +47,21 @@ void VisualizeStopWatch(SkCanvas& canvas, } if (show_labels) { - auto text = PerformanceOverlayLayer::MakeStatisticsText( - stopwatch, label_prefix, font_path); - SkPaint paint; - paint.setColor(SK_ColorGRAY); - canvas.drawTextBlob(text, x + label_x, y + height + label_y, paint); + double max_ms_per_frame = stopwatch.MaxDelta().ToMillisecondsF(); + double average_ms_per_frame = stopwatch.AverageDelta().ToMillisecondsF(); + std::stringstream stream; + stream.setf(std::ios::fixed | std::ios::showpoint); + stream << std::setprecision(1); + stream << label_prefix << " " + << "max " << max_ms_per_frame << " ms/frame, " + << "avg " << average_ms_per_frame << " ms/frame"; + DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y, + font_path); } } } // namespace -sk_sp PerformanceOverlayLayer::MakeStatisticsText( - const Stopwatch& stopwatch, - const std::string& label_prefix, - const std::string& font_path) { - SkFont font; - if (font_path != "") { - font = SkFont(SkTypeface::MakeFromFile(font_path.c_str())); - } - font.setSize(15); - - double max_ms_per_frame = stopwatch.MaxDelta().ToMillisecondsF(); - double average_ms_per_frame = stopwatch.AverageDelta().ToMillisecondsF(); - std::stringstream stream; - stream.setf(std::ios::fixed | std::ios::showpoint); - stream << std::setprecision(1); - stream << label_prefix << " " - << "max " << max_ms_per_frame << " ms/frame, " - << "avg " << average_ms_per_frame << " ms/frame"; - auto text = stream.str(); - return SkTextBlob::MakeFromText(text.c_str(), text.size(), font, - SkTextEncoding::kUTF8); -} - PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options, const char* font_path) : options_(options) { diff --git a/flow/layers/performance_overlay_layer.h b/flow/layers/performance_overlay_layer.h index b1434a221e688..b5c3370d2055a 100644 --- a/flow/layers/performance_overlay_layer.h +++ b/flow/layers/performance_overlay_layer.h @@ -7,12 +7,9 @@ #include -#include "flutter/flow/instrumentation.h" #include "flutter/flow/layers/layer.h" #include "flutter/fml/macros.h" -class SkTextBlob; - namespace flutter { const int kDisplayRasterizerStatistics = 1 << 0; @@ -22,10 +19,6 @@ const int kVisualizeEngineStatistics = 1 << 3; class PerformanceOverlayLayer : public Layer { public: - static sk_sp MakeStatisticsText(const Stopwatch& stopwatch, - const std::string& label_prefix, - const std::string& font_path); - explicit PerformanceOverlayLayer(uint64_t options, const char* font_path = nullptr); diff --git a/flow/layers/performance_overlay_layer_unittests.cc b/flow/layers/performance_overlay_layer_unittests.cc index 11d7218f2c5aa..605717c870ee3 100644 --- a/flow/layers/performance_overlay_layer_unittests.cc +++ b/flow/layers/performance_overlay_layer_unittests.cc @@ -2,28 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/flow/layers/performance_overlay_layer.h" - #include "flutter/flow/flow_test_utils.h" +#include "flutter/flow/layers/performance_overlay_layer.h" #include "flutter/flow/raster_cache.h" -#include "flutter/flow/testing/layer_test.h" -#include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/build_config.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" -#include "gtest/gtest.h" -#include "third_party/skia/include/core/SkData.h" -#include "third_party/skia/include/core/SkSerialProcs.h" + #include "third_party/skia/include/core/SkSurface.h" -#include "third_party/skia/include/core/SkTextBlob.h" #include "third_party/skia/include/utils/SkBase64.h" -#include -#include +#include "gtest/gtest.h" -namespace flutter { -namespace testing { -namespace { +#include // To get the size of kMockedTimes in compile time. template @@ -88,7 +77,7 @@ static void TestPerformanceOverlayLayerGold(int refresh_rate) { << "Please either set --golden-dir, or make sure that the unit test is " << "run from the right directory (e.g., flutter/engine/src)."; -#if !defined(OS_LINUX) +#if !OS_LINUX GTEST_SKIP() << "Skipping golden tests on non-Linux OSes"; #endif // OS_LINUX const bool golden_data_matches = golden_data->equals(snapshot_data.get()); @@ -108,71 +97,12 @@ static void TestPerformanceOverlayLayerGold(int refresh_rate) { << "Golden file mismatch. Please check " << "the difference between " << golden_file_path << " and " << new_golden_file_path << ", and replace the former " - << "with the latter if the difference looks good.\nS\n" + << "with the latter if the difference looks good.\n\n" << "See also the base64 encoded " << new_golden_file_path << ":\n" << b64_char; } } -} // namespace - -using PerformanceOverlayLayerTest = LayerTest; - -TEST_F(PerformanceOverlayLayerTest, EmptyLayerGraph) { - const uint64_t overlay_opts = kVisualizeRasterizerStatistics; - auto layer = std::make_shared(overlay_opts); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), ""); -} - -TEST_F(PerformanceOverlayLayerTest, InvalidOptions) { - const SkRect layer_bounds = SkRect::MakeLTRB(0.0f, 0.0f, 64.0f, 64.0f); - const uint64_t overlay_opts = 0; - auto layer = std::make_shared(overlay_opts); - - // TODO(): Note calling code has to call set_paint_bounds right now. Make - // this a constructor parameter and move the set_paint_bounds into Preroll - layer->set_paint_bounds(layer_bounds); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), layer_bounds); - EXPECT_TRUE(layer->needs_painting()); - - // Nothing is drawn if options are invalid (0). - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); -} - -TEST_F(PerformanceOverlayLayerTest, SimpleRasterizerStatistics) { - const SkRect layer_bounds = SkRect::MakeLTRB(0.0f, 0.0f, 64.0f, 64.0f); - const uint64_t overlay_opts = kDisplayRasterizerStatistics; - auto layer = std::make_shared(overlay_opts); - - // TODO(): Note calling code has to call set_paint_bounds right now. Make - // this a constructor parameter and move the set_paint_bounds into Preroll - layer->set_paint_bounds(layer_bounds); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), layer_bounds); - EXPECT_TRUE(layer->needs_painting()); - - layer->Paint(paint_context()); - auto overlay_text = PerformanceOverlayLayer::MakeStatisticsText( - paint_context().raster_time, "GPU", ""); - auto overlay_text_data = overlay_text->serialize(SkSerialProcs{}); - SkPaint text_paint; - text_paint.setColor(SK_ColorGRAY); - SkPoint text_position = SkPoint::Make(16.0f, 22.0f); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawTextData{overlay_text_data, text_paint, - text_position}}})); -} - TEST(PerformanceOverlayLayerDefault, Gold) { TestPerformanceOverlayLayerGold(60); } @@ -184,6 +114,3 @@ TEST(PerformanceOverlayLayer90fps, Gold) { TEST(PerformanceOverlayLayer120fps, Gold) { TestPerformanceOverlayLayerGold(120); } - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index d138bff80f651..0a607a88c23b0 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -22,9 +22,7 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color, : color_(color), shadow_color_(shadow_color), device_pixel_ratio_(device_pixel_ratio), -#if defined(OS_FUCHSIA) viewport_depth_(viewport_depth), -#endif elevation_(elevation), path_(path), isRect_(false), @@ -48,9 +46,10 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color, // an SkPath. frameRRect_ = SkRRect::MakeRect(path.getBounds()); } - set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer); } +PhysicalShapeLayer::~PhysicalShapeLayer() = default; + void PhysicalShapeLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { TRACE_EVENT0("flutter", "PhysicalShapeLayer::Preroll"); @@ -67,11 +66,48 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, // Let the system compositor draw all shadows for us. set_needs_system_composite(true); #else - // We will draw the shadow in Paint(), so add some margin to the paint - // bounds to leave space for the shadow. We fill this whole region and clip - // children to it so we don't need to join the child paint bounds. - set_paint_bounds(ComputeShadowBounds(path_.getBounds(), elevation_, - device_pixel_ratio_)); + // Add some margin to the paint bounds to leave space for the shadow. + // We fill this whole region and clip children to it so we don't need to + // join the child paint bounds. + // The offset is calculated as follows: + + // .--- (kLightRadius) + // -------/ (light) + // | / + // | / + // |/ + // |O + // /| (kLightHeight) + // / | + // / | + // / | + // / | + // ------------- (layer) + // /| | + // / | | (elevation) + // A / | |B + // ------------------------------------------------ (canvas) + // --- (extent of shadow) + // + // E = lt } t = (r + w/2)/h + // } => + // r + w/2 = ht } E = (l/h)(r + w/2) + // + // Where: E = extent of shadow + // l = elevation of layer + // r = radius of the light source + // w = width of the layer + // h = light height + // t = tangent of AOB, i.e., multiplier for elevation to extent + SkRect bounds(path_.getBounds()); + // tangent for x + double tx = (kLightRadius * device_pixel_ratio_ + bounds.width() * 0.5) / + kLightHeight; + // tangent for y + double ty = (kLightRadius * device_pixel_ratio_ + bounds.height() * 0.5) / + kLightHeight; + bounds.outset(elevation_ * tx, elevation_ * ty); + set_paint_bounds(bounds); #endif // defined(OS_FUCHSIA) } } @@ -156,50 +192,6 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { context.internal_nodes_canvas->restoreToCount(saveCount); } -SkRect PhysicalShapeLayer::ComputeShadowBounds(const SkRect& bounds, - float elevation, - float pixel_ratio) { - // The shadow offset is calculated as follows: - // .--- (kLightRadius) - // -------/ (light) - // | / - // | / - // |/ - // |O - // /| (kLightHeight) - // / | - // / | - // / | - // / | - // ------------- (layer) - // /| | - // / | | (elevation) - // A / | |B - // ------------------------------------------------ (canvas) - // --- (extent of shadow) - // - // E = lt } t = (r + w/2)/h - // } => - // r + w/2 = ht } E = (l/h)(r + w/2) - // - // Where: E = extent of shadow - // l = elevation of layer - // r = radius of the light source - // w = width of the layer - // h = light height - // t = tangent of AOB, i.e., multiplier for elevation to extent - // tangent for x - double tx = - (kLightRadius * pixel_ratio + bounds.width() * 0.5) / kLightHeight; - // tangent for y - double ty = - (kLightRadius * pixel_ratio + bounds.height() * 0.5) / kLightHeight; - SkRect shadow_bounds(bounds); - shadow_bounds.outset(elevation * tx, elevation * ty); - - return shadow_bounds; -} - void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, const SkPath& path, SkColor color, diff --git a/flow/layers/physical_shape_layer.h b/flow/layers/physical_shape_layer.h index 1b5564c3662b3..f884fe02fc5bd 100644 --- a/flow/layers/physical_shape_layer.h +++ b/flow/layers/physical_shape_layer.h @@ -18,10 +18,8 @@ class PhysicalShapeLayer : public ContainerLayer { float elevation, const SkPath& path, Clip clip_behavior); + ~PhysicalShapeLayer() override; - static SkRect ComputeShadowBounds(const SkRect& bounds, - float elevation, - float pixel_ratio); static void DrawShadow(SkCanvas* canvas, const SkPath& path, SkColor color, @@ -37,21 +35,19 @@ class PhysicalShapeLayer : public ContainerLayer { void UpdateScene(SceneUpdateContext& context) override; #endif // defined(OS_FUCHSIA) - float total_elevation() const { return total_elevation_; } - private: SkColor color_; SkColor shadow_color_; SkScalar device_pixel_ratio_; -#if defined(OS_FUCHSIA) - float viewport_depth_ = 0.0f; -#endif + float viewport_depth_; float elevation_ = 0.0f; float total_elevation_ = 0.0f; SkPath path_; bool isRect_; SkRRect frameRRect_; Clip clip_behavior_; + + friend class PhysicalShapeLayer_TotalElevation_Test; }; } // namespace flutter diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc index f0e22593122c9..972424a2fec6d 100644 --- a/flow/layers/physical_shape_layer_unittests.cc +++ b/flow/layers/physical_shape_layer_unittests.cc @@ -4,243 +4,65 @@ #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" -#include "flutter/testing/mock_canvas.h" +#include "gtest/gtest.h" namespace flutter { -namespace testing { -using PhysicalShapeLayerTest = LayerTest; - -TEST_F(PhysicalShapeLayerTest, EmptyLayer) { - auto layer = - std::make_shared(SK_ColorBLACK, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - SkPath(), Clip::none); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(PhysicalShapeLayerTest, PaintBeforePreroll) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_layer = std::make_shared(child_path, SkPaint()); - auto layer = - std::make_shared(SK_ColorBLACK, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - SkPath(), Clip::none); - layer->Add(mock_layer); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(PhysicalShapeLayerTest, NonEmptyLayer) { - SkPath layer_path; - layer_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto layer = - std::make_shared(SK_ColorGREEN, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - layer_path, Clip::none); - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - SkPaint 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::DrawPathData{layer_path, layer_paint}}})); -} - -TEST_F(PhysicalShapeLayerTest, ChildrenLargerThanPath) { - 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(SK_ColorRED, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - child1_path, Clip::none); - auto child2 = - std::make_shared(SK_ColorBLUE, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - child2_path, Clip::none); - auto layer = - std::make_shared(SK_ColorGREEN, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 0.0f, // elevation - layer_path, Clip::none); - layer->Add(child1); - layer->Add(child2); - - SkRect child_paint_bounds; - layer->Preroll(preroll_context(), SkMatrix()); - 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_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - SkPaint layer_paint; - layer_paint.setColor(SK_ColorGREEN); - layer_paint.setAntiAlias(true); - SkPaint child1_paint; - child1_paint.setColor(SK_ColorRED); - child1_paint.setAntiAlias(true); - SkPaint child2_paint; - child2_paint.setColor(SK_ColorBLUE); - 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( - SK_ColorGREEN, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - initial_elevation, layer_path, Clip::none); +TEST(PhysicalShapeLayer, TotalElevation) { + std::shared_ptr layers[4]; - layer->Preroll(preroll_context(), SkMatrix()); - // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and - // their shadows , so we do not do any painting there. -#if defined(OS_FUCHSIA) - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_TRUE(layer->needs_system_composite()); -#else - EXPECT_EQ(layer->paint_bounds(), - PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(), - initial_elevation, 1.0f)); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); -#endif - EXPECT_EQ(layer->total_elevation(), initial_elevation); + SkColor dummy_color = 0; + SkPath dummy_path; + for (int i = 0; i < 4; i += 1) { + layers[i] = + std::make_shared(dummy_color, dummy_color, + 1.0f, // pixel ratio, + 1.0f, // depth + (float)(i + 1), // elevation + dummy_path, Clip::none); + } - // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and - // their shadows , so we do not use the direct |Paint()| path there. -#if !defined(OS_FUCHSIA) - SkPaint 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}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}})); -#endif -} + layers[0]->Add(layers[1]); + layers[0]->Add(layers[2]); + layers[2]->Add(layers[3]); -TEST_F(PhysicalShapeLayerTest, ElevationComplex) { - // The layer tree should look like this: - // layers[0] +1.0f = 1.0f + const Stopwatch unused_stopwatch; + TextureRegistry unused_texture_registry; + MutatorsStack unused_stack; + PrerollContext preroll_context{ + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // external view embedder + unused_stack, // mutator stack + nullptr, // SkColorSpace* dst_color_space + kGiantRect, // SkRect cull_rect + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry, // texture registry (not supported) + false, // checkerboard_offscreen_layers + 0.0f, // total elevation + }; + + SkMatrix identity; + identity.setIdentity(); + + layers[0]->Preroll(&preroll_context, identity); + + // It should look like this: + // layers[0] +1.0f // | \ // | \ // | \ - // | layers[2] +3.0f = 4.0f + // | layers[2] +3.0f // | | - // | layers[3] +4.0f = 8.0f + // | layers[3] +4.0f // | // | - // layers[1] + 2.0f = 3.0f - constexpr float initial_elevations[4] = {1.0f, 2.0f, 3.0f, 4.0f}; - constexpr float total_elevations[4] = {1.0f, 3.0f, 4.0f, 8.0f}; - SkPath layer_path; - layer_path.addRect(0, 0, 80, 80).close(); - - std::shared_ptr layers[4]; - for (int i = 0; i < 4; i += 1) { - layers[i] = std::make_shared( - SK_ColorBLACK, SK_ColorBLACK, - 1.0f, // pixel ratio - 1.0f, // depth - 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(), SkMatrix()); - 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. -#if defined(OS_FUCHSIA) - EXPECT_EQ(layers[i]->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layers[i]->needs_painting()); - EXPECT_TRUE(layers[i]->needs_system_composite()); -#else - EXPECT_EQ(layers[i]->paint_bounds(), - (PhysicalShapeLayer::ComputeShadowBounds( - layer_path.getBounds(), initial_elevations[i], - 1.0f /* pixel_ratio */))); - EXPECT_TRUE(layers[i]->needs_painting()); - EXPECT_FALSE(layers[i]->needs_system_composite()); -#endif - EXPECT_EQ(layers[i]->total_elevation(), total_elevations[i]); - } - - // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and - // their shadows , so we do not use the direct |Paint()| path there. -#if !defined(OS_FUCHSIA) - SkPaint layer_paint; - layer_paint.setColor(SK_ColorBLACK); - layer_paint.setAntiAlias(true); - layers[0]->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}, - MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{layer_path, layer_paint}}})); -#endif + // layers[1] + 2.0f + EXPECT_EQ(layers[0]->total_elevation_, 1.0f); + EXPECT_EQ(layers[1]->total_elevation_, 3.0f); + EXPECT_EQ(layers[2]->total_elevation_, 4.0f); + EXPECT_EQ(layers[3]->total_elevation_, 8.0f); } -} // namespace testing } // namespace flutter diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 230b648f50e80..c4275e76c13cf 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -17,6 +17,8 @@ PictureLayer::PictureLayer(const SkPoint& offset, is_complex_(is_complex), will_change_(will_change) {} +PictureLayer::~PictureLayer() = default; + void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkPicture* sk_picture = picture(); diff --git a/flow/layers/picture_layer.h b/flow/layers/picture_layer.h index e733e7455ca6c..9c40cbef37cbd 100644 --- a/flow/layers/picture_layer.h +++ b/flow/layers/picture_layer.h @@ -19,6 +19,7 @@ class PictureLayer : public Layer { SkiaGPUObject picture, bool is_complex, bool will_change); + ~PictureLayer() override; SkPicture* picture() const { return picture_.get().get(); } diff --git a/flow/layers/picture_layer_unittests.cc b/flow/layers/picture_layer_unittests.cc deleted file mode 100644 index 7c88845c61be7..0000000000000 --- a/flow/layers/picture_layer_unittests.cc +++ /dev/null @@ -1,102 +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. - -#define FML_USED_ON_EMBEDDER - -#include "flutter/flow/layers/picture_layer.h" - -#include "flutter/flow/testing/skia_gpu_object_layer_test.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" -#include "third_party/skia/include/core/SkPicture.h" - -#ifndef SUPPORT_FRACTIONAL_TRANSLATION -#include "flutter/flow/raster_cache.h" -#endif - -namespace flutter { -namespace testing { - -using PictureLayerTest = SkiaGPUObjectLayerTest; - -TEST_F(PictureLayerTest, InvalidPicture) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - auto layer = std::make_shared( - layer_offset, SkiaGPUObject(), false, false); - - EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), ""); -} - -TEST_F(PictureLayerTest, PaintBeforePrerollInvalidPicture) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - auto layer = std::make_shared( - layer_offset, SkiaGPUObject(), false, false); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "picture_\\.get\\(\\)"); -} - -TEST_F(PictureLayerTest, PaintBeforePreroll) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_picture = SkPicture::MakePlaceholder(picture_bounds); - auto layer = std::make_shared( - layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false); - - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(PictureLayerTest, EmptyLayer) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - const SkRect picture_bounds = SkRect::MakeEmpty(); - auto mock_picture = SkPicture::MakePlaceholder(picture_bounds); - auto layer = std::make_shared( - layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(PictureLayerTest, SimplePicture) { - const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f); - const SkMatrix layer_offset_matrix = - SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); - const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_picture = SkPicture::MakePlaceholder(picture_bounds); - auto layer = std::make_shared( - layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), - picture_bounds.makeOffset(layer_offset.fX, layer_offset.fY)); - EXPECT_EQ(layer->picture(), mock_picture.get()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - layer->Paint(paint_context()); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, - MockCanvas::ConcatMatrixData{layer_offset_matrix}}, -#ifndef SUPPORT_FRACTIONAL_TRANSLATION - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{RasterCache::GetIntegralTransCTM( - layer_offset_matrix)}}, -#endif - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPictureData{mock_picture->serialize(), SkPaint(), - SkMatrix()}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/platform_view_layer.cc b/flow/layers/platform_view_layer.cc index 81541b7a0cde8..3f72993f97d66 100644 --- a/flow/layers/platform_view_layer.cc +++ b/flow/layers/platform_view_layer.cc @@ -11,6 +11,8 @@ PlatformViewLayer::PlatformViewLayer(const SkPoint& offset, int64_t view_id) : offset_(offset), size_(size), view_id_(view_id) {} +PlatformViewLayer::~PlatformViewLayer() = default; + void PlatformViewLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(), diff --git a/flow/layers/platform_view_layer.h b/flow/layers/platform_view_layer.h index 242b3734dd3b1..7ce7ccb58a856 100644 --- a/flow/layers/platform_view_layer.h +++ b/flow/layers/platform_view_layer.h @@ -14,6 +14,7 @@ namespace flutter { class PlatformViewLayer : public Layer { public: PlatformViewLayer(const SkPoint& offset, const SkSize& size, int64_t view_id); + ~PlatformViewLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/platform_view_layer_unittests.cc b/flow/layers/platform_view_layer_unittests.cc deleted file mode 100644 index 123f9ab9925f6..0000000000000 --- a/flow/layers/platform_view_layer_unittests.cc +++ /dev/null @@ -1,38 +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/platform_view_layer.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" - -namespace flutter { -namespace testing { - -using PlatformViewLayerTest = LayerTest; - -TEST_F(PlatformViewLayerTest, NullViewEmbedderDoesntPrerollCompositeOrPaint) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - const SkSize layer_size = SkSize::Make(8.0f, 8.0f); - const int64_t view_id = 0; - auto layer = - std::make_shared(layer_offset, layer_size, view_id); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_FALSE(preroll_context()->has_platform_view); - EXPECT_EQ(layer->paint_bounds(), - SkRect::MakeSize(layer_size) - .makeOffset(layer_offset.fX, layer_offset.fY)); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - - layer->Paint(paint_context()); - EXPECT_EQ(paint_context().leaf_nodes_canvas, &mock_canvas()); - EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/shader_mask_layer.cc b/flow/layers/shader_mask_layer.cc index a1590ec8c9e9a..36e7b7332aeae 100644 --- a/flow/layers/shader_mask_layer.cc +++ b/flow/layers/shader_mask_layer.cc @@ -9,9 +9,9 @@ namespace flutter { ShaderMaskLayer::ShaderMaskLayer(sk_sp shader, const SkRect& mask_rect, SkBlendMode blend_mode) - : shader_(shader), mask_rect_(mask_rect), blend_mode_(blend_mode) { - set_renders_to_save_layer(true); -} + : shader_(shader), mask_rect_(mask_rect), blend_mode_(blend_mode) {} + +ShaderMaskLayer::~ShaderMaskLayer() = default; void ShaderMaskLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "ShaderMaskLayer::Paint"); diff --git a/flow/layers/shader_mask_layer.h b/flow/layers/shader_mask_layer.h index 7f633c0372d45..01836f4f2fb54 100644 --- a/flow/layers/shader_mask_layer.h +++ b/flow/layers/shader_mask_layer.h @@ -16,6 +16,7 @@ class ShaderMaskLayer : public ContainerLayer { ShaderMaskLayer(sk_sp shader, const SkRect& mask_rect, SkBlendMode blend_mode); + ~ShaderMaskLayer() override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/shader_mask_layer_unittests.cc b/flow/layers/shader_mask_layer_unittests.cc deleted file mode 100644 index 4194747863ff4..0000000000000 --- a/flow/layers/shader_mask_layer_unittests.cc +++ /dev/null @@ -1,255 +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/shader_mask_layer.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/SkShader.h" -#include "third_party/skia/include/effects/SkPerlinNoiseShader.h" - -namespace flutter { -namespace testing { - -using ShaderMaskLayerTest = LayerTest; - -TEST_F(ShaderMaskLayerTest, EmptyLayer) { - auto layer = - std::make_shared(nullptr, kEmptyRect, SkBlendMode::kSrc); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ShaderMaskLayerTest, PaintBeforePreroll) { - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - auto mock_layer = std::make_shared(child_path); - auto layer = - std::make_shared(nullptr, kEmptyRect, SkBlendMode::kSrc); - layer->Add(mock_layer); - - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(ShaderMaskLayerTest, EmptyFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkRect layer_bounds = SkRect::MakeLTRB(2.0f, 4.0f, 6.5f, 6.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(nullptr, layer_bounds, - SkBlendMode::kSrc); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setBlendMode(SkBlendMode::kSrc); - filter_paint.setShader(nullptr); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, SkPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkMatrix::MakeTrans( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ShaderMaskLayerTest, SimpleFilter) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkRect layer_bounds = SkRect::MakeLTRB(2.0f, 4.0f, 6.5f, 6.5f); - const SkPath child_path = SkPath().addRect(child_bounds); - const SkPaint child_paint = SkPaint(SkColors::kYellow); - auto layer_filter = - SkPerlinNoiseShader::MakeImprovedNoise(1.0f, 1.0f, 1, 1.0f); - auto mock_layer = std::make_shared(child_path, child_paint); - auto layer = std::make_shared(layer_filter, layer_bounds, - SkBlendMode::kSrc); - layer->Add(mock_layer); - - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(layer->paint_bounds(), child_bounds); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setBlendMode(SkBlendMode::kSrc); - filter_paint.setShader(layer_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, SkPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkMatrix::MakeTrans( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ShaderMaskLayerTest, MultipleChildren) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); - const SkRect layer_bounds = SkRect::MakeLTRB(2.0f, 4.0f, 6.5f, 6.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter = - SkPerlinNoiseShader::MakeImprovedNoise(1.0f, 1.0f, 1, 1.0f); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer = std::make_shared(layer_filter, layer_bounds, - SkBlendMode::kSrc); - layer->Add(mock_layer1); - layer->Add(mock_layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer->paint_bounds(), children_bounds); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - SkPaint filter_paint; - filter_paint.setBlendMode(SkBlendMode::kSrc); - filter_paint.setShader(layer_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkMatrix::MakeTrans( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(ShaderMaskLayerTest, Nested) { - const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f); - const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 7.5f, 8.5f); - const SkRect layer_bounds = SkRect::MakeLTRB(2.0f, 4.0f, 20.5f, 20.5f); - const SkPath child_path1 = SkPath().addRect(child_bounds); - const SkPath child_path2 = - SkPath().addRect(child_bounds.makeOffset(3.0f, 0.0f)); - const SkPaint child_paint1 = SkPaint(SkColors::kYellow); - const SkPaint child_paint2 = SkPaint(SkColors::kCyan); - auto layer_filter1 = - SkPerlinNoiseShader::MakeImprovedNoise(1.0f, 1.0f, 1, 1.0f); - auto layer_filter2 = - SkPerlinNoiseShader::MakeImprovedNoise(2.0f, 2.0f, 2, 2.0f); - auto mock_layer1 = std::make_shared(child_path1, child_paint1); - auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto layer1 = std::make_shared(layer_filter1, layer_bounds, - SkBlendMode::kSrc); - auto layer2 = std::make_shared(layer_filter2, layer_bounds, - SkBlendMode::kSrc); - layer2->Add(mock_layer2); - layer1->Add(mock_layer1); - layer1->Add(layer2); - - SkRect children_bounds = child_path1.getBounds(); - children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); - EXPECT_EQ(layer1->paint_bounds(), children_bounds); - EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); - EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - - SkPaint filter_paint1, filter_paint2; - filter_paint1.setBlendMode(SkBlendMode::kSrc); - filter_paint2.setBlendMode(SkBlendMode::kSrc); - filter_paint1.setShader(layer_filter1); - filter_paint2.setShader(layer_filter2); - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), nullptr, - 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{child_path2.getBounds(), SkPaint(), - nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{SkMatrix::MakeTrans( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 2, - MockCanvas::DrawRectData{ - SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), - filter_paint2}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkMatrix::MakeTrans( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, - MockCanvas::DrawRectData{ - SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), - filter_paint1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/texture_layer.cc b/flow/layers/texture_layer.cc index 848f69c8a115a..c7716dd59bc29 100644 --- a/flow/layers/texture_layer.cc +++ b/flow/layers/texture_layer.cc @@ -14,6 +14,8 @@ TextureLayer::TextureLayer(const SkPoint& offset, bool freeze) : offset_(offset), size_(size), texture_id_(texture_id), freeze_(freeze) {} +TextureLayer::~TextureLayer() = default; + void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(), size_.height())); diff --git a/flow/layers/texture_layer.h b/flow/layers/texture_layer.h index 20f6c709d6107..7c04471afa0c1 100644 --- a/flow/layers/texture_layer.h +++ b/flow/layers/texture_layer.h @@ -17,6 +17,7 @@ class TextureLayer : public Layer { const SkSize& size, int64_t texture_id, bool freeze); + ~TextureLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/texture_layer_unittests.cc b/flow/layers/texture_layer_unittests.cc deleted file mode 100644 index d8a1a2bee8aa5..0000000000000 --- a/flow/layers/texture_layer_unittests.cc +++ /dev/null @@ -1,57 +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/texture_layer.h" - -#include "flutter/flow/testing/layer_test.h" -#include "flutter/flow/testing/mock_layer.h" -#include "flutter/flow/testing/mock_texture.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" - -namespace flutter { -namespace testing { - -using TextureLayerTest = LayerTest; - -TEST_F(TextureLayerTest, InvalidTexture) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - const SkSize layer_size = SkSize::Make(8.0f, 8.0f); - auto layer = - std::make_shared(layer_offset, layer_size, 0, false); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), - (SkRect::MakeSize(layer_size) - .makeOffset(layer_offset.fX, layer_offset.fY))); - EXPECT_TRUE(layer->needs_painting()); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); -} - -TEST_F(TextureLayerTest, EmptyLayer) { - const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f); - const SkSize layer_size = SkSize::Make(0.0f, 0.0f); - const int64_t texture_id = 0; - auto mock_texture = std::make_shared(texture_id); - auto layer = std::make_shared(layer_offset, layer_size, - texture_id, false); - - // Ensure the texture is located by the Layer. - preroll_context()->texture_registry.RegisterTexture(mock_texture); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), kEmptyRect); - EXPECT_FALSE(layer->needs_painting()); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_texture->paint_calls(), - std::vector({MockTexture::PaintCall{ - mock_canvas(), layer->paint_bounds(), false, nullptr}})); - EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc index 9513e8bc0fec6..5a7af132c68f2 100644 --- a/flow/layers/transform_layer.cc +++ b/flow/layers/transform_layer.cc @@ -24,6 +24,8 @@ TransformLayer::TransformLayer(const SkMatrix& transform) } } +TransformLayer::~TransformLayer() = default; + void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkMatrix child_matrix; child_matrix.setConcat(matrix, transform_); diff --git a/flow/layers/transform_layer.h b/flow/layers/transform_layer.h index a21e7d4f10c5b..f19a963ced9fe 100644 --- a/flow/layers/transform_layer.h +++ b/flow/layers/transform_layer.h @@ -14,6 +14,7 @@ namespace flutter { class TransformLayer : public ContainerLayer { public: TransformLayer(const SkMatrix& transform); + ~TransformLayer() override; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; diff --git a/flow/layers/transform_layer_unittests.cc b/flow/layers/transform_layer_unittests.cc deleted file mode 100644 index 8d196db279c4b..0000000000000 --- a/flow/layers/transform_layer_unittests.cc +++ /dev/null @@ -1,226 +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/transform_layer.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" - -namespace flutter { -namespace testing { - -using TransformLayerTest = LayerTest; - -TEST_F(TransformLayerTest, EmptyLayer) { - auto layer = std::make_shared(SkMatrix()); // identity - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); - EXPECT_FALSE(layer->needs_painting()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(TransformLayerTest, PaintBeforePreroll) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto mock_layer = std::make_shared(child_path, SkPaint()); - auto layer = std::make_shared(SkMatrix()); // identity - layer->Add(mock_layer); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(TransformLayerTest, Identity) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkRect cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); - auto mock_layer = std::make_shared(child_path, SkPaint()); - auto layer = std::make_shared(SkMatrix()); // identity - layer->Add(mock_layer); - - preroll_context()->cull_rect = cull_rect; - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix()); // identity - EXPECT_EQ(mock_layer->parent_cull_rect(), cull_rect); - EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(SkMatrix())})); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, SkPaint()}}})); -} - -TEST_F(TransformLayerTest, Simple) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkRect cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - SkMatrix layer_transform = SkMatrix::MakeTrans(2.5f, 2.5f); - SkMatrix inverse_layer_transform; - EXPECT_TRUE(layer_transform.invert(&inverse_layer_transform)); - - auto mock_layer = std::make_shared(child_path, SkPaint()); - auto layer = std::make_shared(layer_transform); - layer->Add(mock_layer); - - preroll_context()->cull_rect = cull_rect; - layer->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer->paint_bounds(), - layer_transform.mapRect(mock_layer->paint_bounds())); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_EQ(mock_layer->parent_matrix(), - SkMatrix::Concat(initial_transform, layer_transform)); - EXPECT_EQ(mock_layer->parent_cull_rect(), - inverse_layer_transform.mapRect(cull_rect)); - EXPECT_EQ(mock_layer->parent_mutators(), - std::vector({Mutator(layer_transform)})); - - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{layer_transform}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, SkPaint()}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(TransformLayerTest, Nested) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkRect cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - SkMatrix layer1_transform = SkMatrix::MakeTrans(2.5f, 2.5f); - SkMatrix layer2_transform = SkMatrix::MakeTrans(2.5f, 2.5f); - SkMatrix inverse_layer1_transform, inverse_layer2_transform; - EXPECT_TRUE(layer1_transform.invert(&inverse_layer1_transform)); - EXPECT_TRUE(layer2_transform.invert(&inverse_layer2_transform)); - - auto mock_layer = std::make_shared(child_path, SkPaint()); - auto layer1 = std::make_shared(layer1_transform); - auto layer2 = std::make_shared(layer2_transform); - layer1->Add(layer2); - layer2->Add(mock_layer); - - preroll_context()->cull_rect = cull_rect; - layer1->Preroll(preroll_context(), initial_transform); - EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer2->paint_bounds(), - layer2_transform.mapRect(mock_layer->paint_bounds())); - EXPECT_EQ(layer1->paint_bounds(), - layer1_transform.mapRect(layer2->paint_bounds())); - EXPECT_TRUE(mock_layer->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_EQ( - mock_layer->parent_matrix(), - SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform), - layer2_transform)); - EXPECT_EQ(mock_layer->parent_cull_rect(), - inverse_layer2_transform.mapRect( - inverse_layer1_transform.mapRect(cull_rect))); - EXPECT_EQ( - mock_layer->parent_mutators(), - std::vector({Mutator(layer2_transform), Mutator(layer1_transform)})); - - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{layer1_transform}}, - MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{layer2_transform}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, SkPaint()}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -TEST_F(TransformLayerTest, NestedSeparated) { - SkPath child_path; - child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f); - SkRect cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); - SkMatrix initial_transform = SkMatrix::MakeTrans(-0.5f, -0.5f); - SkMatrix layer1_transform = SkMatrix::MakeTrans(2.5f, 2.5f); - SkMatrix layer2_transform = SkMatrix::MakeTrans(2.5f, 2.5f); - SkMatrix inverse_layer1_transform, inverse_layer2_transform; - EXPECT_TRUE(layer1_transform.invert(&inverse_layer1_transform)); - EXPECT_TRUE(layer2_transform.invert(&inverse_layer2_transform)); - - auto mock_layer1 = - std::make_shared(child_path, SkPaint(SkColors::kBlue)); - auto mock_layer2 = - std::make_shared(child_path, SkPaint(SkColors::kGreen)); - auto layer1 = std::make_shared(layer1_transform); - auto layer2 = std::make_shared(layer2_transform); - layer1->Add(mock_layer1); - layer1->Add(layer2); - layer2->Add(mock_layer2); - - preroll_context()->cull_rect = cull_rect; - layer1->Preroll(preroll_context(), initial_transform); - SkRect expected_layer1_bounds = layer2->paint_bounds(); - expected_layer1_bounds.join(mock_layer1->paint_bounds()); - layer1_transform.mapRect(&expected_layer1_bounds); - EXPECT_EQ(mock_layer2->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer2->paint_bounds(), - layer2_transform.mapRect(mock_layer2->paint_bounds())); - EXPECT_EQ(mock_layer1->paint_bounds(), child_path.getBounds()); - EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds); - EXPECT_TRUE(mock_layer2->needs_painting()); - EXPECT_TRUE(layer2->needs_painting()); - EXPECT_TRUE(mock_layer1->needs_painting()); - EXPECT_TRUE(layer1->needs_painting()); - EXPECT_EQ(mock_layer1->parent_matrix(), - SkMatrix::Concat(initial_transform, layer1_transform)); - EXPECT_EQ( - mock_layer2->parent_matrix(), - SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform), - layer2_transform)); - EXPECT_EQ(mock_layer1->parent_cull_rect(), - inverse_layer1_transform.mapRect(cull_rect)); - EXPECT_EQ(mock_layer2->parent_cull_rect(), - inverse_layer2_transform.mapRect( - inverse_layer1_transform.mapRect(cull_rect))); - EXPECT_EQ(mock_layer1->parent_mutators(), - std::vector({Mutator(layer1_transform)})); - EXPECT_EQ( - mock_layer2->parent_mutators(), - std::vector({Mutator(layer2_transform), Mutator(layer1_transform)})); - - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{layer1_transform}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, - SkPaint(SkColors::kBlue)}}, - MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{layer2_transform}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, - SkPaint(SkColors::kGreen)}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/matrix_decomposition_unittests.cc b/flow/matrix_decomposition_unittests.cc index 8aa511e4a0a97..cf96025276737 100644 --- a/flow/matrix_decomposition_unittests.cc +++ b/flow/matrix_decomposition_unittests.cc @@ -12,9 +12,6 @@ #include "flutter/flow/matrix_decomposition.h" #include "gtest/gtest.h" -namespace flutter { -namespace testing { - TEST(MatrixDecomposition, Rotation) { SkMatrix44 matrix = SkMatrix44::I(); @@ -96,8 +93,7 @@ TEST(MatrixDecomposition, Combination) { } TEST(MatrixDecomposition, ScaleFloatError) { - constexpr float scale_increment = 0.00001f; - for (float scale = 0.0001f; scale < 2.0f; scale += scale_increment) { + for (float scale = 0.0001f; scale < 2.0f; scale += 0.000001f) { SkMatrix44 matrix = SkMatrix44::I(); matrix.setScale(scale, scale, 1.0f); @@ -156,6 +152,3 @@ TEST(MatrixDecomposition, ScaleFloatError) { ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[1]); ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[2]); } - -} // namespace testing -} // namespace flutter diff --git a/flow/mutators_stack_unittests.cc b/flow/mutators_stack_unittests.cc index 1d31a81623307..97cfe9a54a7c7 100644 --- a/flow/mutators_stack_unittests.cc +++ b/flow/mutators_stack_unittests.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/flow/embedded_views.h" - #include "gtest/gtest.h" namespace flutter { diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc index bd83d807875f2..64f4405ebe5a0 100644 --- a/flow/raster_cache_unittests.cc +++ b/flow/raster_cache_unittests.cc @@ -3,15 +3,10 @@ // found in the LICENSE file. #include "flutter/flow/raster_cache.h" - #include "gtest/gtest.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -namespace flutter { -namespace testing { -namespace { - sk_sp GetSamplePicture() { SkPictureRecorder recorder; recorder.beginRecording(SkRect::MakeWH(150, 100)); @@ -22,8 +17,6 @@ sk_sp GetSamplePicture() { return recorder.finishRecordingAsPicture(); } -} // namespace - TEST(RasterCache, SimpleInitialization) { flutter::RasterCache cache; ASSERT_TRUE(true); @@ -100,6 +93,3 @@ TEST(RasterCache, SweepsRemoveUnusedFrames) { ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 5 } - -} // namespace testing -} // namespace flutter diff --git a/flow/skia_gpu_object.h b/flow/skia_gpu_object.h index 2a09f982a4386..4823ec14208c5 100644 --- a/flow/skia_gpu_object.h +++ b/flow/skia_gpu_object.h @@ -54,11 +54,14 @@ class SkiaGPUObject { using SkiaObjectType = T; SkiaGPUObject() = default; + SkiaGPUObject(sk_sp object, fml::RefPtr queue) : object_(std::move(object)), queue_(std::move(queue)) { FML_DCHECK(object_); } + SkiaGPUObject(SkiaGPUObject&&) = default; + ~SkiaGPUObject() { reset(); } SkiaGPUObject& operator=(SkiaGPUObject&&) = default; diff --git a/flow/skia_gpu_object_unittests.cc b/flow/skia_gpu_object_unittests.cc index 9df82ad11c312..aa259a6909eec 100644 --- a/flow/skia_gpu_object_unittests.cc +++ b/flow/skia_gpu_object_unittests.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/flow/skia_gpu_object.h" - #include "flutter/fml/message_loop.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/fml/task_runner.h" @@ -14,6 +13,8 @@ namespace flutter { namespace testing { +using SkiaGpuObjectTest = flutter::testing::ThreadTest; + class TestSkObject : public SkRefCnt { public: TestSkObject(std::shared_ptr latch, @@ -21,9 +22,7 @@ class TestSkObject : public SkRefCnt { : latch_(latch), dtor_task_queue_id_(dtor_task_queue_id) {} ~TestSkObject() { - if (dtor_task_queue_id_) { - *dtor_task_queue_id_ = fml::MessageLoop::GetCurrentTaskQueueId(); - } + *dtor_task_queue_id_ = fml::MessageLoop::GetCurrentTaskQueueId(); latch_->Signal(); } @@ -32,107 +31,19 @@ class TestSkObject : public SkRefCnt { fml::TaskQueueId* dtor_task_queue_id_; }; -class SkiaGpuObjectTest : public ThreadTest { - public: - SkiaGpuObjectTest() - : unref_task_runner_(CreateNewThread()), - unref_queue_(fml::MakeRefCounted( - unref_task_runner(), - fml::TimeDelta::FromSeconds(0))), - delayed_unref_queue_(fml::MakeRefCounted( - unref_task_runner(), - fml::TimeDelta::FromSeconds(3))) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - } - - fml::RefPtr unref_task_runner() { - return unref_task_runner_; - } - fml::RefPtr unref_queue() { return unref_queue_; } - fml::RefPtr delayed_unref_queue() { - return delayed_unref_queue_; - } - - private: - fml::RefPtr unref_task_runner_; - fml::RefPtr unref_queue_; - fml::RefPtr delayed_unref_queue_; -}; +TEST_F(SkiaGpuObjectTest, UnrefQueue) { + fml::RefPtr task_runner = CreateNewThread(); + fml::RefPtr queue = fml::MakeRefCounted( + task_runner, fml::TimeDelta::FromSeconds(0)); -TEST_F(SkiaGpuObjectTest, QueueSimple) { std::shared_ptr latch = std::make_shared(); fml::TaskQueueId dtor_task_queue_id(0); SkRefCnt* ref_object = new TestSkObject(latch, &dtor_task_queue_id); - unref_queue()->Unref(ref_object); - latch->Wait(); - ASSERT_EQ(dtor_task_queue_id, unref_task_runner()->GetTaskQueueId()); -} - -TEST_F(SkiaGpuObjectTest, ObjectDestructor) { - std::shared_ptr latch = - std::make_shared(); - fml::TaskQueueId dtor_task_queue_id(0); - - { - auto object = sk_make_sp(latch, &dtor_task_queue_id); - SkiaGPUObject sk_object(object, unref_queue()); - ASSERT_EQ(sk_object.get(), object); - ASSERT_EQ(dtor_task_queue_id, 0); - } - - latch->Wait(); - ASSERT_EQ(dtor_task_queue_id, unref_task_runner()->GetTaskQueueId()); -} - -TEST_F(SkiaGpuObjectTest, ObjectReset) { - std::shared_ptr latch = - std::make_shared(); - fml::TaskQueueId dtor_task_queue_id(0); - SkiaGPUObject sk_object( - sk_make_sp(latch, &dtor_task_queue_id), unref_queue()); - - sk_object.reset(); - ASSERT_EQ(sk_object.get(), nullptr); - - latch->Wait(); - ASSERT_EQ(dtor_task_queue_id, unref_task_runner()->GetTaskQueueId()); -} - -TEST_F(SkiaGpuObjectTest, ObjectResetBeforeDestructor) { - std::shared_ptr latch = - std::make_shared(); - fml::TaskQueueId dtor_task_queue_id(0); - - { - auto object = sk_make_sp(latch, &dtor_task_queue_id); - SkiaGPUObject sk_object(object, unref_queue()); - ASSERT_EQ(sk_object.get(), object); - ASSERT_EQ(dtor_task_queue_id, 0); - - sk_object.reset(); - ASSERT_EQ(sk_object.get(), nullptr); - } - - latch->Wait(); - ASSERT_EQ(dtor_task_queue_id, unref_task_runner()->GetTaskQueueId()); -} - -TEST_F(SkiaGpuObjectTest, ObjectResetTwice) { - std::shared_ptr latch = - std::make_shared(); - fml::TaskQueueId dtor_task_queue_id(0); - SkiaGPUObject sk_object( - sk_make_sp(latch, &dtor_task_queue_id), unref_queue()); - - sk_object.reset(); - ASSERT_EQ(sk_object.get(), nullptr); - sk_object.reset(); - ASSERT_EQ(sk_object.get(), nullptr); - + queue->Unref(ref_object); latch->Wait(); - ASSERT_EQ(dtor_task_queue_id, unref_task_runner()->GetTaskQueueId()); + ASSERT_EQ(dtor_task_queue_id, task_runner->GetTaskQueueId()); } } // namespace testing diff --git a/flow/testing/layer_test.h b/flow/testing/layer_test.h deleted file mode 100644 index e38d690a2eeb7..0000000000000 --- a/flow/testing/layer_test.h +++ /dev/null @@ -1,74 +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 FLOW_TESTING_LAYER_TEST_H_ -#define FLOW_TESTING_LAYER_TEST_H_ - -#include "flutter/flow/layers/layer.h" - -#include -#include - -#include "flutter/fml/macros.h" -#include "flutter/testing/canvas_test.h" -#include "flutter/testing/mock_canvas.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkImageInfo.h" -#include "third_party/skia/include/utils/SkNWayCanvas.h" - -namespace flutter { -namespace testing { - -// This fixture allows generating tests which can |Paint()| and |Preroll()| -// |Layer|'s. -// |LayerTest| is a default implementation based on |::testing::Test|. -// -// |BaseT| should be the base test type, such as |::testing::Test| below. -template -class LayerTestBase : public CanvasTestBase { - using TestT = CanvasTestBase; - - public: - LayerTestBase() - : preroll_context_({ - nullptr, /* raster_cache */ - nullptr, /* gr_context */ - nullptr, /* external_view_embedder */ - mutators_stack_, TestT::mock_canvas().imageInfo().colorSpace(), - kGiantRect, /* cull_rect */ - raster_time_, ui_time_, texture_registry_, - false, /* checkerboard_offscreen_layers */ - 0.0f /* total_elevation */ - }), - paint_context_({ - TestT::mock_canvas().internal_canvas(), /* internal_nodes_canvas */ - &TestT::mock_canvas(), /* leaf_nodes_canvas */ - nullptr, /* gr_context */ - nullptr, /* external_view_embedder */ - raster_time_, ui_time_, texture_registry_, - nullptr, /* raster_cache */ - false, /* checkerboard_offscreen_layers */ - }) {} - - TextureRegistry& texture_regitry() { return texture_registry_; } - PrerollContext* preroll_context() { return &preroll_context_; } - Layer::PaintContext& paint_context() { return paint_context_; } - - private: - Stopwatch raster_time_; - Stopwatch ui_time_; - MutatorsStack mutators_stack_; - TextureRegistry texture_registry_; - - PrerollContext preroll_context_; - Layer::PaintContext paint_context_; - - FML_DISALLOW_COPY_AND_ASSIGN(LayerTestBase); -}; -using LayerTest = LayerTestBase<::testing::Test>; - -} // namespace testing -} // namespace flutter - -#endif // FLOW_TESTING_LAYER_TEST_H_ diff --git a/flow/testing/mock_layer.cc b/flow/testing/mock_layer.cc deleted file mode 100644 index 1065f43054674..0000000000000 --- a/flow/testing/mock_layer.cc +++ /dev/null @@ -1,38 +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/testing/mock_layer.h" - -namespace flutter { -namespace testing { - -MockLayer::MockLayer(SkPath path, - SkPaint paint, - bool fake_has_platform_view, - bool fake_needs_system_composite) - : fake_paint_path_(path), - fake_paint_(paint), - fake_has_platform_view_(fake_has_platform_view), - fake_needs_system_composite_(fake_needs_system_composite) {} - -void MockLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { - parent_mutators_ = context->mutators_stack; - parent_matrix_ = matrix; - parent_cull_rect_ = context->cull_rect; - parent_elevation_ = context->total_elevation; - parent_has_platform_view_ = context->has_platform_view; - - context->has_platform_view = fake_has_platform_view_; - set_paint_bounds(fake_paint_path_.getBounds()); - set_needs_system_composite(fake_needs_system_composite_); -} - -void MockLayer::Paint(PaintContext& context) const { - FML_DCHECK(needs_painting()); - - context.leaf_nodes_canvas->drawPath(fake_paint_path_, fake_paint_); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/mock_layer.h b/flow/testing/mock_layer.h deleted file mode 100644 index b55452a37812c..0000000000000 --- a/flow/testing/mock_layer.h +++ /dev/null @@ -1,50 +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 FLOW_TESTING_MOCK_LAYER_H_ -#define FLOW_TESTING_MOCK_LAYER_H_ - -#include "flutter/flow/layers/layer.h" - -namespace flutter { -namespace testing { - -// Mock implementation of the |Layer| interface that does nothing but paint -// the specified |path| into the canvas. It records the |PrerollContext| and -// |PaintContext| data passed in by its parent |Layer|, so the test can later -// verify the data against expected values. -class MockLayer : public Layer { - public: - MockLayer(SkPath path, - SkPaint paint = SkPaint(), - bool fake_has_platform_view = false, - bool fake_needs_system_composite = false); - - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; - void Paint(PaintContext& context) const override; - - const MutatorsStack& parent_mutators() { return parent_mutators_; } - const SkMatrix& parent_matrix() { return parent_matrix_; } - const SkRect& parent_cull_rect() { return parent_cull_rect_; } - float parent_elevation() { return parent_elevation_; } - bool parent_has_platform_view() { return parent_has_platform_view_; } - - private: - MutatorsStack parent_mutators_; - SkMatrix parent_matrix_; - SkRect parent_cull_rect_ = SkRect::MakeEmpty(); - SkPath fake_paint_path_; - SkPaint fake_paint_; - float parent_elevation_ = 0; - bool parent_has_platform_view_ = false; - bool fake_has_platform_view_ = false; - bool fake_needs_system_composite_ = false; - - FML_DISALLOW_COPY_AND_ASSIGN(MockLayer); -}; - -} // namespace testing -} // namespace flutter - -#endif // FLOW_TESTING_MOCK_LAYER_H_ diff --git a/flow/testing/mock_layer_unittests.cc b/flow/testing/mock_layer_unittests.cc deleted file mode 100644 index ab2518edec108..0000000000000 --- a/flow/testing/mock_layer_unittests.cc +++ /dev/null @@ -1,85 +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/testing/mock_layer.h" - -#include "flutter/flow/testing/layer_test.h" -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" - -namespace flutter { -namespace testing { - -using MockLayerTest = LayerTest; - -TEST_F(MockLayerTest, PaintBeforePreroll) { - SkPath path = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f); - auto layer = std::make_shared(path, SkPaint()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(MockLayerTest, EmptyLayer) { - auto layer = std::make_shared(SkPath(), SkPaint()); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->paint_bounds(), SkPath().getBounds()); - - EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), - "needs_painting\\(\\)"); -} - -TEST_F(MockLayerTest, SimpleParams) { - const SkPath path = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f); - const SkPaint paint = SkPaint(SkColors::kBlue); - const SkMatrix start_matrix = SkMatrix::MakeTrans(1.0f, 2.0f); - const SkMatrix scale_matrix = SkMatrix::MakeScale(0.5f, 0.5f); - const SkRect cull_rect = SkRect::MakeWH(5.0f, 5.0f); - const float parent_elevation = 5.0f; - const bool parent_has_platform_view = true; - auto layer = std::make_shared(path, paint); - - preroll_context()->mutators_stack.PushTransform(scale_matrix); - preroll_context()->cull_rect = cull_rect; - preroll_context()->total_elevation = parent_elevation; - preroll_context()->has_platform_view = parent_has_platform_view; - layer->Preroll(preroll_context(), start_matrix); - EXPECT_EQ(preroll_context()->has_platform_view, false); - EXPECT_EQ(layer->paint_bounds(), path.getBounds()); - EXPECT_TRUE(layer->needs_painting()); - EXPECT_FALSE(layer->needs_system_composite()); - EXPECT_EQ(layer->parent_mutators(), std::vector{Mutator(scale_matrix)}); - EXPECT_EQ(layer->parent_matrix(), start_matrix); - EXPECT_EQ(layer->parent_cull_rect(), cull_rect); - EXPECT_EQ(layer->parent_elevation(), parent_elevation); - EXPECT_EQ(layer->parent_has_platform_view(), parent_has_platform_view); - - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{path, paint}}})); -} - -TEST_F(MockLayerTest, FakePlatformView) { - auto layer = std::make_shared(SkPath(), SkPaint(), - true /* fake_has_platform_view */); - EXPECT_EQ(preroll_context()->has_platform_view, false); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(preroll_context()->has_platform_view, true); -} - -TEST_F(MockLayerTest, FakeSystemComposite) { - auto layer = std::make_shared( - SkPath(), SkPaint(), false /* fake_has_platform_view */, - true /* fake_needs_system_composite */); - EXPECT_EQ(layer->needs_system_composite(), false); - - layer->Preroll(preroll_context(), SkMatrix()); - EXPECT_EQ(layer->needs_system_composite(), true); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/mock_texture.cc b/flow/testing/mock_texture.cc deleted file mode 100644 index 26e49b764cdaf..0000000000000 --- a/flow/testing/mock_texture.cc +++ /dev/null @@ -1,31 +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/testing/mock_texture.h" - -namespace flutter { -namespace testing { - -MockTexture::MockTexture(int64_t textureId) : Texture(textureId) {} - -void MockTexture::Paint(SkCanvas& canvas, - const SkRect& bounds, - bool freeze, - GrContext* context) { - paint_calls_.emplace_back(PaintCall{canvas, bounds, freeze, context}); -} - -bool operator==(const MockTexture::PaintCall& a, - const MockTexture::PaintCall& b) { - return &a.canvas == &b.canvas && a.bounds == b.bounds && - a.context == b.context && a.freeze == b.freeze; -} - -std::ostream& operator<<(std::ostream& os, const MockTexture::PaintCall& data) { - return os << &data.canvas << " " << data.bounds << " " << data.context << " " - << data.freeze; -} - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/mock_texture.h b/flow/testing/mock_texture.h deleted file mode 100644 index c5339ebb77a66..0000000000000 --- a/flow/testing/mock_texture.h +++ /dev/null @@ -1,57 +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/texture.h" -#include "flutter/testing/assertions_skia.h" - -#include -#include - -namespace flutter { -namespace testing { - -// Mock implementation of the |Texture| interface that does not interact with -// the GPU. It simply records the list of various calls made so the test can -// later verify them against expected data. -class MockTexture : public Texture { - public: - struct PaintCall { - SkCanvas& canvas; - SkRect bounds; - bool freeze; - GrContext* context; - }; - - explicit MockTexture(int64_t textureId); - - // Called from GPU thread. - void Paint(SkCanvas& canvas, - const SkRect& bounds, - bool freeze, - GrContext* context) override; - - void OnGrContextCreated() override { gr_context_created_ = true; } - void OnGrContextDestroyed() override { gr_context_destroyed_ = true; } - void MarkNewFrameAvailable() override {} - void OnTextureUnregistered() override { unregistered_ = true; } - - const std::vector& paint_calls() { return paint_calls_; } - bool gr_context_created() { return gr_context_created_; } - bool gr_context_destroyed() { return gr_context_destroyed_; } - bool unregistered() { return unregistered_; } - - private: - std::vector paint_calls_; - bool gr_context_created_ = false; - bool gr_context_destroyed_ = false; - bool unregistered_ = false; -}; - -extern bool operator==(const MockTexture::PaintCall& a, - const MockTexture::PaintCall& b); -extern std::ostream& operator<<(std::ostream& os, - const MockTexture::PaintCall& data); - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/mock_texture_unittests.cc b/flow/testing/mock_texture_unittests.cc deleted file mode 100644 index 107eb76307928..0000000000000 --- a/flow/testing/mock_texture_unittests.cc +++ /dev/null @@ -1,43 +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/testing/mock_texture.h" - -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -TEST(MockTextureTest, Callbacks) { - auto texture = std::make_shared(0); - - ASSERT_FALSE(texture->gr_context_created()); - texture->OnGrContextCreated(); - ASSERT_TRUE(texture->gr_context_created()); - - ASSERT_FALSE(texture->gr_context_destroyed()); - texture->OnGrContextDestroyed(); - ASSERT_TRUE(texture->gr_context_destroyed()); - - ASSERT_FALSE(texture->unregistered()); - texture->OnTextureUnregistered(); - ASSERT_TRUE(texture->unregistered()); -} - -TEST(MockTextureTest, PaintCalls) { - SkCanvas canvas; - const SkRect paint_bounds1 = SkRect::MakeWH(1.0f, 1.0f); - const SkRect paint_bounds2 = SkRect::MakeWH(2.0f, 2.0f); - const auto expected_paint_calls = - std::vector{MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr}, - MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr}}; - auto texture = std::make_shared(0); - - texture->Paint(canvas, paint_bounds1, false, nullptr); - texture->Paint(canvas, paint_bounds2, true, nullptr); - EXPECT_EQ(texture->paint_calls(), expected_paint_calls); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/skia_gpu_object_layer_test.cc b/flow/testing/skia_gpu_object_layer_test.cc deleted file mode 100644 index 1fca8ec8f3b81..0000000000000 --- a/flow/testing/skia_gpu_object_layer_test.cc +++ /dev/null @@ -1,18 +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/testing/skia_gpu_object_layer_test.h" - -#include "flutter/fml/time/time_delta.h" - -namespace flutter { -namespace testing { - -SkiaGPUObjectLayerTest::SkiaGPUObjectLayerTest() - : unref_queue_(fml::MakeRefCounted( - GetCurrentTaskRunner(), - fml::TimeDelta::FromSeconds(0))) {} - -} // namespace testing -} // namespace flutter diff --git a/flow/testing/skia_gpu_object_layer_test.h b/flow/testing/skia_gpu_object_layer_test.h deleted file mode 100644 index d573ac0b41007..0000000000000 --- a/flow/testing/skia_gpu_object_layer_test.h +++ /dev/null @@ -1,30 +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 FLOW_TESTING_SKIA_GPU_OBJECT_LAYER_TEST_H_ -#define FLOW_TESTING_SKIA_GPU_OBJECT_LAYER_TEST_H_ - -#include "flutter/flow/skia_gpu_object.h" -#include "flutter/flow/testing/layer_test.h" -#include "flutter/testing/thread_test.h" - -namespace flutter { -namespace testing { - -// This fixture allows generating tests that create |SkiaGPUObject|'s which -// are destroyed on a |SkiaUnrefQueue|. -class SkiaGPUObjectLayerTest : public LayerTestBase { - public: - SkiaGPUObjectLayerTest(); - - fml::RefPtr unref_queue() { return unref_queue_; } - - private: - fml::RefPtr unref_queue_; -}; - -} // namespace testing -} // namespace flutter - -#endif // FLOW_TESTING_SKIA_GPU_OBJECT_LAYER_TEST_H_ diff --git a/flow/texture.cc b/flow/texture.cc index 15c93d360366e..6f25c6df89593 100644 --- a/flow/texture.cc +++ b/flow/texture.cc @@ -6,12 +6,10 @@ namespace flutter { -Texture::Texture(int64_t id) : id_(id) {} - -Texture::~Texture() = default; - TextureRegistry::TextureRegistry() = default; +TextureRegistry::~TextureRegistry() = default; + void TextureRegistry::RegisterTexture(std::shared_ptr texture) { mapping_[texture->Id()] = texture; } @@ -38,4 +36,8 @@ std::shared_ptr TextureRegistry::GetTexture(int64_t id) { return it != mapping_.end() ? it->second : nullptr; } +Texture::Texture(int64_t id) : id_(id) {} + +Texture::~Texture() = default; + } // namespace flutter diff --git a/flow/texture.h b/flow/texture.h index 812588d382bb1..6e06445884b66 100644 --- a/flow/texture.h +++ b/flow/texture.h @@ -14,9 +14,12 @@ namespace flutter { class Texture { + protected: + Texture(int64_t id); + public: - Texture(int64_t id); // Called from UI or GPU thread. - virtual ~Texture(); // Called from GPU thread. + // Called from GPU thread. + virtual ~Texture(); // Called from GPU thread. virtual void Paint(SkCanvas& canvas, @@ -47,6 +50,7 @@ class Texture { class TextureRegistry { public: TextureRegistry(); + ~TextureRegistry(); // Called from GPU thread. void RegisterTexture(std::shared_ptr texture); diff --git a/flow/texture_unittests.cc b/flow/texture_unittests.cc index f3eb0fc0931ac..d292e3965af87 100644 --- a/flow/texture_unittests.cc +++ b/flow/texture_unittests.cc @@ -2,97 +2,44 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/flow/testing/mock_texture.h" #include "flutter/flow/texture.h" - #include "gtest/gtest.h" namespace flutter { namespace testing { -TEST(TextureRegistryTest, UnregisterTextureCallbackTriggered) { - TextureRegistry registry; - auto mock_texture1 = std::make_shared(0); - auto mock_texture2 = std::make_shared(1); - - registry.RegisterTexture(mock_texture1); - registry.RegisterTexture(mock_texture2); - ASSERT_EQ(registry.GetTexture(0), mock_texture1); - ASSERT_EQ(registry.GetTexture(1), mock_texture2); - ASSERT_FALSE(mock_texture1->unregistered()); - ASSERT_FALSE(mock_texture2->unregistered()); - - registry.UnregisterTexture(0); - ASSERT_EQ(registry.GetTexture(0), nullptr); - ASSERT_TRUE(mock_texture1->unregistered()); - ASSERT_FALSE(mock_texture2->unregistered()); - - registry.UnregisterTexture(1); - ASSERT_EQ(registry.GetTexture(1), nullptr); - ASSERT_TRUE(mock_texture1->unregistered()); - ASSERT_TRUE(mock_texture2->unregistered()); -} - -TEST(TextureRegistryTest, GrContextCallbackTriggered) { - TextureRegistry registry; - auto mock_texture1 = std::make_shared(0); - auto mock_texture2 = std::make_shared(1); - - registry.RegisterTexture(mock_texture1); - registry.RegisterTexture(mock_texture2); - ASSERT_FALSE(mock_texture1->gr_context_created()); - ASSERT_FALSE(mock_texture2->gr_context_created()); - ASSERT_FALSE(mock_texture1->gr_context_destroyed()); - ASSERT_FALSE(mock_texture2->gr_context_destroyed()); +class MockTexture : public Texture { + public: + MockTexture(int64_t textureId) : Texture(textureId) {} - registry.OnGrContextCreated(); - ASSERT_TRUE(mock_texture1->gr_context_created()); - ASSERT_TRUE(mock_texture2->gr_context_created()); + ~MockTexture() override = default; - registry.UnregisterTexture(0); - registry.OnGrContextDestroyed(); - ASSERT_FALSE(mock_texture1->gr_context_destroyed()); - ASSERT_TRUE(mock_texture2->gr_context_created()); -} + // Called from GPU thread. + void Paint(SkCanvas& canvas, + const SkRect& bounds, + bool freeze, + GrContext* context) override {} -TEST(TextureRegistryTest, RegisterTextureTwice) { - TextureRegistry registry; - auto mock_texture1 = std::make_shared(0); - auto mock_texture2 = std::make_shared(0); + void OnGrContextCreated() override {} - registry.RegisterTexture(mock_texture1); - ASSERT_EQ(registry.GetTexture(0), mock_texture1); - registry.RegisterTexture(mock_texture2); - ASSERT_EQ(registry.GetTexture(0), mock_texture2); - ASSERT_FALSE(mock_texture1->unregistered()); - ASSERT_FALSE(mock_texture2->unregistered()); - - registry.UnregisterTexture(0); - ASSERT_EQ(registry.GetTexture(0), nullptr); - ASSERT_FALSE(mock_texture1->unregistered()); - ASSERT_TRUE(mock_texture2->unregistered()); -} + void OnGrContextDestroyed() override {} -TEST(TextureRegistryTest, ReuseSameTextureSlot) { - TextureRegistry registry; - auto mock_texture1 = std::make_shared(0); - auto mock_texture2 = std::make_shared(0); + void MarkNewFrameAvailable() override {} - registry.RegisterTexture(mock_texture1); - ASSERT_EQ(registry.GetTexture(0), mock_texture1); + void OnTextureUnregistered() override { unregistered_ = true; } - registry.UnregisterTexture(0); - ASSERT_EQ(registry.GetTexture(0), nullptr); - ASSERT_TRUE(mock_texture1->unregistered()); - ASSERT_FALSE(mock_texture2->unregistered()); + bool unregistered() { return unregistered_; } - registry.RegisterTexture(mock_texture2); - ASSERT_EQ(registry.GetTexture(0), mock_texture2); + private: + bool unregistered_ = false; +}; - registry.UnregisterTexture(0); - ASSERT_EQ(registry.GetTexture(0), nullptr); - ASSERT_TRUE(mock_texture1->unregistered()); - ASSERT_TRUE(mock_texture2->unregistered()); +TEST(TextureRegistry, UnregisterTextureCallbackTriggered) { + TextureRegistry textureRegistry; + std::shared_ptr mockTexture = std::make_shared(0); + textureRegistry.RegisterTexture(mockTexture); + textureRegistry.UnregisterTexture(0); + ASSERT_TRUE(mockTexture->unregistered()); } } // namespace testing diff --git a/fml/BUILD.gn b/fml/BUILD.gn index 94c22c5d9a673..408942435ab83 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -2,11 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/fuchsia/sdk.gni") +import("$flutter_root/testing/testing.gni") + if (is_fuchsia) { - import("//build/fuchsia/sdk.gni") import("$flutter_root/tools/fuchsia/fuchsia_archive.gni") } -import("$flutter_root/testing/testing.gni") source_set("fml") { sources = [ diff --git a/runtime/runtime_test.cc b/runtime/runtime_test.cc index 295d3daf2bc0e..455a52c95a67a 100644 --- a/runtime/runtime_test.cc +++ b/runtime/runtime_test.cc @@ -11,10 +11,9 @@ namespace flutter { namespace testing { RuntimeTest::RuntimeTest() - : native_resolver_(std::make_shared()), - assets_dir_(fml::OpenDirectory(GetFixturesPath(), - false, - fml::FilePermission::kRead)) {} + : native_resolver_(std::make_shared()) {} + +RuntimeTest::~RuntimeTest() = default; void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) { if (!assets_dir_.is_valid()) { @@ -68,6 +67,19 @@ Settings RuntimeTest::CreateSettingsForFixture() { return settings; } +// |testing::ThreadTest| +void RuntimeTest::SetUp() { + assets_dir_ = + fml::OpenDirectory(GetFixturesPath(), false, fml::FilePermission::kRead); + ThreadTest::SetUp(); +} + +// |testing::ThreadTest| +void RuntimeTest::TearDown() { + ThreadTest::TearDown(); + assets_dir_.reset(); +} + void RuntimeTest::AddNativeCallback(std::string name, Dart_NativeFunction callback) { native_resolver_->AddNativeCallback(std::move(name), callback); diff --git a/runtime/runtime_test.h b/runtime/runtime_test.h index abce2e94970f9..8c60a6e858a6c 100644 --- a/runtime/runtime_test.h +++ b/runtime/runtime_test.h @@ -19,17 +19,24 @@ class RuntimeTest : public ThreadTest { public: RuntimeTest(); + ~RuntimeTest(); + Settings CreateSettingsForFixture(); void AddNativeCallback(std::string name, Dart_NativeFunction callback); - private: - void SetSnapshotsAndAssets(Settings& settings); + protected: + // |testing::ThreadTest| + void SetUp() override; - std::shared_ptr native_resolver_; + // |testing::ThreadTest| + void TearDown() override; + + private: fml::UniqueFD assets_dir_; + std::shared_ptr native_resolver_; - FML_DISALLOW_COPY_AND_ASSIGN(RuntimeTest); + void SetSnapshotsAndAssets(Settings& settings); }; } // namespace testing diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index fa25b0d7933cf..11fdd3f6ee6ad 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -297,8 +297,7 @@ RasterStatus Rasterizer::DoDraw( RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { FML_DCHECK(surface_); - auto frame = surface_->AcquireFrame(layer_tree.frame_size(), - layer_tree.root_needs_screen_readback()); + auto frame = surface_->AcquireFrame(layer_tree.frame_size()); if (frame == nullptr) { return RasterStatus::kFailed; diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 97a382dcacbbd..ed7f1febaf51c 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -19,13 +19,9 @@ namespace flutter { namespace testing { ShellTest::ShellTest() - : native_resolver_(std::make_shared()), - thread_host_("io.flutter.test." + GetCurrentTestName() + ".", - ThreadHost::Type::Platform | ThreadHost::Type::IO | - ThreadHost::Type::UI | ThreadHost::Type::GPU), - assets_dir_(fml::OpenDirectory(GetFixturesPath(), - false, - fml::FilePermission::kRead)) {} + : native_resolver_(std::make_shared()) {} + +ShellTest::~ShellTest() = default; void ShellTest::SendEnginePlatformMessage( Shell* shell, @@ -229,10 +225,10 @@ Settings ShellTest::CreateSettingsForFixture() { TaskRunners ShellTest::GetTaskRunnersForFixture() { return { "test", - thread_host_.platform_thread->GetTaskRunner(), // platform - thread_host_.gpu_thread->GetTaskRunner(), // gpu - thread_host_.ui_thread->GetTaskRunner(), // ui - thread_host_.io_thread->GetTaskRunner() // io + thread_host_->platform_thread->GetTaskRunner(), // platform + thread_host_->gpu_thread->GetTaskRunner(), // gpu + thread_host_->ui_thread->GetTaskRunner(), // ui + thread_host_->io_thread->GetTaskRunner() // io }; } @@ -271,6 +267,24 @@ void ShellTest::DestroyShell(std::unique_ptr shell, latch.Wait(); } +// |testing::ThreadTest| +void ShellTest::SetUp() { + ThreadTest::SetUp(); + assets_dir_ = + fml::OpenDirectory(GetFixturesPath(), false, fml::FilePermission::kRead); + thread_host_ = std::make_unique( + "io.flutter.test." + GetCurrentTestName() + ".", + ThreadHost::Type::Platform | ThreadHost::Type::IO | ThreadHost::Type::UI | + ThreadHost::Type::GPU); +} + +// |testing::ThreadTest| +void ShellTest::TearDown() { + ThreadTest::TearDown(); + assets_dir_.reset(); + thread_host_.reset(); +} + void ShellTest::AddNativeCallback(std::string name, Dart_NativeFunction callback) { native_resolver_->AddNativeCallback(std::move(name), callback); diff --git a/shell/common/shell_test.h b/shell/common/shell_test.h index 0ae092a1c91bf..270ea812dbf8a 100644 --- a/shell/common/shell_test.h +++ b/shell/common/shell_test.h @@ -26,6 +26,8 @@ class ShellTest : public ThreadTest { public: ShellTest(); + ~ShellTest(); + Settings CreateSettingsForFixture(); std::unique_ptr CreateShell(Settings settings, bool simulate_vsync = false); @@ -76,14 +78,19 @@ class ShellTest : public ThreadTest { // is unpredictive. static int UnreportedTimingsCount(Shell* shell); - private: - void SetSnapshotsAndAssets(Settings& settings); + protected: + // |testing::ThreadTest| + void SetUp() override; - std::shared_ptr native_resolver_; - ThreadHost thread_host_; + // |testing::ThreadTest| + void TearDown() override; + + private: fml::UniqueFD assets_dir_; + std::shared_ptr native_resolver_; + std::unique_ptr thread_host_; - FML_DISALLOW_COPY_AND_ASSIGN(ShellTest); + void SetSnapshotsAndAssets(Settings& settings); }; class ShellTestVsyncClock { diff --git a/shell/common/surface.h b/shell/common/surface.h index 661f21f04cb05..14f898fad3fe1 100644 --- a/shell/common/surface.h +++ b/shell/common/surface.h @@ -50,9 +50,7 @@ class Surface { virtual bool IsValid() = 0; - virtual std::unique_ptr AcquireFrame( - const SkISize& size, - const bool needs_readback) = 0; + virtual std::unique_ptr AcquireFrame(const SkISize& size) = 0; virtual SkMatrix GetRootTransformation() const = 0; diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc index ac81687f84037..5f30a48375d33 100644 --- a/shell/gpu/gpu_surface_gl.cc +++ b/shell/gpu/gpu_surface_gl.cc @@ -193,17 +193,12 @@ static sk_sp CreateOffscreenSurface(GrContext* context, &surface_props); } -bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size, - const bool needs_readback) { - bool needs_offscreen = delegate_->UseOffscreenSurface(needs_readback); +bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size) { if (onscreen_surface_ != nullptr && size == SkISize::Make(onscreen_surface_->width(), onscreen_surface_->height())) { // Surface size appears unchanged. So bail. - bool has_offscreen = offscreen_surface_ != nullptr; - if (needs_offscreen == has_offscreen) { - return true; - } + return true; } // We need to do some updates. @@ -233,7 +228,7 @@ bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size, return false; } - if (needs_offscreen) { + if (delegate_->UseOffscreenSurface()) { offscreen_surface = CreateOffscreenSurface(context_.get(), size); if (offscreen_surface == nullptr) { FML_LOG(ERROR) << "Could not create offscreen surface."; @@ -253,9 +248,7 @@ SkMatrix GPUSurfaceGL::GetRootTransformation() const { } // |Surface| -std::unique_ptr GPUSurfaceGL::AcquireFrame( - const SkISize& size, - const bool needs_readback) { +std::unique_ptr GPUSurfaceGL::AcquireFrame(const SkISize& size) { if (delegate_ == nullptr) { return nullptr; } @@ -278,7 +271,7 @@ std::unique_ptr GPUSurfaceGL::AcquireFrame( const auto root_surface_transformation = GetRootTransformation(); sk_sp surface = - AcquireRenderSurface(size, root_surface_transformation, needs_readback); + AcquireRenderSurface(size, root_surface_transformation); if (surface == nullptr) { return nullptr; @@ -342,15 +335,14 @@ bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) { sk_sp GPUSurfaceGL::AcquireRenderSurface( const SkISize& untransformed_size, - const SkMatrix& root_surface_transformation, - const bool needs_readback) { + const SkMatrix& root_surface_transformation) { const auto transformed_rect = root_surface_transformation.mapRect( SkRect::MakeWH(untransformed_size.width(), untransformed_size.height())); const auto transformed_size = SkISize::Make(transformed_rect.width(), transformed_rect.height()); - if (!CreateOrUpdateSurfaces(transformed_size, needs_readback)) { + if (!CreateOrUpdateSurfaces(transformed_size)) { return nullptr; } diff --git a/shell/gpu/gpu_surface_gl.h b/shell/gpu/gpu_surface_gl.h index b7a26e1a057b7..97325569bfd16 100644 --- a/shell/gpu/gpu_surface_gl.h +++ b/shell/gpu/gpu_surface_gl.h @@ -32,9 +32,7 @@ class GPUSurfaceGL : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame( - const SkISize& size, - const bool needs_readback) override; + std::unique_ptr AcquireFrame(const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; @@ -62,12 +60,11 @@ class GPUSurfaceGL : public Surface { bool valid_ = false; fml::WeakPtrFactory weak_factory_; - bool CreateOrUpdateSurfaces(const SkISize& size, const bool needs_readback); + bool CreateOrUpdateSurfaces(const SkISize& size); sk_sp AcquireRenderSurface( const SkISize& untransformed_size, - const SkMatrix& root_surface_transformation, - const bool needs_readback); + const SkMatrix& root_surface_transformation); bool PresentSurface(SkCanvas* canvas); diff --git a/shell/gpu/gpu_surface_gl_delegate.cc b/shell/gpu/gpu_surface_gl_delegate.cc index 89c660688b3cc..1ef969fe8acc5 100644 --- a/shell/gpu/gpu_surface_gl_delegate.cc +++ b/shell/gpu/gpu_surface_gl_delegate.cc @@ -12,8 +12,7 @@ bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const { return false; } -bool GPUSurfaceGLDelegate::UseOffscreenSurface( - const bool needs_readback) const { +bool GPUSurfaceGLDelegate::UseOffscreenSurface() const { return false; } diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 7a222c3567909..dfe0ce7f468db 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -36,10 +36,8 @@ class GPUSurfaceGLDelegate : public GPUSurfaceDelegate { // subsequent frames. virtual bool GLContextFBOResetAfterPresent() const; - // Create an offscreen surface to render into before onscreen composition - // based on whether or not the frame will perform any operations that will - // require readback from the rendering target. - virtual bool UseOffscreenSurface(const bool needs_readback) const; + // Create an offscreen surface to render into before onscreen composition. + virtual bool UseOffscreenSurface() const; // A transformation applied to the onscreen surface before the canvas is // flushed. diff --git a/shell/gpu/gpu_surface_metal.h b/shell/gpu/gpu_surface_metal.h index 30f8fe2fa35e1..fc6b0964766ce 100644 --- a/shell/gpu/gpu_surface_metal.h +++ b/shell/gpu/gpu_surface_metal.h @@ -37,8 +37,7 @@ class GPUSurfaceMetal : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size, - const bool needs_readback) override; + std::unique_ptr AcquireFrame(const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_metal.mm b/shell/gpu/gpu_surface_metal.mm index bc71337dcb94f..81abf740d48f6 100644 --- a/shell/gpu/gpu_surface_metal.mm +++ b/shell/gpu/gpu_surface_metal.mm @@ -83,8 +83,7 @@ } // |Surface| -std::unique_ptr GPUSurfaceMetal::AcquireFrame(const SkISize& size, - const bool needs_readback) { +std::unique_ptr GPUSurfaceMetal::AcquireFrame(const SkISize& size) { if (!IsValid()) { FML_LOG(ERROR) << "Metal surface was invalid."; return nullptr; diff --git a/shell/gpu/gpu_surface_software.cc b/shell/gpu/gpu_surface_software.cc index 7bec87eed1948..346857ac47e6a 100644 --- a/shell/gpu/gpu_surface_software.cc +++ b/shell/gpu/gpu_surface_software.cc @@ -24,8 +24,7 @@ bool GPUSurfaceSoftware::IsValid() { // |Surface| std::unique_ptr GPUSurfaceSoftware::AcquireFrame( - const SkISize& logical_size, - const bool needs_readback) { + const SkISize& logical_size) { // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. if (!render_to_surface_) { diff --git a/shell/gpu/gpu_surface_software.h b/shell/gpu/gpu_surface_software.h index 66b8b90500463..af4d1cb3c107f 100644 --- a/shell/gpu/gpu_surface_software.h +++ b/shell/gpu/gpu_surface_software.h @@ -23,9 +23,7 @@ class GPUSurfaceSoftware : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame( - const SkISize& size, - const bool needs_readback) override; + std::unique_ptr AcquireFrame(const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index 7a494849bdfcf..fbc9696b15d52 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -22,8 +22,7 @@ bool GPUSurfaceVulkan::IsValid() { // |Surface| std::unique_ptr GPUSurfaceVulkan::AcquireFrame( - const SkISize& size, - const bool needs_readback) { + const SkISize& size) { auto surface = window_.AcquireSurface(); if (surface == nullptr) { diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 58c805936017e..7c410dd526cf7 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -26,9 +26,7 @@ class GPUSurfaceVulkan : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame( - const SkISize& size, - const bool needs_readback) override; + std::unique_ptr AcquireFrame(const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 4837ef22f4a42..33ca14d9fabea 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -369,7 +369,7 @@ bool did_submit = true; for (int64_t view_id : composition_order_) { EnsureOverlayInitialized(view_id, gl_context, gr_context); - auto frame = overlays_[view_id]->surface->AcquireFrame(frame_size_, true); + auto frame = overlays_[view_id]->surface->AcquireFrame(frame_size_); SkCanvas* canvas = frame->SkiaCanvas(); canvas->drawPicture(picture_recorders_[view_id]->finishRecordingAsPicture()); canvas->flush(); diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h index 73148f34ce9ed..c1019bb442bb0 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.h +++ b/shell/platform/darwin/ios/ios_surface_gl.h @@ -48,7 +48,7 @@ class IOSSurfaceGL final : public IOSSurface, intptr_t GLContextFBO() const override; - bool UseOffscreenSurface(const bool needs_readback) const override; + bool UseOffscreenSurface() const override; // |GPUSurfaceGLDelegate| ExternalViewEmbedder* GetExternalViewEmbedder() override; diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index 1130375758831..48e70e00a4e7a 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -49,12 +49,11 @@ return IsValid() ? render_target_->framebuffer() : GL_NONE; } -bool IOSSurfaceGL::UseOffscreenSurface(const bool needs_readback) const { +bool IOSSurfaceGL::UseOffscreenSurface() const { // The onscreen surface wraps a GL renderbuffer, which is extremely slow to read. // Certain filter effects require making a copy of the current destination, so we - // render to an offscreen surface, which will be much quicker to read/copy, if - // they are present. - return needs_readback; + // always render to an offscreen surface, which will be much quicker to read/copy. + return true; } bool IOSSurfaceGL::GLContextMakeCurrent() { diff --git a/shell/platform/embedder/tests/embedder_test.cc b/shell/platform/embedder/tests/embedder_test.cc index bca2e0eb5f258..cc699c26e463a 100644 --- a/shell/platform/embedder/tests/embedder_test.cc +++ b/shell/platform/embedder/tests/embedder_test.cc @@ -9,12 +9,14 @@ namespace testing { EmbedderTest::EmbedderTest() = default; +EmbedderTest::~EmbedderTest() = default; + std::string EmbedderTest::GetFixturesDirectory() const { return GetFixturesPath(); } EmbedderTestContext& EmbedderTest::GetEmbedderContext() { - // Setup the embedder context lazily instead of in the constructor because we + // Setup the embedder context lazily instead of in the SetUp method because we // don't to do all the work if the test won't end up using context. if (!embedder_context_) { embedder_context_ = @@ -23,5 +25,16 @@ EmbedderTestContext& EmbedderTest::GetEmbedderContext() { return *embedder_context_; } +// |testing::Test| +void EmbedderTest::SetUp() { + ThreadTest::SetUp(); +} + +// |testing::Test| +void EmbedderTest::TearDown() { + embedder_context_.reset(); + ThreadTest::TearDown(); +} + } // namespace testing } // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_test.h b/shell/platform/embedder/tests/embedder_test.h index 15cc101ae24a6..f170a106553dc 100644 --- a/shell/platform/embedder/tests/embedder_test.h +++ b/shell/platform/embedder/tests/embedder_test.h @@ -19,6 +19,8 @@ class EmbedderTest : public ThreadTest { public: EmbedderTest(); + ~EmbedderTest() override; + std::string GetFixturesDirectory() const; EmbedderTestContext& GetEmbedderContext(); @@ -26,6 +28,12 @@ class EmbedderTest : public ThreadTest { private: std::unique_ptr embedder_context_; + // |testing::Test| + void SetUp() override; + + // |testing::Test| + void TearDown() override; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTest); }; diff --git a/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx b/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx index 244761694a8dc..bdfec3cd2e4d0 100644 --- a/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx +++ b/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx @@ -16,7 +16,6 @@ "fuchsia.feedback.CrashReporter", "fuchsia.fonts.Provider", "fuchsia.intl.PropertyProvider", - "fuchsia.logger.LogSink", "fuchsia.net.NameLookup", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", diff --git a/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx b/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx index 1119b279ddd6c..912b534df93a2 100644 --- a/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx +++ b/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx @@ -16,7 +16,6 @@ "fuchsia.feedback.CrashReporter", "fuchsia.fonts.Provider", "fuchsia.intl.PropertyProvider", - "fuchsia.logger.LogSink", "fuchsia.net.NameLookup", "fuchsia.netstack.Netstack", "fuchsia.posix.socket.Provider", diff --git a/shell/platform/fuchsia/flutter/surface.cc b/shell/platform/fuchsia/flutter/surface.cc index 1fda6a50f54d5..29fbbc7294cc1 100644 --- a/shell/platform/fuchsia/flutter/surface.cc +++ b/shell/platform/fuchsia/flutter/surface.cc @@ -24,8 +24,7 @@ bool Surface::IsValid() { // |flutter::Surface| std::unique_ptr Surface::AcquireFrame( - const SkISize& size, - const bool needs_readback) { + const SkISize& size) { return std::make_unique( nullptr, [](const flutter::SurfaceFrame& surface_frame, SkCanvas* canvas) { return true; }); diff --git a/shell/platform/fuchsia/flutter/surface.h b/shell/platform/fuchsia/flutter/surface.h index 87d6d09320c08..66220f079b3e5 100644 --- a/shell/platform/fuchsia/flutter/surface.h +++ b/shell/platform/fuchsia/flutter/surface.h @@ -29,8 +29,7 @@ class Surface final : public flutter::Surface { // |flutter::Surface| std::unique_ptr AcquireFrame( - const SkISize& size, - const bool needs_readback) override; + const SkISize& size) override; // |flutter::Surface| GrContext* GetContext() override; diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 8bf9d7bc3922f..a1028b0f18952 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -54,11 +54,7 @@ source_set("skia") { testonly = true sources = [ - "$flutter_root/testing/assertions_skia.cc", "$flutter_root/testing/assertions_skia.h", - "$flutter_root/testing/canvas_test.h", - "$flutter_root/testing/mock_canvas.cc", - "$flutter_root/testing/mock_canvas.h", ] public_deps = [ @@ -122,8 +118,7 @@ if (current_toolchain == host_toolchain) { testonly = true sources = [ - "mock_canvas_unittests.cc", - "test_metal_surface_unittests.cc", + "$flutter_root/testing/test_metal_surface_unittests.cc", ] deps = [ diff --git a/testing/assertions_skia.cc b/testing/assertions_skia.cc deleted file mode 100644 index e8b7ce992b8a8..0000000000000 --- a/testing/assertions_skia.cc +++ /dev/null @@ -1,118 +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/testing/assertions_skia.h" - -namespace flutter { -namespace testing { - -std::ostream& operator<<(std::ostream& os, const SkClipOp& o) { - switch (o) { - case SkClipOp::kDifference: - os << "ClipOpDifference"; - break; - case SkClipOp::kIntersect: - os << "ClipOpIntersect"; - break; -#ifdef SK_SUPPORT_DEPRECATED_CLIPOPS - case SkClipOp::kUnion_deprecated: - os << "ClipOpUnion_deprecated"; - break; - case SkClipOp::kXOR_deprecated: - os << "ClipOpXOR_deprecated"; - break; - case SkClipOp::kReverseDifference_deprecated: - os << "ClipOpReverseDifference_deprecated"; - break; - case SkClipOp::kReplace_deprecated: - os << "ClipOpReplace_deprectaed"; - break; -#else - case SkClipOp::kExtraEnumNeedInternallyPleaseIgnoreWillGoAway2: - os << "ClipOpReserved2"; - break; - case SkClipOp::kExtraEnumNeedInternallyPleaseIgnoreWillGoAway3: - os << "ClipOpReserved3"; - break; - case SkClipOp::kExtraEnumNeedInternallyPleaseIgnoreWillGoAway4: - os << "ClipOpReserved4"; - break; - case SkClipOp::kExtraEnumNeedInternallyPleaseIgnoreWillGoAway5: - os << "ClipOpReserved5"; - break; -#endif - } - return os; -} - -std::ostream& operator<<(std::ostream& os, const SkMatrix& m) { - os << std::endl; - os << "Scale X: " << m[SkMatrix::kMScaleX] << ", "; - os << "Skew X: " << m[SkMatrix::kMSkewX] << ", "; - os << "Trans X: " << m[SkMatrix::kMTransX] << std::endl; - os << "Skew Y: " << m[SkMatrix::kMSkewY] << ", "; - os << "Scale Y: " << m[SkMatrix::kMScaleY] << ", "; - os << "Trans Y: " << m[SkMatrix::kMTransY] << std::endl; - os << "Persp X: " << m[SkMatrix::kMPersp0] << ", "; - os << "Persp Y: " << m[SkMatrix::kMPersp1] << ", "; - os << "Persp Z: " << m[SkMatrix::kMPersp2]; - os << std::endl; - return os; -} - -std::ostream& operator<<(std::ostream& os, const SkMatrix44& m) { - os << m.get(0, 0) << ", " << m.get(0, 1) << ", " << m.get(0, 2) << ", " - << m.get(0, 3) << std::endl; - os << m.get(1, 0) << ", " << m.get(1, 1) << ", " << m.get(1, 2) << ", " - << m.get(1, 3) << std::endl; - os << m.get(2, 0) << ", " << m.get(2, 1) << ", " << m.get(2, 2) << ", " - << m.get(2, 3) << std::endl; - os << m.get(3, 0) << ", " << m.get(3, 1) << ", " << m.get(3, 2) << ", " - << m.get(3, 3); - return os; -} - -std::ostream& operator<<(std::ostream& os, const SkVector3& v) { - return os << v.x() << ", " << v.y() << ", " << v.z(); -} - -std::ostream& operator<<(std::ostream& os, const SkVector4& v) { - return os << v.fData[0] << ", " << v.fData[1] << ", " << v.fData[2] << ", " - << v.fData[3]; -} - -std::ostream& operator<<(std::ostream& os, const SkRect& r) { - return os << "LTRB: " << r.fLeft << ", " << r.fTop << ", " << r.fRight << ", " - << r.fBottom; -} - -std::ostream& operator<<(std::ostream& os, const SkRRect& r) { - return os << "LTRB: " << r.rect().fLeft << ", " << r.rect().fTop << ", " - << r.rect().fRight << ", " << r.rect().fBottom; -} - -std::ostream& operator<<(std::ostream& os, const SkPath& r) { - return os << "Valid: " << r.isValid() << ", FillType: " << r.getFillType() - << ", Bounds: " << r.getBounds(); -} - -std::ostream& operator<<(std::ostream& os, const SkPoint& r) { - return os << "XY: " << r.fX << ", " << r.fY; -} - -std::ostream& operator<<(std::ostream& os, const SkISize& size) { - return os << size.width() << ", " << size.height(); -} - -std::ostream& operator<<(std::ostream& os, const SkColor4f& r) { - return os << r.fR << ", " << r.fG << ", " << r.fB << ", " << r.fA; -} - -std::ostream& operator<<(std::ostream& os, const SkPaint& r) { - return os << "Color: " << r.getColor4f() << ", Style: " << r.getStyle() - << ", AA: " << r.isAntiAlias() << ", Shader: " << r.getShader(); -} - -} // namespace testing -} // namespace flutter diff --git a/testing/assertions_skia.h b/testing/assertions_skia.h index f1eec1897c426..2b501189a23ae 100644 --- a/testing/assertions_skia.h +++ b/testing/assertions_skia.h @@ -7,31 +7,73 @@ #include -#include "third_party/skia/include/core/SkClipOp.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkMatrix44.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPoint3.h" #include "third_party/skia/include/core/SkRRect.h" -namespace flutter { -namespace testing { - -extern std::ostream& operator<<(std::ostream& os, const SkClipOp& o); -extern std::ostream& operator<<(std::ostream& os, const SkMatrix& m); -extern std::ostream& operator<<(std::ostream& os, const SkMatrix44& m); -extern std::ostream& operator<<(std::ostream& os, const SkVector3& v); -extern std::ostream& operator<<(std::ostream& os, const SkVector4& v); -extern std::ostream& operator<<(std::ostream& os, const SkRect& r); -extern std::ostream& operator<<(std::ostream& os, const SkRRect& r); -extern std::ostream& operator<<(std::ostream& os, const SkPath& r); -extern std::ostream& operator<<(std::ostream& os, const SkPoint& r); -extern std::ostream& operator<<(std::ostream& os, const SkISize& size); -extern std::ostream& operator<<(std::ostream& os, const SkColor4f& r); -extern std::ostream& operator<<(std::ostream& os, const SkPaint& r); - -} // namespace testing -} // namespace flutter +//------------------------------------------------------------------------------ +// Printing +//------------------------------------------------------------------------------ + +inline std::ostream& operator<<(std::ostream& os, const SkMatrix& m) { + os << std::endl; + os << "Scale X: " << m[SkMatrix::kMScaleX] << ", "; + os << "Skew X: " << m[SkMatrix::kMSkewX] << ", "; + os << "Trans X: " << m[SkMatrix::kMTransX] << std::endl; + os << "Skew Y: " << m[SkMatrix::kMSkewY] << ", "; + os << "Scale Y: " << m[SkMatrix::kMScaleY] << ", "; + os << "Trans Y: " << m[SkMatrix::kMTransY] << std::endl; + os << "Persp X: " << m[SkMatrix::kMPersp0] << ", "; + os << "Persp Y: " << m[SkMatrix::kMPersp1] << ", "; + os << "Persp Z: " << m[SkMatrix::kMPersp2]; + os << std::endl; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkMatrix44& m) { + os << m.get(0, 0) << ", " << m.get(0, 1) << ", " << m.get(0, 2) << ", " + << m.get(0, 3) << std::endl; + os << m.get(1, 0) << ", " << m.get(1, 1) << ", " << m.get(1, 2) << ", " + << m.get(1, 3) << std::endl; + os << m.get(2, 0) << ", " << m.get(2, 1) << ", " << m.get(2, 2) << ", " + << m.get(2, 3) << std::endl; + os << m.get(3, 0) << ", " << m.get(3, 1) << ", " << m.get(3, 2) << ", " + << m.get(3, 3); + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkVector3& v) { + os << v.x() << ", " << v.y() << ", " << v.z(); + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkVector4& v) { + os << v.fData[0] << ", " << v.fData[1] << ", " << v.fData[2] << ", " + << v.fData[3]; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkRect& r) { + os << "LTRB: " << r.fLeft << ", " << r.fTop << ", " << r.fRight << ", " + << r.fBottom; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkRRect& r) { + os << "LTRB: " << r.rect().fLeft << ", " << r.rect().fTop << ", " + << r.rect().fRight << ", " << r.rect().fBottom; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkPoint& r) { + os << "XY: " << r.fX << ", " << r.fY; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const SkISize& size) { + os << size.width() << ", " << size.height(); + return os; +} #endif // FLUTTER_TESTING_ASSERTIONS_SKIA_H_ diff --git a/testing/canvas_test.h b/testing/canvas_test.h deleted file mode 100644 index 80c157a305dc4..0000000000000 --- a/testing/canvas_test.h +++ /dev/null @@ -1,33 +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 TESTING_CANVAS_TEST_H_ -#define TESTING_CANVAS_TEST_H_ - -#include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -// This fixture allows creating tests that make use of a mock |SkCanvas|. -template -class CanvasTestBase : public BaseT { - public: - CanvasTestBase() = default; - - MockCanvas& mock_canvas() { return canvas_; } - - private: - MockCanvas canvas_; - - FML_DISALLOW_COPY_AND_ASSIGN(CanvasTestBase); -}; -using CanvasTest = CanvasTestBase<::testing::Test>; - -} // namespace testing -} // namespace flutter - -#endif // TESTING_CANVAS_TEST_H_ diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc deleted file mode 100644 index 6782ffdeda733..0000000000000 --- a/testing/mock_canvas.cc +++ /dev/null @@ -1,457 +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/testing/mock_canvas.h" - -#include "flutter/fml/logging.h" -#include "third_party/skia/include/core/SkImageInfo.h" -#include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/core/SkSerialProcs.h" -#include "third_party/skia/include/core/SkSize.h" -#include "third_party/skia/include/core/SkTextBlob.h" - -namespace flutter { -namespace testing { - -constexpr SkISize kSize = SkISize::Make(64, 64); - -MockCanvas::MockCanvas() - : SkCanvasVirtualEnforcer(kSize.fWidth, kSize.fHeight), - internal_canvas_(imageInfo().width(), imageInfo().height()), - current_layer_(0) { - internal_canvas_.addCanvas(this); -} - -MockCanvas::~MockCanvas() { - EXPECT_EQ(current_layer_, 0); -} - -void MockCanvas::willSave() { - draw_calls_.emplace_back( - DrawCall{current_layer_, SaveData{current_layer_ + 1}}); - current_layer_++; // Must go here; func params order of eval is undefined -} - -SkCanvas::SaveLayerStrategy MockCanvas::getSaveLayerStrategy( - const SaveLayerRec& rec) { - // saveLayer calls this prior to running, so we use it to track saveLayer - // calls - draw_calls_.emplace_back(DrawCall{ - current_layer_, - SaveLayerData{rec.fBounds ? *rec.fBounds : SkRect(), - rec.fPaint ? *rec.fPaint : SkPaint(), - rec.fBackdrop ? sk_ref_sp(rec.fBackdrop) - : sk_sp(), - current_layer_ + 1}}); - current_layer_++; // Must go here; func params order of eval is undefined - return kNoLayer_SaveLayerStrategy; -} - -void MockCanvas::willRestore() { - FML_DCHECK(current_layer_ > 0); - - draw_calls_.emplace_back( - DrawCall{current_layer_, RestoreData{current_layer_ - 1}}); - current_layer_--; // Must go here; func params order of eval is undefined -} - -void MockCanvas::didConcat(const SkMatrix& matrix) { - draw_calls_.emplace_back(DrawCall{current_layer_, ConcatMatrixData{matrix}}); -} - -void MockCanvas::didSetMatrix(const SkMatrix& matrix) { - draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{matrix}}); -} - -void MockCanvas::onDrawTextBlob(const SkTextBlob* text, - SkScalar x, - SkScalar y, - const SkPaint& paint) { - // This duplicates existing logic in SkCanvas::onDrawPicture - // that should probably be split out so it doesn't need to be here as well. - SkRect storage; - const SkRect* bounds = nullptr; - if (paint.canComputeFastBounds()) { - storage = text->bounds().makeOffset(x, y); - SkRect tmp; - if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { - return; - } - bounds = &storage; - } - - draw_calls_.emplace_back(DrawCall{ - current_layer_, DrawTextData{text ? text->serialize(SkSerialProcs{}) - : SkData::MakeUninitialized(0), - paint, SkPoint::Make(x, y)}}); -} - -void MockCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { - draw_calls_.emplace_back(DrawCall{current_layer_, DrawRectData{rect, paint}}); -} - -void MockCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { - draw_calls_.emplace_back(DrawCall{current_layer_, DrawPathData{path, paint}}); -} - -void MockCanvas::onDrawShadowRec(const SkPath& path, - const SkDrawShadowRec& rec) { - (void)rec; // Can't use b/c Skia keeps this type anonymous. - draw_calls_.emplace_back(DrawCall{current_layer_, DrawShadowData{path}}); -} - -void MockCanvas::onDrawPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint) { - // This duplicates existing logic in SkCanvas::onDrawPicture - // that should probably be split out so it doesn't need to be here as well. - if (!paint || paint->canComputeFastBounds()) { - SkRect bounds = picture->cullRect(); - if (paint) { - paint->computeFastBounds(bounds, &bounds); - } - if (matrix) { - matrix->mapRect(&bounds); - } - if (this->quickReject(bounds)) { - return; - } - } - - draw_calls_.emplace_back(DrawCall{ - current_layer_, - DrawPictureData{ - picture ? picture->serialize() : SkData::MakeUninitialized(0), - paint ? *paint : SkPaint(), matrix ? *matrix : SkMatrix()}}); -} - -void MockCanvas::onClipRect(const SkRect& rect, - SkClipOp op, - ClipEdgeStyle style) { - draw_calls_.emplace_back( - DrawCall{current_layer_, ClipRectData{rect, op, style}}); -} - -void MockCanvas::onClipRRect(const SkRRect& rrect, - SkClipOp op, - ClipEdgeStyle style) { - draw_calls_.emplace_back( - DrawCall{current_layer_, ClipRRectData{rrect, op, style}}); -} - -void MockCanvas::onClipPath(const SkPath& path, - SkClipOp op, - ClipEdgeStyle style) { - draw_calls_.emplace_back( - DrawCall{current_layer_, ClipPathData{path, op, style}}); -} - -bool MockCanvas::onDoSaveBehind(const SkRect*) { - FML_DCHECK(false); - return false; -} - -void MockCanvas::onDrawAnnotation(const SkRect&, const char[], SkData*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawPatch(const SkPoint[12], - const SkColor[4], - const SkPoint[4], - SkBlendMode, - const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawPaint(const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawBehind(const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawPoints(PointMode, - size_t, - const SkPoint[], - const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawRegion(const SkRegion&, const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawOval(const SkRect&, const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawArc(const SkRect&, - SkScalar, - SkScalar, - bool, - const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawRRect(const SkRRect&, const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawBitmap(const SkBitmap&, - SkScalar, - SkScalar, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawImage(const SkImage*, - SkScalar, - SkScalar, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawBitmapRect(const SkBitmap&, - const SkRect*, - const SkRect&, - const SkPaint*, - SrcRectConstraint) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawImageRect(const SkImage*, - const SkRect*, - const SkRect&, - const SkPaint*, - SrcRectConstraint) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawImageNine(const SkImage*, - const SkIRect&, - const SkRect&, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawBitmapNine(const SkBitmap&, - const SkIRect&, - const SkRect&, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawImageLattice(const SkImage*, - const Lattice&, - const SkRect&, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawBitmapLattice(const SkBitmap&, - const Lattice&, - const SkRect&, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawVerticesObject(const SkVertices*, - const SkVertices::Bone[], - int, - SkBlendMode, - const SkPaint&) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawAtlas(const SkImage*, - const SkRSXform[], - const SkRect[], - const SkColor[], - int, - SkBlendMode, - const SkRect*, - const SkPaint*) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawEdgeAAQuad(const SkRect&, - const SkPoint[4], - QuadAAFlags, - const SkColor4f&, - SkBlendMode) { - FML_DCHECK(false); -} - -void MockCanvas::onDrawEdgeAAImageSet(const ImageSetEntry[], - int, - const SkPoint[], - const SkMatrix[], - const SkPaint*, - SrcRectConstraint) { - FML_DCHECK(false); -} - -void MockCanvas::onClipRegion(const SkRegion&, SkClipOp) { - FML_DCHECK(false); -} - -bool operator==(const MockCanvas::SaveData& a, const MockCanvas::SaveData& b) { - return a.save_to_layer == b.save_to_layer; -} - -std::ostream& operator<<(std::ostream& os, const MockCanvas::SaveData& data) { - return os << data.save_to_layer; -} - -bool operator==(const MockCanvas::SaveLayerData& a, - const MockCanvas::SaveLayerData& b) { - return a.save_bounds == b.save_bounds && a.restore_paint == b.restore_paint && - a.backdrop_filter == b.backdrop_filter && - a.save_to_layer == b.save_to_layer; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::SaveLayerData& data) { - return os << data.save_bounds << " " << data.restore_paint << " " - << data.backdrop_filter << " " << data.save_to_layer; -} - -bool operator==(const MockCanvas::RestoreData& a, - const MockCanvas::RestoreData& b) { - return a.restore_to_layer == b.restore_to_layer; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::RestoreData& data) { - return os << data.restore_to_layer; -} - -bool operator==(const MockCanvas::ConcatMatrixData& a, - const MockCanvas::ConcatMatrixData& b) { - return a.matrix == b.matrix; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::ConcatMatrixData& data) { - return os << data.matrix; -} - -bool operator==(const MockCanvas::SetMatrixData& a, - const MockCanvas::SetMatrixData& b) { - return a.matrix == b.matrix; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::SetMatrixData& data) { - return os << data.matrix; -} - -bool operator==(const MockCanvas::DrawRectData& a, - const MockCanvas::DrawRectData& b) { - return a.rect == b.rect && a.paint == b.paint; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawRectData& data) { - return os << data.rect << " " << data.paint; -} - -bool operator==(const MockCanvas::DrawPathData& a, - const MockCanvas::DrawPathData& b) { - return a.path == b.path && a.paint == b.paint; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawPathData& data) { - return os << data.path << " " << data.paint; -} - -bool operator==(const MockCanvas::DrawTextData& a, - const MockCanvas::DrawTextData& b) { - return a.serialized_text->equals(b.serialized_text.get()) && - a.paint == b.paint && a.offset == b.offset; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawTextData& data) { - return os << data.serialized_text << " " << data.paint << " " << data.offset; -} - -bool operator==(const MockCanvas::DrawPictureData& a, - const MockCanvas::DrawPictureData& b) { - return a.serialized_picture->equals(b.serialized_picture.get()) && - a.paint == b.paint && a.matrix == b.matrix; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawPictureData& data) { - return os << data.serialized_picture << " " << data.paint << " " - << data.matrix; -} - -bool operator==(const MockCanvas::DrawShadowData& a, - const MockCanvas::DrawShadowData& b) { - return a.path == b.path; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawShadowData& data) { - return os << data.path; -} - -bool operator==(const MockCanvas::ClipRectData& a, - const MockCanvas::ClipRectData& b) { - return a.rect == b.rect && a.clip_op == b.clip_op && a.style == b.style; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipRectData& data) { - return os << data.rect << " " << data.clip_op << " " << data.style; -} - -bool operator==(const MockCanvas::ClipRRectData& a, - const MockCanvas::ClipRRectData& b) { - return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipRRectData& data) { - return os << data.rrect << " " << data.clip_op << " " << data.style; -} - -bool operator==(const MockCanvas::ClipPathData& a, - const MockCanvas::ClipPathData& b) { - return a.path == b.path && a.clip_op == b.clip_op && a.style == b.style; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipPathData& data) { - return os << data.path << " " << data.clip_op << " " << data.style; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawCallData& data) { - std::visit([&os](auto& d) { os << d; }, data); - return os; -} - -bool operator==(const MockCanvas::DrawCall& a, const MockCanvas::DrawCall& b) { - return a.layer == b.layer && a.data == b.data; -} - -std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) { - return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]"; -} - -} // namespace testing -} // namespace flutter diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h deleted file mode 100644 index cc4c2b11a9c2e..0000000000000 --- a/testing/mock_canvas.h +++ /dev/null @@ -1,318 +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 TESTING_MOCK_CANVAS_H_ -#define TESTING_MOCK_CANVAS_H_ - -#include -#include -#include - -#include "flutter/testing/assertions_skia.h" -#include "gtest/gtest.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkCanvasVirtualEnforcer.h" -#include "third_party/skia/include/core/SkClipOp.h" -#include "third_party/skia/include/core/SkData.h" -#include "third_party/skia/include/core/SkImageFilter.h" -#include "third_party/skia/include/core/SkPath.h" -#include "third_party/skia/include/core/SkRRect.h" -#include "third_party/skia/include/core/SkRect.h" -#include "third_party/skia/include/utils/SkNWayCanvas.h" - -namespace flutter { -namespace testing { - -static constexpr SkRect kEmptyRect = SkRect::MakeEmpty(); - -// Mock |SkCanvas|, useful for writing tests that use Skia but do not interact -// with the GPU. -// -// The |MockCanvas| stores a list of |DrawCall| that the test can later verify -// against the expected list of primitives to be drawn. -class MockCanvas : public SkCanvasVirtualEnforcer { - public: - using SkCanvas::kHard_ClipEdgeStyle; - using SkCanvas::kSoft_ClipEdgeStyle; - - struct SaveData { - int save_to_layer; - }; - - struct SaveLayerData { - SkRect save_bounds; - SkPaint restore_paint; - sk_sp backdrop_filter; - int save_to_layer; - }; - - struct RestoreData { - int restore_to_layer; - }; - - struct ConcatMatrixData { - SkMatrix matrix; - }; - - struct SetMatrixData { - SkMatrix matrix; - }; - - struct DrawRectData { - SkRect rect; - SkPaint paint; - }; - - struct DrawPathData { - SkPath path; - SkPaint paint; - }; - - struct DrawTextData { - sk_sp serialized_text; - SkPaint paint; - SkPoint offset; - }; - - struct DrawPictureData { - sk_sp serialized_picture; - SkPaint paint; - SkMatrix matrix; - }; - - struct DrawShadowData { - SkPath path; - }; - - struct ClipRectData { - SkRect rect; - SkClipOp clip_op; - ClipEdgeStyle style; - }; - - struct ClipRRectData { - SkRRect rrect; - SkClipOp clip_op; - ClipEdgeStyle style; - }; - - struct ClipPathData { - SkPath path; - SkClipOp clip_op; - ClipEdgeStyle style; - }; - - // Discriminated union of all the different |DrawCall| types. It is roughly - // equivalent to the different methods in |SkCanvas|' public API. - using DrawCallData = std::variant; - - // A single call made against this canvas. - struct DrawCall { - int layer; - DrawCallData data; - }; - - MockCanvas(); - ~MockCanvas() override; - - SkNWayCanvas* internal_canvas() { return &internal_canvas_; } - - const std::vector& draw_calls() const { return draw_calls_; } - - protected: - // Save/restore/set operations that we track. - void willSave() override; - SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override; - void willRestore() override; - void didRestore() override {} - void didConcat(const SkMatrix& matrix) override; - void didSetMatrix(const SkMatrix& matrix) override; - - // Draw and clip operations that we track. - void onDrawRect(const SkRect& rect, const SkPaint& paint) override; - void onDrawPath(const SkPath& path, const SkPaint& paint) override; - void onDrawTextBlob(const SkTextBlob* text, - SkScalar x, - SkScalar y, - const SkPaint& paint) override; - void onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) override; - void onDrawPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint) override; - void onClipRect(const SkRect& rect, - SkClipOp op, - ClipEdgeStyle style) override; - void onClipRRect(const SkRRect& rrect, - SkClipOp op, - ClipEdgeStyle style) override; - void onClipPath(const SkPath& path, - SkClipOp op, - ClipEdgeStyle style) override; - - // Operations that we don't track. - bool onDoSaveBehind(const SkRect*) override; - void onDrawAnnotation(const SkRect&, const char[], SkData*) override; - void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; - void onDrawDrawable(SkDrawable*, const SkMatrix*) override; - void onDrawPatch(const SkPoint[12], - const SkColor[4], - const SkPoint[4], - SkBlendMode, - const SkPaint&) override; - void onDrawPaint(const SkPaint&) override; - void onDrawBehind(const SkPaint&) override; - void onDrawPoints(PointMode, - size_t, - const SkPoint[], - const SkPaint&) override; - void onDrawRegion(const SkRegion&, const SkPaint&) override; - void onDrawOval(const SkRect&, const SkPaint&) override; - void onDrawArc(const SkRect&, - SkScalar, - SkScalar, - bool, - const SkPaint&) override; - void onDrawRRect(const SkRRect&, const SkPaint&) override; - void onDrawBitmapRect(const SkBitmap&, - const SkRect*, - const SkRect&, - const SkPaint*, - SrcRectConstraint) override; - void onDrawImage(const SkImage* image, - SkScalar x, - SkScalar y, - const SkPaint* paint) override; - void onDrawImageRect(const SkImage*, - const SkRect*, - const SkRect&, - const SkPaint*, - SrcRectConstraint) override; - void onDrawImageNine(const SkImage*, - const SkIRect&, - const SkRect&, - const SkPaint*) override; - void onDrawBitmap(const SkBitmap& bitmap, - SkScalar x, - SkScalar y, - const SkPaint* paint) override; - void onDrawBitmapNine(const SkBitmap&, - const SkIRect&, - const SkRect&, - const SkPaint*) override; - void onDrawImageLattice(const SkImage*, - const Lattice&, - const SkRect&, - const SkPaint*) override; - void onDrawBitmapLattice(const SkBitmap&, - const Lattice&, - const SkRect&, - const SkPaint*) override; - void onDrawVerticesObject(const SkVertices*, - const SkVertices::Bone[], - int, - SkBlendMode, - const SkPaint&) override; - void onDrawAtlas(const SkImage*, - const SkRSXform[], - const SkRect[], - const SkColor[], - int, - SkBlendMode, - const SkRect*, - const SkPaint*) override; - void onDrawEdgeAAQuad(const SkRect&, - const SkPoint[4], - QuadAAFlags, - const SkColor4f&, - SkBlendMode) override; - void onDrawEdgeAAImageSet(const ImageSetEntry[], - int, - const SkPoint[], - const SkMatrix[], - const SkPaint*, - SrcRectConstraint) override; - void onClipRegion(const SkRegion&, SkClipOp) override; - - private: - SkNWayCanvas internal_canvas_; - - std::vector draw_calls_; - int current_layer_; -}; - -extern bool operator==(const MockCanvas::SaveData& a, - const MockCanvas::SaveData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::SaveData& data); -extern bool operator==(const MockCanvas::SaveLayerData& a, - const MockCanvas::SaveLayerData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::SaveLayerData& data); -extern bool operator==(const MockCanvas::RestoreData& a, - const MockCanvas::RestoreData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::RestoreData& data); -extern bool operator==(const MockCanvas::ConcatMatrixData& a, - const MockCanvas::ConcatMatrixData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::ConcatMatrixData& data); -extern bool operator==(const MockCanvas::SetMatrixData& a, - const MockCanvas::SetMatrixData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::SetMatrixData& data); -extern bool operator==(const MockCanvas::DrawRectData& a, - const MockCanvas::DrawRectData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawRectData& data); -extern bool operator==(const MockCanvas::DrawPathData& a, - const MockCanvas::DrawPathData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawPathData& data); -extern bool operator==(const MockCanvas::DrawTextData& a, - const MockCanvas::DrawTextData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawTextData& data); -extern bool operator==(const MockCanvas::DrawPictureData& a, - const MockCanvas::DrawPictureData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawPictureData& data); -extern bool operator==(const MockCanvas::DrawShadowData& a, - const MockCanvas::DrawShadowData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawShadowData& data); -extern bool operator==(const MockCanvas::ClipRectData& a, - const MockCanvas::ClipRectData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipRectData& data); -extern bool operator==(const MockCanvas::ClipRRectData& a, - const MockCanvas::ClipRRectData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipRRectData& data); -extern bool operator==(const MockCanvas::ClipPathData& a, - const MockCanvas::ClipPathData& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipPathData& data); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawCallData& data); -extern bool operator==(const MockCanvas::DrawCall& a, - const MockCanvas::DrawCall& b); -extern std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawCall& draw); - -} // namespace testing -} // namespace flutter - -#endif // TESTING_MOCK_CANVAS_H_ diff --git a/testing/mock_canvas_unittests.cc b/testing/mock_canvas_unittests.cc deleted file mode 100644 index bab2fa43edd99..0000000000000 --- a/testing/mock_canvas_unittests.cc +++ /dev/null @@ -1,30 +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/testing/mock_canvas.h" - -#include "flutter/testing/canvas_test.h" -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -using MockCanvasTest = CanvasTest; - -TEST_F(MockCanvasTest, DrawCalls) { - const SkRect rect = SkRect::MakeWH(5.0f, 5.0f); - const SkPaint paint = SkPaint(SkColors::kGreen); - const auto expected_draw_calls = std::vector{ - MockCanvas::DrawCall{0, MockCanvas::DrawRectData{rect, paint}}}; - - mock_canvas().drawRect(rect, paint); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); -} - -TEST_F(MockCanvasTest, InvalidDrawCalls) { - EXPECT_DEATH_IF_SUPPORTED(mock_canvas().drawRRect(SkRRect(), SkPaint()), ""); -} - -} // namespace testing -} // namespace flutter diff --git a/testing/thread_test.cc b/testing/thread_test.cc index 2f67b6ee18368..88415169a3c70 100644 --- a/testing/thread_test.cc +++ b/testing/thread_test.cc @@ -8,16 +8,18 @@ namespace flutter { namespace testing { -namespace { -fml::RefPtr GetDefaultTaskRunner() { +// |testing::Test| +void ThreadTest::SetUp() { fml::MessageLoop::EnsureInitializedForCurrentThread(); - return fml::MessageLoop::GetCurrent().GetTaskRunner(); + current_task_runner_ = fml::MessageLoop::GetCurrent().GetTaskRunner(); } -} // namespace - -ThreadTest::ThreadTest() : current_task_runner_(GetDefaultTaskRunner()) {} +// |testing::Test| +void ThreadTest::TearDown() { + current_task_runner_ = nullptr; + extra_threads_.clear(); +} fml::RefPtr ThreadTest::GetCurrentTaskRunner() { return current_task_runner_; diff --git a/testing/thread_test.h b/testing/thread_test.h index 4a7d60fb0312c..8c55dbf80ce68 100644 --- a/testing/thread_test.h +++ b/testing/thread_test.h @@ -21,16 +21,14 @@ namespace testing { /// @brief A fixture that creates threads with running message loops that /// are terminated when the test is done (the threads are joined /// then as well). While this fixture may be used on it's own, it is -/// often sub-classed by other fixtures whose functioning requires +/// often sub-classed but other fixtures whose functioning requires /// threads to be created as necessary. /// class ThreadTest : public ::testing::Test { public: - ThreadTest(); - //---------------------------------------------------------------------------- /// @brief Get the task runner for the thread that the current unit-test - /// is running on. This creates a message loop as necessary. + /// is running on. The creates a message loop is necessary. /// /// @attention Unlike all other threads and task runners, this task runner is /// shared by all tests running in the process. Tests must ensure @@ -58,11 +56,16 @@ class ThreadTest : public ::testing::Test { /// fml::RefPtr CreateNewThread(std::string name = ""); + protected: + // |testing::Test| + void SetUp() override; + + // |testing::Test| + void TearDown() override; + private: fml::RefPtr current_task_runner_; std::vector> extra_threads_; - - FML_DISALLOW_COPY_AND_ASSIGN(ThreadTest); }; } // namespace testing