From b9df033311cc1b029ff4ac130690d46a4752844e Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Thu, 12 Dec 2024 20:33:17 -0800 Subject: [PATCH] Migrate DlRTree and DlRegion to DisplayList/Impeller geometry classes (#57175) Continuing the migration of engine code to the new geometry classes. Only DlRTree and DlRegion are converted in this pass, plus a small amount of associated code. --- .../benchmarking/dl_builder_benchmarks.cc | 6 +- .../benchmarking/dl_region_benchmarks.cc | 81 +++-- display_list/display_list.cc | 17 +- display_list/display_list.h | 20 +- display_list/display_list_unittests.cc | 162 ++++----- display_list/dl_builder.cc | 136 ++++---- display_list/dl_builder.h | 18 +- display_list/dl_vertices.h | 1 + display_list/geometry/dl_geometry_types.h | 4 + display_list/geometry/dl_path.h | 1 + display_list/geometry/dl_region.cc | 127 ++++--- display_list/geometry/dl_region.h | 21 +- display_list/geometry/dl_region_unittests.cc | 324 +++++++++--------- display_list/geometry/dl_rtree.cc | 37 +- display_list/geometry/dl_rtree.h | 25 +- display_list/geometry/dl_rtree_unittests.cc | 82 +++-- display_list/utils/dl_matrix_clip_tracker.cc | 12 + display_list/utils/dl_matrix_clip_tracker.h | 4 + flow/embedded_views.h | 5 +- flow/layers/display_list_layer_unittests.cc | 18 +- flow/layers/display_list_raster_cache_item.cc | 3 +- flow/raster_cache.cc | 6 +- flow/view_slicer.cc | 31 +- impeller/geometry/rect.h | 8 + ...urface_texture_external_texture_gl_skia.cc | 1 + .../darwin/ios/ios_surface_software.mm | 1 + .../embedder_external_view_embedder.cc | 2 +- shell/platform/embedder/embedder_layers.cc | 4 +- shell/platform/embedder/embedder_layers.h | 2 +- shell/platform/fuchsia/flutter/rtree.cc | 6 +- 30 files changed, 606 insertions(+), 559 deletions(-) diff --git a/display_list/benchmarking/dl_builder_benchmarks.cc b/display_list/benchmarking/dl_builder_benchmarks.cc index 3463ba55685cb..9e5128c6d476e 100644 --- a/display_list/benchmarking/dl_builder_benchmarks.cc +++ b/display_list/benchmarking/dl_builder_benchmarks.cc @@ -267,7 +267,7 @@ static void BM_DisplayListDispatchByVectorDefault( DlOpReceiverIgnore receiver; while (state.KeepRunning()) { std::vector indices = - display_list->GetCulledIndices(display_list->bounds()); + display_list->GetCulledIndices(display_list->GetBounds()); for (DlIndex index : indices) { display_list->Dispatch(receiver, index); } @@ -299,8 +299,8 @@ static void BM_DisplayListDispatchByVectorCull( InvokeAllOps(builder); } auto display_list = builder.Build(); - SkRect rect = SkRect::MakeLTRB(0, 0, 100, 100); - EXPECT_FALSE(rect.contains(display_list->bounds())); + DlRect rect = DlRect::MakeLTRB(0, 0, 100, 100); + EXPECT_FALSE(rect.Contains(display_list->GetBounds())); DlOpReceiverIgnore receiver; while (state.KeepRunning()) { std::vector indices = display_list->GetCulledIndices(rect); diff --git a/display_list/benchmarking/dl_region_benchmarks.cc b/display_list/benchmarking/dl_region_benchmarks.cc index bf169baf7db1d..c2d68969bf681 100644 --- a/display_list/benchmarking/dl_region_benchmarks.cc +++ b/display_list/benchmarking/dl_region_benchmarks.cc @@ -12,49 +12,54 @@ namespace { +using DlIRect = flutter::DlIRect; + template -std::vector GenerateRects(RNG& rng, - const SkIRect& bounds, +std::vector GenerateRects(RNG& rng, + const DlIRect& bounds, int numRects, int maxSize) { - auto max_size_x = std::min(maxSize, bounds.width()); - auto max_size_y = std::min(maxSize, bounds.height()); + auto max_size_x = std::min(maxSize, bounds.GetWidth()); + auto max_size_y = std::min(maxSize, bounds.GetHeight()); - std::uniform_int_distribution pos_x(bounds.fLeft, bounds.fRight - max_size_x); - std::uniform_int_distribution pos_y(bounds.fTop, bounds.fBottom - max_size_y); + std::uniform_int_distribution pos_x(bounds.GetLeft(), + bounds.GetRight() - max_size_x); + std::uniform_int_distribution pos_y(bounds.GetTop(), + bounds.GetBottom() - max_size_y); std::uniform_int_distribution size_x(1, max_size_x); std::uniform_int_distribution size_y(1, max_size_y); - std::vector rects; + std::vector rects; for (int i = 0; i < numRects; ++i) { - SkIRect rect = - SkIRect::MakeXYWH(pos_x(rng), pos_y(rng), size_x(rng), size_y(rng)); + DlIRect rect = + DlIRect::MakeXYWH(pos_x(rng), pos_y(rng), size_x(rng), size_y(rng)); rects.push_back(rect); } return rects; } template -SkIRect RandomSubRect(RNG& rng, const SkIRect& rect, double size_factor) { +DlIRect RandomSubRect(RNG& rng, const DlIRect& rect, double size_factor) { FML_DCHECK(size_factor <= 1); - int32_t width = rect.width() * size_factor; - int32_t height = rect.height() * size_factor; + int32_t width = rect.GetWidth() * size_factor; + int32_t height = rect.GetHeight() * size_factor; - std::uniform_int_distribution pos_x(0, rect.width() - width); - std::uniform_int_distribution pos_y(0, rect.height() - height); + std::uniform_int_distribution pos_x(0, rect.GetWidth() - width); + std::uniform_int_distribution pos_y(0, rect.GetHeight() - height); - return SkIRect::MakeXYWH(rect.fLeft + pos_x(rng), rect.fTop + pos_y(rng), + return DlIRect::MakeXYWH(rect.GetLeft() + pos_x(rng), + rect.GetTop() + pos_y(rng), // width, height); } class SkRegionAdapter { public: - explicit SkRegionAdapter(const std::vector& rects) { - region_.setRects(rects.data(), rects.size()); + explicit SkRegionAdapter(const std::vector& rects) { + region_.setRects(flutter::ToSkIRects(rects.data()), rects.size()); } - SkIRect getBounds() { return region_.getBounds(); } + DlIRect getBounds() { return flutter::ToDlIRect(region_.getBounds()); } static SkRegionAdapter unionRegions(const SkRegionAdapter& a1, const SkRegionAdapter& a2) { @@ -74,13 +79,15 @@ class SkRegionAdapter { return region_.intersects(region.region_); } - bool intersects(const SkIRect& rect) { return region_.intersects(rect); } + bool intersects(const DlIRect& rect) { + return region_.intersects(flutter::ToSkIRect(rect)); + } - std::vector getRects() { - std::vector rects; + std::vector getRects() { + std::vector rects; SkRegion::Iterator it(region_); while (!it.done()) { - rects.push_back(it.rect()); + rects.push_back(flutter::ToDlIRect(it.rect())); it.next(); } return rects; @@ -92,7 +99,7 @@ class SkRegionAdapter { class DlRegionAdapter { public: - explicit DlRegionAdapter(const std::vector& rects) + explicit DlRegionAdapter(const std::vector& rects) : region_(rects) {} static DlRegionAdapter unionRegions(const DlRegionAdapter& a1, @@ -107,15 +114,15 @@ class DlRegionAdapter { flutter::DlRegion::MakeIntersection(a1.region_, a2.region_)); } - SkIRect getBounds() { return region_.bounds(); } + DlIRect getBounds() { return region_.bounds(); } bool intersects(const DlRegionAdapter& region) { return region_.intersects(region.region_); } - bool intersects(const SkIRect& rect) { return region_.intersects(rect); } + bool intersects(const DlIRect& rect) { return region_.intersects(rect); } - std::vector getRects() { return region_.getRects(false); } + std::vector getRects() { return region_.getRects(false); } private: explicit DlRegionAdapter(flutter::DlRegion&& region) @@ -133,9 +140,9 @@ void RunFromRectsBenchmark(benchmark::State& state, int maxSize) { std::uniform_int_distribution pos(0, 4000); std::uniform_int_distribution size(1, maxSize); - std::vector rects; + std::vector rects; for (int i = 0; i < 2000; ++i) { - SkIRect rect = SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects.push_back(rect); } @@ -153,9 +160,9 @@ void RunGetRectsBenchmark(benchmark::State& state, int maxSize) { std::uniform_int_distribution pos(0, 4000); std::uniform_int_distribution size(1, maxSize); - std::vector rects; + std::vector rects; for (int i = 0; i < 2000; ++i) { - SkIRect rect = SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects.push_back(rect); } @@ -178,8 +185,8 @@ void RunRegionOpBenchmark(benchmark::State& state, std::seed_seq seed{2, 1, 3}; std::mt19937 rng(seed); - SkIRect bounds1 = SkIRect::MakeWH(4000, 4000); - SkIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor); + DlIRect bounds1 = DlIRect::MakeWH(4000, 4000); + DlIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor); auto rects = GenerateRects(rng, bounds1, 500, maxSize); Region region1(rects); @@ -210,8 +217,8 @@ void RunIntersectsRegionBenchmark(benchmark::State& state, std::seed_seq seed{2, 1, 3}; std::mt19937 rng(seed); - SkIRect bounds1 = SkIRect::MakeWH(4000, 4000); - SkIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor); + DlIRect bounds1 = DlIRect::MakeWH(4000, 4000); + DlIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor); auto rects = GenerateRects(rng, bounds1, 500, maxSize); Region region1(rects); @@ -233,16 +240,16 @@ void RunIntersectsSingleRectBenchmark(benchmark::State& state, int maxSize) { std::uniform_int_distribution pos(0, 4000); std::uniform_int_distribution size(1, maxSize); - std::vector rects; + std::vector rects; for (int i = 0; i < 500; ++i) { - SkIRect rect = SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects.push_back(rect); } Region region1(rects); rects.clear(); for (int i = 0; i < 100; ++i) { - SkIRect rect = SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects.push_back(rect); } diff --git a/display_list/display_list.cc b/display_list/display_list.cc index fc823dee83209..91f7f29f1517e 100644 --- a/display_list/display_list.cc +++ b/display_list/display_list.cc @@ -20,7 +20,6 @@ DisplayList::DisplayList() nested_op_count_(0), total_depth_(0), unique_id_(0), - bounds_({0, 0, 0, 0}), can_apply_group_opacity_(true), is_ui_thread_safe_(true), modifies_transparent_black_(false), @@ -37,7 +36,7 @@ DisplayList::DisplayList(DisplayListStorage&& storage, size_t nested_byte_count, uint32_t nested_op_count, uint32_t total_depth, - const SkRect& bounds, + const DlRect& bounds, bool can_apply_group_opacity, bool is_ui_thread_safe, bool modifies_transparent_black, @@ -187,16 +186,16 @@ void DisplayList::Dispatch(DlOpReceiver& receiver) const { } void DisplayList::Dispatch(DlOpReceiver& receiver, - const SkIRect& cull_rect) const { - Dispatch(receiver, SkRect::Make(cull_rect)); + const DlIRect& cull_rect) const { + Dispatch(receiver, DlRect::Make(cull_rect)); } void DisplayList::Dispatch(DlOpReceiver& receiver, - const SkRect& cull_rect) const { - if (cull_rect.isEmpty()) { + const DlRect& cull_rect) const { + if (cull_rect.IsEmpty()) { return; } - if (!has_rtree() || cull_rect.contains(bounds())) { + if (!has_rtree() || cull_rect.Contains(GetBounds())) { Dispatch(receiver); } else { auto op_indices = GetCulledIndices(cull_rect); @@ -366,9 +365,9 @@ static void FillAllIndices(std::vector& indices, DlIndex size) { } std::vector DisplayList::GetCulledIndices( - const SkRect& cull_rect) const { + const DlRect& cull_rect) const { std::vector indices; - if (!cull_rect.isEmpty()) { + if (!cull_rect.IsEmpty()) { if (rtree_) { std::vector rect_indices; rtree_->search(cull_rect, &rect_indices); diff --git a/display_list/display_list.h b/display_list/display_list.h index 0c13a437df60e..1e2f35ca84fac 100644 --- a/display_list/display_list.h +++ b/display_list/display_list.h @@ -271,8 +271,14 @@ class DisplayList : public SkRefCnt { ~DisplayList(); void Dispatch(DlOpReceiver& ctx) const; - void Dispatch(DlOpReceiver& ctx, const SkRect& cull_rect) const; - void Dispatch(DlOpReceiver& ctx, const SkIRect& cull_rect) const; + void Dispatch(DlOpReceiver& ctx, const SkRect& cull_rect) const { + Dispatch(ctx, ToDlRect(cull_rect)); + } + void Dispatch(DlOpReceiver& ctx, const SkIRect& cull_rect) const { + Dispatch(ctx, ToDlIRect(cull_rect)); + } + void Dispatch(DlOpReceiver& ctx, const DlRect& cull_rect) const; + void Dispatch(DlOpReceiver& ctx, const DlIRect& cull_rect) const; // From historical behavior, SkPicture always included nested bytes, // but nested ops are only included if requested. The defaults used @@ -290,8 +296,8 @@ class DisplayList : public SkRefCnt { uint32_t unique_id() const { return unique_id_; } - const SkRect& bounds() const { return bounds_; } - const DlRect& GetBounds() const { return ToDlRect(bounds_); } + const SkRect& bounds() const { return ToSkRect(bounds_); } + const DlRect& GetBounds() const { return bounds_; } bool has_rtree() const { return rtree_ != nullptr; } sk_sp rtree() const { return rtree_; } @@ -500,7 +506,7 @@ class DisplayList : public SkRefCnt { /// primarily for debugging use /// /// @see |Dispatch(receiver, index)| - std::vector GetCulledIndices(const SkRect& cull_rect) const; + std::vector GetCulledIndices(const DlRect& cull_rect) const; private: DisplayList(DisplayListStorage&& ptr, @@ -509,7 +515,7 @@ class DisplayList : public SkRefCnt { size_t nested_byte_count, uint32_t nested_op_count, uint32_t total_depth, - const SkRect& bounds, + const DlRect& bounds, bool can_apply_group_opacity, bool is_ui_thread_safe, bool modifies_transparent_black, @@ -533,7 +539,7 @@ class DisplayList : public SkRefCnt { const uint32_t total_depth_; const uint32_t unique_id_; - const SkRect bounds_; + const DlRect bounds_; const bool can_apply_group_opacity_; const bool is_ui_thread_safe_; diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index cfd1f6b66bbc5..d090bf83784aa 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -2424,8 +2424,8 @@ TEST_F(DisplayListTest, FlatDrawPointsProducesBounds) { test_rtree(rtree, query, expected_rects, expected_indices, __FILE__, __LINE__) static void test_rtree(const sk_sp& rtree, - const SkRect& query, - std::vector expected_rects, + const DlRect& query, + std::vector expected_rects, const std::vector& expected_indices, const std::string& file, int line) { @@ -2434,7 +2434,7 @@ static void test_rtree(const sk_sp& rtree, rtree->search(query, &indices); EXPECT_EQ(indices, expected_indices) << label; EXPECT_EQ(indices.size(), expected_indices.size()) << label; - std::list rects = rtree->searchAndConsolidateRects(query, false); + std::list rects = rtree->searchAndConsolidateRects(query, false); // ASSERT_EQ(rects.size(), expected_indices.size()); auto iterator = rects.cbegin(); for (int i : expected_indices) { @@ -2445,9 +2445,9 @@ static void test_rtree(const sk_sp& rtree, TEST_F(DisplayListTest, RTreeOfSimpleScene) { DisplayListBuilder builder(/*prepare_rtree=*/true); - std::vector rects = { - {10, 10, 20, 20}, - {50, 50, 60, 60}, + std::vector rects = { + DlRect::MakeLTRB(10, 10, 20, 20), + DlRect::MakeLTRB(50, 50, 60, 60), }; builder.DrawRect(rects[0], DlPaint()); builder.DrawRect(rects[1], DlPaint()); @@ -2455,49 +2455,49 @@ TEST_F(DisplayListTest, RTreeOfSimpleScene) { auto rtree = display_list->rtree(); // Missing all drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 10, 10), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(20, 20, 25, 25), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 50, 50), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(60, 60, 65, 65), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 10, 10), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(20, 20, 25, 25), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 50, 50), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(60, 60, 65, 65), rects, {}); // Hitting just 1 of the drawRects - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 11, 11), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 25, 25), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 51, 51), rects, {1}); - TEST_RTREE(rtree, SkRect::MakeLTRB(59, 59, 65, 65), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 11, 11), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 25, 25), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 51, 51), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(59, 59, 65, 65), rects, {1}); // Hitting both drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 51, 51), rects, + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 51, 51), rects, std::vector({0, 1})); } TEST_F(DisplayListTest, RTreeOfSaveRestoreScene) { DisplayListBuilder builder(/*prepare_rtree=*/true); - builder.DrawRect(SkRect{10, 10, 20, 20}, DlPaint()); + builder.DrawRect(DlRect::MakeLTRB(10, 10, 20, 20), DlPaint()); builder.Save(); - builder.DrawRect(SkRect{50, 50, 60, 60}, DlPaint()); + builder.DrawRect(DlRect::MakeLTRB(50, 50, 60, 60), DlPaint()); builder.Restore(); auto display_list = builder.Build(); auto rtree = display_list->rtree(); - std::vector rects = { - {10, 10, 20, 20}, - {50, 50, 60, 60}, + std::vector rects = { + DlRect::MakeLTRB(10, 10, 20, 20), + DlRect::MakeLTRB(50, 50, 60, 60), }; // Missing all drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 10, 10), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(20, 20, 25, 25), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 50, 50), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(60, 60, 65, 65), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 10, 10), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(20, 20, 25, 25), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 50, 50), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(60, 60, 65, 65), rects, {}); // Hitting just 1 of the drawRects - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 11, 11), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 25, 25), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 51, 51), rects, {1}); - TEST_RTREE(rtree, SkRect::MakeLTRB(59, 59, 65, 65), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 11, 11), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 25, 25), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 51, 51), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(59, 59, 65, 65), rects, {1}); // Hitting both drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 51, 51), rects, + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 51, 51), rects, std::vector({0, 1})); } @@ -2507,40 +2507,40 @@ TEST_F(DisplayListTest, RTreeOfSaveLayerFilterScene) { auto filter = DlBlurImageFilter(1.0, 1.0, DlTileMode::kClamp); DlPaint default_paint = DlPaint(); DlPaint filter_paint = DlPaint().setImageFilter(&filter); - builder.DrawRect(SkRect{10, 10, 20, 20}, default_paint); + builder.DrawRect(DlRect::MakeLTRB(10, 10, 20, 20), default_paint); builder.SaveLayer(nullptr, &filter_paint); // the following rectangle will be expanded to 50,50,60,60 // by the SaveLayer filter during the restore operation - builder.DrawRect(SkRect{53, 53, 57, 57}, default_paint); + builder.DrawRect(DlRect::MakeLTRB(53, 53, 57, 57), default_paint); builder.Restore(); auto display_list = builder.Build(); auto rtree = display_list->rtree(); - std::vector rects = { - {10, 10, 20, 20}, - {50, 50, 60, 60}, + std::vector rects = { + DlRect::MakeLTRB(10, 10, 20, 20), + DlRect::MakeLTRB(50, 50, 60, 60), }; // Missing all drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 10, 10), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(20, 20, 25, 25), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 50, 50), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(60, 60, 65, 65), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 10, 10), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(20, 20, 25, 25), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 50, 50), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(60, 60, 65, 65), rects, {}); // Hitting just 1 of the drawRects - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 11, 11), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 25, 25), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 51, 51), rects, {1}); - TEST_RTREE(rtree, SkRect::MakeLTRB(59, 59, 65, 65), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 11, 11), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 25, 25), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 51, 51), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(59, 59, 65, 65), rects, {1}); // Hitting both drawRect calls auto expected_indices = std::vector{0, 1}; - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 51, 51), rects, expected_indices); + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 51, 51), rects, expected_indices); } TEST_F(DisplayListTest, NestedDisplayListRTreesAreSparse) { DisplayListBuilder nested_dl_builder(/**prepare_rtree=*/true); - nested_dl_builder.DrawRect(SkRect{10, 10, 20, 20}, DlPaint()); - nested_dl_builder.DrawRect(SkRect{50, 50, 60, 60}, DlPaint()); + nested_dl_builder.DrawRect(DlRect::MakeLTRB(10, 10, 20, 20), DlPaint()); + nested_dl_builder.DrawRect(DlRect::MakeLTRB(50, 50, 60, 60), DlPaint()); auto nested_display_list = nested_dl_builder.Build(); DisplayListBuilder builder(/**prepare_rtree=*/true); @@ -2548,13 +2548,13 @@ TEST_F(DisplayListTest, NestedDisplayListRTreesAreSparse) { auto display_list = builder.Build(); auto rtree = display_list->rtree(); - std::vector rects = { - {10, 10, 20, 20}, - {50, 50, 60, 60}, + std::vector rects = { + DlRect::MakeLTRB(10, 10, 20, 20), + DlRect::MakeLTRB(50, 50, 60, 60), }; // Hitting both sub-dl drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 51, 51), rects, + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 51, 51), rects, std::vector({0, 1})); } @@ -3268,43 +3268,43 @@ TEST_F(DisplayListTest, RTreeOfClippedSaveLayerFilterScene) { auto filter = DlBlurImageFilter(10.0, 10.0, DlTileMode::kClamp); DlPaint default_paint = DlPaint(); DlPaint filter_paint = DlPaint().setImageFilter(&filter); - builder.DrawRect(SkRect{10, 10, 20, 20}, default_paint); - builder.ClipRect(SkRect{50, 50, 60, 60}, ClipOp::kIntersect, false); + builder.DrawRect(DlRect::MakeLTRB(10, 10, 20, 20), default_paint); + builder.ClipRect(DlRect::MakeLTRB(50, 50, 60, 60), ClipOp::kIntersect, false); builder.SaveLayer(nullptr, &filter_paint); // the following rectangle will be expanded to 23,23,87,87 // by the SaveLayer filter during the restore operation // but it will then be clipped to 50,50,60,60 - builder.DrawRect(SkRect{53, 53, 57, 57}, default_paint); + builder.DrawRect(DlRect::MakeLTRB(53, 53, 57, 57), default_paint); builder.Restore(); auto display_list = builder.Build(); auto rtree = display_list->rtree(); - std::vector rects = { - {10, 10, 20, 20}, - {50, 50, 60, 60}, + std::vector rects = { + DlRect::MakeLTRB(10, 10, 20, 20), + DlRect::MakeLTRB(50, 50, 60, 60), }; // Missing all drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 10, 10), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(20, 20, 25, 25), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 50, 50), rects, {}); - TEST_RTREE(rtree, SkRect::MakeLTRB(60, 60, 65, 65), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 10, 10), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(20, 20, 25, 25), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 50, 50), rects, {}); + TEST_RTREE(rtree, DlRect::MakeLTRB(60, 60, 65, 65), rects, {}); // Hitting just 1 of the drawRects - TEST_RTREE(rtree, SkRect::MakeLTRB(5, 5, 11, 11), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 25, 25), rects, {0}); - TEST_RTREE(rtree, SkRect::MakeLTRB(45, 45, 51, 51), rects, {1}); - TEST_RTREE(rtree, SkRect::MakeLTRB(59, 59, 65, 65), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(5, 5, 11, 11), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 25, 25), rects, {0}); + TEST_RTREE(rtree, DlRect::MakeLTRB(45, 45, 51, 51), rects, {1}); + TEST_RTREE(rtree, DlRect::MakeLTRB(59, 59, 65, 65), rects, {1}); // Hitting both drawRect calls - TEST_RTREE(rtree, SkRect::MakeLTRB(19, 19, 51, 51), rects, + TEST_RTREE(rtree, DlRect::MakeLTRB(19, 19, 51, 51), rects, std::vector({0, 1})); } TEST_F(DisplayListTest, RTreeRenderCulling) { - SkRect rect1 = SkRect::MakeLTRB(0, 0, 10, 10); - SkRect rect2 = SkRect::MakeLTRB(20, 0, 30, 10); - SkRect rect3 = SkRect::MakeLTRB(0, 20, 10, 30); - SkRect rect4 = SkRect::MakeLTRB(20, 20, 30, 30); + DlRect rect1 = DlRect::MakeLTRB(0, 0, 10, 10); + DlRect rect2 = DlRect::MakeLTRB(20, 0, 30, 10); + DlRect rect3 = DlRect::MakeLTRB(0, 20, 10, 30); + DlRect rect4 = DlRect::MakeLTRB(20, 20, 30, 30); DlPaint paint1 = DlPaint().setColor(DlColor::kRed()); DlPaint paint2 = DlPaint().setColor(DlColor::kGreen()); DlPaint paint3 = DlPaint().setColor(DlColor::kBlue()); @@ -3317,11 +3317,11 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { main_builder.DrawRect(rect4, paint4); auto main = main_builder.Build(); - auto test = [main](SkIRect cull_rect, const sk_sp& expected, + auto test = [main](DlIRect cull_rect, const sk_sp& expected, const std::string& label) { - SkRect cull_rectf = SkRect::Make(cull_rect); + DlRect cull_rectf = DlRect::Make(cull_rect); - { // Test SkIRect culling + { // Test DlIRect culling DisplayListBuilder culling_builder; main->Dispatch(ToReceiver(culling_builder), cull_rect); @@ -3330,7 +3330,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { << " where " << label; } - { // Test SkRect culling + { // Test DlRect culling DisplayListBuilder culling_builder; main->Dispatch(ToReceiver(culling_builder), cull_rectf); @@ -3354,7 +3354,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { }; { // No rects - SkIRect cull_rect = {11, 11, 19, 19}; + DlIRect cull_rect = DlIRect::MakeLTRB(11, 11, 19, 19); DisplayListBuilder expected_builder; auto expected = expected_builder.Build(); @@ -3363,7 +3363,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { } { // Rect 1 - SkIRect cull_rect = {9, 9, 19, 19}; + DlIRect cull_rect = DlIRect::MakeLTRB(9, 9, 19, 19); DisplayListBuilder expected_builder; expected_builder.DrawRect(rect1, paint1); @@ -3373,7 +3373,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { } { // Rect 2 - SkIRect cull_rect = {11, 9, 21, 19}; + DlIRect cull_rect = DlIRect::MakeLTRB(11, 9, 21, 19); DisplayListBuilder expected_builder; // Unfortunately we don't cull attribute records (yet?), so we forcibly @@ -3386,7 +3386,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { } { // Rect 3 - SkIRect cull_rect = {9, 11, 19, 21}; + DlIRect cull_rect = DlIRect::MakeLTRB(9, 11, 19, 21); DisplayListBuilder expected_builder; // Unfortunately we don't cull attribute records (yet?), so we forcibly @@ -3400,7 +3400,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { } { // Rect 4 - SkIRect cull_rect = {11, 11, 21, 21}; + DlIRect cull_rect = DlIRect::MakeLTRB(11, 11, 21, 21); DisplayListBuilder expected_builder; // Unfortunately we don't cull attribute records (yet?), so we forcibly @@ -3415,7 +3415,7 @@ TEST_F(DisplayListTest, RTreeRenderCulling) { } { // All 4 rects - SkIRect cull_rect = {9, 9, 21, 21}; + DlIRect cull_rect = DlIRect::MakeLTRB(9, 9, 21, 21); test(cull_rect, main, "all rects intersect"); } @@ -4221,7 +4221,7 @@ TEST_F(DisplayListTest, SaveContentDepthTest) { TEST_F(DisplayListTest, FloodingFilteredLayerPushesRestoreOpIndex) { DisplayListBuilder builder(true); - builder.ClipRect(SkRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f)); + builder.ClipRect(DlRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f)); // ClipRect does not contribute to rtree rects, no id needed DlPaint save_paint; @@ -4238,7 +4238,7 @@ TEST_F(DisplayListTest, FloodingFilteredLayerPushesRestoreOpIndex) { builder.SaveLayer(nullptr, &save_paint); int save_layer_id = DisplayListBuilderTestingLastOpIndex(builder); - builder.DrawRect(SkRect::MakeLTRB(120.0f, 120.0f, 125.0f, 125.0f), DlPaint()); + builder.DrawRect(DlRect::MakeLTRB(120.0f, 120.0f, 125.0f, 125.0f), DlPaint()); int draw_rect_id = DisplayListBuilderTestingLastOpIndex(builder); builder.Restore(); @@ -4246,7 +4246,7 @@ TEST_F(DisplayListTest, FloodingFilteredLayerPushesRestoreOpIndex) { auto dl = builder.Build(); std::vector indices; - dl->rtree()->search(SkRect::MakeLTRB(0.0f, 0.0f, 500.0f, 500.0f), &indices); + dl->rtree()->search(DlRect::MakeLTRB(0.0f, 0.0f, 500.0f, 500.0f), &indices); ASSERT_EQ(indices.size(), 3u); EXPECT_EQ(dl->rtree()->id(indices[0]), save_layer_id); EXPECT_EQ(dl->rtree()->id(indices[1]), draw_rect_id); diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 682e8823c5607..f05cb3eff721f 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -13,7 +13,6 @@ #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/display_list/utils/dl_accumulation_rect.h" #include "fml/logging.h" -#include "third_party/skia/include/core/SkScalar.h" namespace flutter { @@ -78,7 +77,7 @@ sk_sp DisplayListBuilder::Build() { DlBlendMode max_root_blend_mode = current_layer().max_blend_mode; sk_sp rtree; - SkRect bounds; + DlRect bounds; if (rtree_data_.has_value()) { auto& rects = rtree_data_->rects; auto& indices = rtree_data_->indices; @@ -90,7 +89,7 @@ sk_sp DisplayListBuilder::Build() { bounds = rtree->bounds(); rtree_data_.reset(); } else { - bounds = current_layer().global_space_accumulator.bounds(); + bounds = current_layer().global_space_accumulator.GetBounds(); } render_op_count_ = op_index_ = 0; @@ -598,7 +597,7 @@ void DisplayListBuilder::RestoreLayer() { // the total content depth computed above in Restore. depth_ += render_op_depth_cost_; - SkRect content_bounds = current_layer().layer_local_accumulator.bounds(); + DlRect content_bounds = current_layer().layer_local_accumulator.GetBounds(); SaveLayerOpBase* layer_op = reinterpret_cast( storage_.base() + current_info().save_offset); @@ -606,18 +605,13 @@ void DisplayListBuilder::RestoreLayer() { layer_op->type == DisplayListOpType::kSaveLayerBackdrop); if (layer_op->options.bounds_from_caller()) { - SkRect user_bounds = ToSkRect(layer_op->rect); - if (!content_bounds.isEmpty() && !user_bounds.contains(content_bounds)) { + DlRect user_bounds = layer_op->rect; + if (!content_bounds.IsEmpty() && !user_bounds.Contains(content_bounds)) { layer_op->options = layer_op->options.with_content_is_clipped(); - if (!content_bounds.intersect(user_bounds)) { - // Should never happen because we prune ops that don't intersect the - // supplied bounds so content_bounds would already be empty and we - // wouldn't come into this control block due to the empty test above. - content_bounds.setEmpty(); - } + content_bounds = content_bounds.IntersectionOrEmpty(user_bounds); } } - layer_op->rect = ToDlRect(content_bounds); + layer_op->rect = content_bounds; layer_op->max_blend_mode = current_layer().max_blend_mode; if (current_layer().contains_backdrop_filter) { @@ -669,7 +663,7 @@ void DisplayListBuilder::RestoreLayer() { // // Finally, we will have to adjust the layer's content bounds by the filter // and accumulate those into the parent layer's local bounds. -void DisplayListBuilder::TransferLayerBounds(const SkRect& content_bounds) { +void DisplayListBuilder::TransferLayerBounds(const DlRect& content_bounds) { auto& filter = current_layer().filter; if (!filter) { @@ -685,7 +679,7 @@ void DisplayListBuilder::TransferLayerBounds(const SkRect& content_bounds) { } bool parent_is_flooded = false; - SkRect bounds_for_parent = content_bounds; + DlRect bounds_for_parent = content_bounds; // First, let's adjust or transfer the global/rtree bounds by the filter. @@ -742,10 +736,10 @@ void DisplayListBuilder::TransferLayerBounds(const SkRect& content_bounds) { // to flood the parent due to any of the cases above, we don't need to // run the filter on the content bounds only to discover the same // condition. - if (!parent_is_flooded && !bounds_for_parent.isEmpty()) { - DlRect mappable_bounds = ToDlRect(bounds_for_parent); + if (!parent_is_flooded && !bounds_for_parent.IsEmpty()) { + DlRect mappable_bounds = bounds_for_parent; if (filter->map_local_bounds(mappable_bounds, mappable_bounds)) { - bounds_for_parent = ToSkRect(mappable_bounds); + bounds_for_parent = mappable_bounds; } else { parent_is_flooded = true; } @@ -778,7 +772,7 @@ bool DisplayListBuilder::AdjustRTreeRects(RTreeData& data, int ret = false; auto rect_keep = rect_start_index; for (size_t i = rect_start_index; i < rects.size(); i++) { - DlRect bounds = ToDlRect(rects[i]); + DlRect bounds = rects[i]; DlIRect ibounds = DlIRect::RoundOut(bounds); if (filter.map_device_bounds(ibounds, matrix, ibounds)) { bounds = DlRect::Make(ibounds); @@ -789,7 +783,7 @@ bool DisplayListBuilder::AdjustRTreeRects(RTreeData& data, auto clipped_bounds = bounds.Intersection(clip); if (clipped_bounds.has_value()) { indices[rect_keep] = indices[i]; - rects[rect_keep] = ToSkRect(clipped_bounds.value()); + rects[rect_keep] = clipped_bounds.value(); rect_keep++; } } @@ -1100,10 +1094,9 @@ void DisplayListBuilder::DrawColor(DlColor color, DlBlendMode mode) { } } void DisplayListBuilder::drawLine(const DlPoint& p0, const DlPoint& p1) { - SkRect bounds = SkRect::MakeLTRB(p0.x, p0.y, p1.x, p1.y).makeSorted(); + DlRect bounds = DlRect::MakeLTRB(p0.x, p0.y, p1.x, p1.y).GetPositive(); DisplayListAttributeFlags flags = - (bounds.width() > 0.0f && bounds.height() > 0.0f) ? kDrawLineFlags - : kDrawHVLineFlags; + bounds.IsEmpty() ? kDrawHVLineFlags : kDrawLineFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && AccumulateOpBounds(bounds, flags)) { Push(0, p0, p1); @@ -1121,10 +1114,9 @@ void DisplayListBuilder::drawDashedLine(const DlPoint& p0, const DlPoint& p1, DlScalar on_length, DlScalar off_length) { - SkRect bounds = SkRect::MakeLTRB(p0.x, p0.y, p1.x, p1.y).makeSorted(); + DlRect bounds = DlRect::MakeLTRB(p0.x, p0.y, p1.x, p1.y).GetPositive(); DisplayListAttributeFlags flags = - (bounds.width() > 0.0f && bounds.height() > 0.0f) ? kDrawLineFlags - : kDrawHVLineFlags; + bounds.IsEmpty() ? kDrawHVLineFlags : kDrawLineFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && AccumulateOpBounds(bounds, flags)) { Push(0, p0, p1, on_length, off_length); @@ -1144,7 +1136,7 @@ void DisplayListBuilder::drawRect(const DlRect& rect) { DisplayListAttributeFlags flags = kDrawRectFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(rect.GetPositive()), flags)) { + AccumulateOpBounds(rect.GetPositive(), flags)) { Push(0, rect); CheckLayerOpacityCompatibility(); UpdateLayerResult(result); @@ -1158,7 +1150,7 @@ void DisplayListBuilder::drawOval(const DlRect& bounds) { DisplayListAttributeFlags flags = kDrawOvalFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(bounds.GetPositive()), flags)) { + AccumulateOpBounds(bounds.GetPositive(), flags)) { Push(0, bounds); CheckLayerOpacityCompatibility(); UpdateLayerResult(result); @@ -1172,7 +1164,7 @@ void DisplayListBuilder::drawCircle(const DlPoint& center, DlScalar radius) { DisplayListAttributeFlags flags = kDrawCircleFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect) { - SkRect bounds = SkRect::MakeLTRB(center.x - radius, center.y - radius, + DlRect bounds = DlRect::MakeLTRB(center.x - radius, center.y - radius, center.x + radius, center.y + radius); if (AccumulateOpBounds(bounds, flags)) { Push(0, center, radius); @@ -1196,7 +1188,7 @@ void DisplayListBuilder::drawRoundRect(const DlRoundRect& rrect) { DisplayListAttributeFlags flags = kDrawRRectFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(rrect.GetBounds()), flags)) { + AccumulateOpBounds(rrect.GetBounds(), flags)) { Push(0, rrect); CheckLayerOpacityCompatibility(); UpdateLayerResult(result); @@ -1213,7 +1205,7 @@ void DisplayListBuilder::drawDiffRoundRect(const DlRoundRect& outer, DisplayListAttributeFlags flags = kDrawDRRectFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(outer.GetBounds()), flags)) { + AccumulateOpBounds(outer.GetBounds(), flags)) { Push(0, outer, inner); CheckLayerOpacityCompatibility(); UpdateLayerResult(result); @@ -1229,10 +1221,9 @@ void DisplayListBuilder::drawPath(const DlPath& path) { DisplayListAttributeFlags flags = kDrawPathFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect) { - bool is_visible = - path.IsInverseFillType() - ? AccumulateUnbounded() - : AccumulateOpBounds(ToSkRect(path.GetBounds()), flags); + bool is_visible = path.IsInverseFillType() + ? AccumulateUnbounded() + : AccumulateOpBounds(path.GetBounds(), flags); if (is_visible) { Push(0, path); CheckLayerOpacityHairlineCompatibility(); @@ -1257,8 +1248,7 @@ void DisplayListBuilder::drawArc(const DlRect& bounds, // This could be tighter if we compute where the start and end // angles are and then also consider the quadrants swept and // the center if specified. - if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(bounds), flags)) { + if (result != OpResult::kNoEffect && AccumulateOpBounds(bounds, flags)) { Push(0, bounds, start, sweep, useCenter); if (useCenter) { CheckLayerOpacityHairlineCompatibility(); @@ -1308,8 +1298,7 @@ void DisplayListBuilder::drawPoints(PointMode mode, for (size_t i = 0; i < count; i++) { accumulator.accumulate(pts[i]); } - SkRect point_bounds = accumulator.bounds(); - if (!AccumulateOpBounds(point_bounds, flags)) { + if (!AccumulateOpBounds(accumulator.GetBounds(), flags)) { return; } @@ -1355,7 +1344,7 @@ void DisplayListBuilder::drawVertices( DisplayListAttributeFlags flags = kDrawVerticesFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && - AccumulateOpBounds(vertices->bounds(), flags)) { + AccumulateOpBounds(vertices->GetBounds(), flags)) { Push(0, vertices, mode); // DrawVertices applies its colors to the paint so we have no way // of controlling opacity using the current paint attributes. @@ -1393,7 +1382,7 @@ void DisplayListBuilder::drawImage(const sk_sp image, if (result == OpResult::kNoEffect) { return; } - SkRect bounds = SkRect::MakeXYWH(point.x, point.y, // + DlRect bounds = DlRect::MakeXYWH(point.x, point.y, // image->width(), image->height()); if (AccumulateOpBounds(bounds, flags)) { render_with_attributes @@ -1426,8 +1415,7 @@ void DisplayListBuilder::drawImageRect(const sk_sp image, ? kDrawImageRectWithPaintFlags : kDrawImageRectFlags; OpResult result = PaintResult(current_, flags); - if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(dst), flags)) { + if (result != OpResult::kNoEffect && AccumulateOpBounds(dst, flags)) { Push(0, image, src, dst, sampling, render_with_attributes, constraint); CheckLayerOpacityCompatibility(render_with_attributes); @@ -1458,8 +1446,7 @@ void DisplayListBuilder::drawImageNine(const sk_sp image, ? kDrawImageNineWithPaintFlags : kDrawImageNineFlags; OpResult result = PaintResult(current_, flags); - if (result != OpResult::kNoEffect && - AccumulateOpBounds(ToSkRect(dst), flags)) { + if (result != OpResult::kNoEffect && AccumulateOpBounds(dst, flags)) { render_with_attributes ? Push(0, image, center, dst, filter) : Push(0, image, center, dst, filter); @@ -1500,14 +1487,14 @@ void DisplayListBuilder::drawAtlas(const sk_sp atlas, SkPoint quad[4]; AccumulationRect accumulator; for (int i = 0; i < count; i++) { - const SkRect& src = ToSkRect(tex[i]); - xform[i].toQuad(src.width(), src.height(), quad); + const DlRect& src = tex[i]; + xform[i].toQuad(src.GetWidth(), src.GetHeight(), quad); for (int j = 0; j < 4; j++) { accumulator.accumulate(quad[j]); } } if (accumulator.is_empty() || - !AccumulateOpBounds(accumulator.bounds(), flags)) { + !AccumulateOpBounds(accumulator.GetBounds(), flags)) { return; } // Accumulating the bounds might not trip the overlap condition if the @@ -1582,7 +1569,7 @@ void DisplayListBuilder::DrawDisplayList(const sk_sp display_list, current_info().is_nop) { return; } - const SkRect bounds = display_list->bounds(); + const DlRect bounds = display_list->GetBounds(); bool accumulated; sk_sp rtree; if (display_list->root_is_unbounded()) { @@ -1590,10 +1577,10 @@ void DisplayListBuilder::DrawDisplayList(const sk_sp display_list, } else if (!rtree_data_.has_value() || !(rtree = display_list->rtree())) { accumulated = AccumulateOpBounds(bounds, kDrawDisplayListFlags); } else { - std::list rects = - rtree->searchAndConsolidateRects(GetLocalClipBounds(), false); + std::list rects = + rtree->searchAndConsolidateRects(GetLocalClipCoverage(), false); accumulated = false; - for (const SkRect& rect : rects) { + for (const DlRect& rect : rects) { // TODO (https://github.com/flutter/flutter/issues/114919): Attributes // are not necessarily `kDrawDisplayListFlags`. if (AccumulateOpBounds(rect, kDrawDisplayListFlags)) { @@ -1653,7 +1640,8 @@ void DisplayListBuilder::drawTextBlob(const sk_sp blob, if (result == OpResult::kNoEffect) { return; } - bool unclipped = AccumulateOpBounds(blob->bounds().makeOffset(x, y), flags); + DlRect bounds = ToDlRect(blob->bounds().makeOffset(x, y)); + bool unclipped = AccumulateOpBounds(bounds, flags); // TODO(https://github.com/flutter/flutter/issues/82202): Remove once the // unit tests can use Fuchsia's font manager instead of the empty default. // Until then we might encounter empty bounds for otherwise valid text and @@ -1689,10 +1677,8 @@ void DisplayListBuilder::drawTextFrame( if (result == OpResult::kNoEffect) { return; } - impeller::Rect bounds = text_frame->GetBounds(); - SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), - bounds.GetRight(), bounds.GetBottom()); - bool unclipped = AccumulateOpBounds(sk_bounds.makeOffset(x, y), flags); + DlRect bounds = text_frame->GetBounds().Shift(x, y); + bool unclipped = AccumulateOpBounds(bounds, flags); // TODO(https://github.com/flutter/flutter/issues/82202): Remove once the // unit tests can use Fuchsia's font manager instead of the empty default. // Until then we might encounter empty bounds for otherwise valid text and @@ -1728,8 +1714,8 @@ void DisplayListBuilder::DrawShadow(const DlPath& path, DlScalar dpr) { OpResult result = PaintResult(DlPaint(color)); if (result != OpResult::kNoEffect) { - SkRect shadow_bounds = DlCanvas::ComputeShadowBounds( - path.GetSkPath(), elevation, dpr, GetTransform()); + DlRect shadow_bounds = + DlCanvas::ComputeShadowBounds(path, elevation, dpr, GetMatrix()); if (AccumulateOpBounds(shadow_bounds, kDrawShadowFlags)) { transparent_occluder // ? Push(0, path, color, elevation, @@ -1741,7 +1727,7 @@ void DisplayListBuilder::DrawShadow(const DlPath& path, } } -bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds, +bool DisplayListBuilder::AdjustBoundsForPaint(DlRect& bounds, DisplayListAttributeFlags flags) { if (flags.ignores_paint()) { return true; @@ -1767,7 +1753,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds, } DlScalar min_stroke_width = 0.01; pad *= std::max(current_.getStrokeWidth() * 0.5f, min_stroke_width); - bounds.outset(pad, pad); + bounds = bounds.Expand(pad, pad); } } @@ -1778,7 +1764,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds, case DlMaskFilterType::kBlur: { FML_DCHECK(filter->asBlur()); DlScalar mask_sigma_pad = filter->asBlur()->sigma() * 3.0; - bounds.outset(mask_sigma_pad, mask_sigma_pad); + bounds = bounds.Expand(mask_sigma_pad, mask_sigma_pad); } } } @@ -1793,10 +1779,10 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds, auto filter = current_.getImageFilterPtr(); if (filter) { DlRect dl_bounds; - if (!filter->map_local_bounds(ToDlRect(bounds), dl_bounds)) { + if (!filter->map_local_bounds(bounds, dl_bounds)) { return false; } - bounds = ToSkRect(dl_bounds); + bounds = dl_bounds; } } @@ -1807,9 +1793,9 @@ bool DisplayListBuilder::AccumulateUnbounded(const SaveInfo& save) { if (!save.has_valid_clip) { save.layer_info->is_unbounded = true; } - SkRect global_clip = save.global_state.device_cull_rect(); - SkRect layer_clip = save.global_state.local_cull_rect(); - if (global_clip.isEmpty() || !save.layer_state.mapAndClipRect(&layer_clip)) { + DlRect global_clip = save.global_state.GetDeviceCullCoverage(); + DlRect layer_clip = save.global_state.GetLocalCullCoverage(); + if (global_clip.IsEmpty() || !save.layer_state.mapAndClipRect(&layer_clip)) { return false; } if (rtree_data_.has_value()) { @@ -1823,7 +1809,7 @@ bool DisplayListBuilder::AccumulateUnbounded(const SaveInfo& save) { return true; } -bool DisplayListBuilder::AccumulateOpBounds(SkRect& bounds, +bool DisplayListBuilder::AccumulateOpBounds(DlRect& bounds, DisplayListAttributeFlags flags) { if (AdjustBoundsForPaint(bounds, flags)) { return AccumulateBounds(bounds); @@ -1832,14 +1818,14 @@ bool DisplayListBuilder::AccumulateOpBounds(SkRect& bounds, } } -bool DisplayListBuilder::AccumulateBounds(const SkRect& bounds, +bool DisplayListBuilder::AccumulateBounds(const DlRect& bounds, SaveInfo& layer, int id) { - if (bounds.isEmpty()) { + if (bounds.IsEmpty()) { return false; } - SkRect global_bounds; - SkRect layer_bounds; + DlRect global_bounds; + DlRect layer_bounds; if (!layer.global_state.mapAndClipRect(bounds, &global_bounds) || !layer.layer_state.mapAndClipRect(bounds, &layer_bounds)) { return false; @@ -1857,11 +1843,11 @@ bool DisplayListBuilder::AccumulateBounds(const SkRect& bounds, return true; } -bool DisplayListBuilder::SaveInfo::AccumulateBoundsLocal(const SkRect& bounds) { - if (bounds.isEmpty()) { +bool DisplayListBuilder::SaveInfo::AccumulateBoundsLocal(const DlRect& bounds) { + if (bounds.IsEmpty()) { return false; } - SkRect local_bounds; + DlRect local_bounds; if (!layer_state.mapAndClipRect(bounds, &local_bounds)) { return false; } diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index 92dc9b83246c0..992e4eb6ae7d7 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -519,7 +519,7 @@ class DisplayListBuilder final : public virtual DlCanvas, void* Push(size_t extra, Args&&... args); struct RTreeData { - std::vector rects; + std::vector rects; std::vector indices; }; @@ -628,7 +628,7 @@ class DisplayListBuilder final : public virtual DlCanvas, // Records the given bounds after transforming by the global and // layer matrices. - bool AccumulateBoundsLocal(const SkRect& bounds); + bool AccumulateBoundsLocal(const DlRect& bounds); // Simply transfers the local bounds to the parent void TransferBoundsToParent(const SaveInfo& parent); @@ -698,7 +698,7 @@ class DisplayListBuilder final : public virtual DlCanvas, } void RestoreLayer(); - void TransferLayerBounds(const SkRect& content_bounds); + void TransferLayerBounds(const DlRect& content_bounds); bool AdjustRTreeRects(RTreeData& data, const DlImageFilter& filter, const DlMatrix& matrix, @@ -811,7 +811,7 @@ class DisplayListBuilder final : public virtual DlCanvas, // Adjusts the indicated bounds for the given flags and returns true if // the calculation was possible, or false if it could not be estimated. - bool AdjustBoundsForPaint(SkRect& bounds, DisplayListAttributeFlags flags); + bool AdjustBoundsForPaint(DlRect& bounds, DisplayListAttributeFlags flags); // Records the fact that we encountered an op that either could not // estimate its bounds or that fills all of the destination space. @@ -822,21 +822,21 @@ class DisplayListBuilder final : public virtual DlCanvas, // Records the bounds for an op after modifying them according to the // supplied attribute flags and transforming by the current matrix. - bool AccumulateOpBounds(const SkRect& bounds, + bool AccumulateOpBounds(const DlRect& bounds, DisplayListAttributeFlags flags) { - SkRect safe_bounds = bounds; + DlRect safe_bounds = bounds; return AccumulateOpBounds(safe_bounds, flags); } // Records the bounds for an op after modifying them according to the // supplied attribute flags and transforming by the current matrix // and clipping against the current clip. - bool AccumulateOpBounds(SkRect& bounds, DisplayListAttributeFlags flags); + bool AccumulateOpBounds(DlRect& bounds, DisplayListAttributeFlags flags); // Records the given bounds after transforming by the current matrix // and clipping against the current clip. - bool AccumulateBounds(const SkRect& bounds, SaveInfo& layer, int id); - bool AccumulateBounds(const SkRect& bounds) { + bool AccumulateBounds(const DlRect& bounds, SaveInfo& layer, int id); + bool AccumulateBounds(const DlRect& bounds) { return AccumulateBounds(bounds, current_info(), op_index_); } }; diff --git a/display_list/dl_vertices.h b/display_list/dl_vertices.h index 8a3bed3f4ca22..49bc38d250455 100644 --- a/display_list/dl_vertices.h +++ b/display_list/dl_vertices.h @@ -195,6 +195,7 @@ class DlVertices { /// Returns the bounds of the vertices. SkRect bounds() const { return bounds_; } + DlRect GetBounds() const { return ToDlRect(bounds_); } /// Returns the vertex mode that defines how the vertices (or the indices) /// are turned into triangles. diff --git a/display_list/geometry/dl_geometry_types.h b/display_list/geometry/dl_geometry_types.h index 6ee6c38385c36..54d70c75daac6 100644 --- a/display_list/geometry/dl_geometry_types.h +++ b/display_list/geometry/dl_geometry_types.h @@ -164,6 +164,10 @@ inline const SkRect* ToSkRects(const DlRect* rects) { return rects == nullptr ? nullptr : reinterpret_cast(rects); } +inline const SkIRect* ToSkIRects(const DlIRect* rects) { + return rects == nullptr ? nullptr : reinterpret_cast(rects); +} + inline const SkSize& ToSkSize(const DlSize& size) { return *reinterpret_cast(&size); } diff --git a/display_list/geometry/dl_path.h b/display_list/geometry/dl_path.h index f7d6ebe870948..a36458305c589 100644 --- a/display_list/geometry/dl_path.h +++ b/display_list/geometry/dl_path.h @@ -36,6 +36,7 @@ class DlPath { DlPath(const DlPath& path) = default; DlPath(DlPath&& path) = default; + DlPath& operator=(const DlPath&) = default; const SkPath& GetSkPath() const; impeller::Path GetPath() const; diff --git a/display_list/geometry/dl_region.cc b/display_list/geometry/dl_region.cc index 386e4e025b1c1..24fed57d1b105 100644 --- a/display_list/geometry/dl_region.cc +++ b/display_list/geometry/dl_region.cc @@ -94,13 +94,13 @@ void DlRegion::SpanBuffer::getSpans(SpanChunkHandle handle, end = begin + getChunkSize(handle); } -DlRegion::DlRegion(const std::vector& rects) { +DlRegion::DlRegion(const std::vector& rects) { setRects(rects); } -DlRegion::DlRegion(const SkIRect& rect) : bounds_(rect) { - Span span{rect.left(), rect.right()}; - lines_.push_back(makeLine(rect.top(), rect.bottom(), &span, &span + 1)); +DlRegion::DlRegion(const DlIRect& rect) : bounds_(rect) { + Span span{rect.GetLeft(), rect.GetRight()}; + lines_.push_back(makeLine(rect.GetTop(), rect.GetBottom(), &span, &span + 1)); } bool DlRegion::spansEqual(SpanLine& line, @@ -248,24 +248,24 @@ size_t DlRegion::intersectLineSpans(std::vector& res, return new_span - res.data(); } -void DlRegion::setRects(const std::vector& unsorted_rects) { +void DlRegion::setRects(const std::vector& unsorted_rects) { // setRects can only be called on empty regions. FML_DCHECK(lines_.empty()); size_t count = unsorted_rects.size(); - std::vector rects(count); + std::vector rects(count); for (size_t i = 0; i < count; i++) { rects[i] = &unsorted_rects[i]; - bounds_.join(unsorted_rects[i]); + bounds_ = bounds_.Union(unsorted_rects[i]); } - std::sort(rects.begin(), rects.end(), [](const SkIRect* a, const SkIRect* b) { - if (a->top() < b->top()) { + std::sort(rects.begin(), rects.end(), [](const DlIRect* a, const DlIRect* b) { + if (a->GetTop() < b->GetTop()) { return true; } - if (a->top() > b->top()) { + if (a->GetTop() > b->GetTop()) { return false; } - return a->left() < b->left(); + return a->GetLeft() < b->GetLeft(); }); size_t active_end = 0; @@ -284,8 +284,8 @@ void DlRegion::setRects(const std::vector& unsorted_rects) { // First prune passed rects out of the active list size_t preserve_end = 0; for (size_t i = 0; i < active_end; i++) { - const SkIRect* r = rects[i]; - if (r->bottom() > cur_y) { + const DlIRect* r = rects[i]; + if (r->GetBottom() > cur_y) { rects[preserve_end++] = r; } } @@ -298,24 +298,24 @@ void DlRegion::setRects(const std::vector& unsorted_rects) { // No active rects and no more rects to bring in. We are done. break; } - cur_y = rects[next_rect]->top(); + cur_y = rects[next_rect]->GetTop(); } // Next, insert any new rects we've reached into the active list while (next_rect < count) { - const SkIRect* r = rects[next_rect]; - if (r->isEmpty()) { + const DlIRect* r = rects[next_rect]; + if (r->IsEmpty()) { continue; } - if (r->top() > cur_y) { + if (r->GetTop() > cur_y) { break; } // We now know that we will be inserting this rect into active list next_rect++; size_t insert_at = active_end++; while (insert_at > 0) { - const SkIRect* ir = rects[insert_at - 1]; - if (ir->left() <= r->left()) { + const DlIRect* ir = rects[insert_at - 1]; + if (ir->GetLeft() <= r->GetLeft()) { break; } rects[insert_at--] = ir; @@ -336,27 +336,27 @@ void DlRegion::setRects(const std::vector& unsorted_rects) { // [start_x, end_x) always represents a valid span to be inserted // [cur_y, end_y) is the intersecting range over which all spans are valid - int32_t start_x = rects[0]->left(); - int32_t end_x = rects[0]->right(); - int32_t end_y = rects[0]->bottom(); + int32_t start_x = rects[0]->GetLeft(); + int32_t end_x = rects[0]->GetRight(); + int32_t end_y = rects[0]->GetBottom(); for (size_t i = 1; i < active_end; i++) { - const SkIRect* r = rects[i]; - if (r->left() > end_x) { + const DlIRect* r = rects[i]; + if (r->GetLeft() > end_x) { working_spans.emplace_back(start_x, end_x); - start_x = r->left(); - end_x = r->right(); - } else if (end_x < r->right()) { - end_x = r->right(); + start_x = r->GetLeft(); + end_x = r->GetRight(); + } else if (end_x < r->GetRight()) { + end_x = r->GetRight(); } - if (end_y > r->bottom()) { - end_y = r->bottom(); + if (end_y > r->GetBottom()) { + end_y = r->GetBottom(); } } working_spans.emplace_back(start_x, end_x); // end_y must not pass by the top of the next input rect - if (next_rect < count && end_y > rects[next_rect]->top()) { - end_y = rects[next_rect]->top(); + if (next_rect < count && end_y > rects[next_rect]->GetTop()) { + end_y = rects[next_rect]->GetTop(); } // If all of the rules above work out, we should never collapse the @@ -407,15 +407,14 @@ DlRegion DlRegion::MakeUnion(const DlRegion& a, const DlRegion& b) { return b; } else if (b.isEmpty()) { return a; - } else if (a.isSimple() && a.bounds_.contains(b.bounds_)) { + } else if (a.isSimple() && a.bounds_.Contains(b.bounds_)) { return a; - } else if (b.isSimple() && b.bounds_.contains(a.bounds_)) { + } else if (b.isSimple() && b.bounds_.Contains(a.bounds_)) { return b; } DlRegion res; - res.bounds_ = a.bounds_; - res.bounds_.join(b.bounds_); + res.bounds_ = a.bounds_.Union(b.bounds_); res.span_buffer_.reserve(a.span_buffer_.capacity() + b.span_buffer_.capacity()); @@ -495,17 +494,15 @@ DlRegion DlRegion::MakeUnion(const DlRegion& a, const DlRegion& b) { } DlRegion DlRegion::MakeIntersection(const DlRegion& a, const DlRegion& b) { - if (!SkIRect::Intersects(a.bounds_, b.bounds_)) { + if (!a.bounds_.IntersectsWithRect(b.bounds_)) { return DlRegion(); } else if (a.isSimple() && b.isSimple()) { - SkIRect r(a.bounds_); - [[maybe_unused]] - auto res = r.intersect(b.bounds_); - FML_DCHECK(res); - return DlRegion(r); - } else if (a.isSimple() && a.bounds_.contains(b.bounds_)) { + auto res = a.bounds_.Intersection(b.bounds_); + FML_DCHECK(res.has_value()); + return res.has_value() ? DlRegion(res.value()) : DlRegion(); + } else if (a.isSimple() && a.bounds_.Contains(b.bounds_)) { return b; - } else if (b.isSimple() && b.bounds_.contains(a.bounds_)) { + } else if (b.isSimple() && b.bounds_.Contains(a.bounds_)) { return a; } @@ -544,7 +541,7 @@ DlRegion DlRegion::MakeIntersection(const DlRegion& a, const DlRegion& b) { b_buffer, b_it->chunk_handle); if (size > 0) { res.appendLine(top, bottom, tmp.data(), tmp.data() + size); - res.bounds_.join(SkIRect::MakeLTRB( + res.bounds_ = res.bounds_.Union(DlIRect::MakeLTRB( tmp.data()->left, top, (tmp.data() + size - 1)->right, bottom)); } cur_top = bottom; @@ -560,8 +557,8 @@ DlRegion DlRegion::MakeIntersection(const DlRegion& a, const DlRegion& b) { return res; } -std::vector DlRegion::getRects(bool deband) const { - std::vector rects; +std::vector DlRegion::getRects(bool deband) const { + std::vector rects; if (isEmpty()) { return rects; } else if (isSimple()) { @@ -580,7 +577,7 @@ std::vector DlRegion::getRects(bool deband) const { const Span *span_begin, *span_end; span_buffer_.getSpans(line.chunk_handle, span_begin, span_end); for (const auto* span = span_begin; span < span_end; ++span) { - SkIRect rect{span->left, line.top, span->right, line.bottom}; + int32_t top = line.top; if (deband) { auto iter = rects.begin() + previous_span_end; // If there is rectangle previously in rects on which this one is a @@ -588,20 +585,21 @@ std::vector DlRegion::getRects(bool deband) const { // this one vertically to cover the area. while (iter != rects.begin()) { --iter; - if (iter->bottom() < rect.top()) { + if (iter->GetBottom() < top) { // Went all the way to previous span line. break; - } else if (iter->left() == rect.left() && - iter->right() == rect.right()) { - FML_DCHECK(iter->bottom() == rect.top()); - rect.fTop = iter->fTop; + } else if (iter->GetLeft() == span->left && + iter->GetRight() == span->right) { + FML_DCHECK(iter->GetBottom() == top); + top = iter->GetTop(); rects.erase(iter); --previous_span_end; break; } } } - rects.push_back(rect); + rects.push_back( + DlIRect::MakeLTRB(span->left, top, span->right, line.bottom)); } previous_span_end = rects.size(); } @@ -614,12 +612,12 @@ bool DlRegion::isComplex() const { span_buffer_.getChunkSize(lines_.front().chunk_handle) > 1); } -bool DlRegion::intersects(const SkIRect& rect) const { +bool DlRegion::intersects(const DlIRect& rect) const { if (isEmpty()) { return false; } - auto bounds_intersect = SkIRect::Intersects(bounds_, rect); + auto bounds_intersect = bounds_.IntersectsWithRect(rect); if (isSimple()) { return bounds_intersect; @@ -632,22 +630,23 @@ bool DlRegion::intersects(const SkIRect& rect) const { auto it = lines_.begin(); auto end = lines_.end(); if (lines_.size() > kBinarySearchThreshold && - it[kBinarySearchThreshold].bottom <= rect.fTop) { + it[kBinarySearchThreshold].bottom <= rect.GetTop()) { it = std::lower_bound( - lines_.begin() + kBinarySearchThreshold + 1, lines_.end(), rect.fTop, + lines_.begin() + kBinarySearchThreshold + 1, lines_.end(), + rect.GetTop(), [](const SpanLine& line, int32_t top) { return line.bottom <= top; }); } else { - while (it != end && it->bottom <= rect.fTop) { + while (it != end && it->bottom <= rect.GetTop()) { ++it; continue; } } - while (it != end && it->top < rect.fBottom) { - FML_DCHECK(rect.fTop < it->bottom && it->top < rect.fBottom); + while (it != end && it->top < rect.GetBottom()) { + FML_DCHECK(rect.GetTop() < it->bottom && it->top < rect.GetBottom()); const Span *begin, *end; span_buffer_.getSpans(it->chunk_handle, begin, end); - while (begin != end && begin->left < rect.fRight) { - if (begin->right > rect.fLeft) { + while (begin != end && begin->left < rect.GetRight()) { + if (begin->right > rect.GetLeft()) { return true; } ++begin; @@ -709,7 +708,7 @@ bool DlRegion::intersects(const DlRegion& region) const { auto our_complex = isComplex(); auto their_complex = region.isComplex(); - auto bounds_intersect = SkIRect::Intersects(bounds_, region.bounds_); + auto bounds_intersect = bounds_.IntersectsWithRect(region.bounds_); if (!our_complex && !their_complex) { return bounds_intersect; diff --git a/display_list/geometry/dl_region.h b/display_list/geometry/dl_region.h index 170a67cbffa92..1e3c824e4ba98 100644 --- a/display_list/geometry/dl_region.h +++ b/display_list/geometry/dl_region.h @@ -5,11 +5,11 @@ #ifndef FLUTTER_DISPLAY_LIST_GEOMETRY_DL_REGION_H_ #define FLUTTER_DISPLAY_LIST_GEOMETRY_DL_REGION_H_ -#include "third_party/skia/include/core/SkRect.h" - #include #include +#include "flutter/display_list/geometry/dl_geometry_types.h" + namespace flutter { /// Represents a region as a collection of non-overlapping rectangles. @@ -22,10 +22,10 @@ class DlRegion { /// Creates region by bulk adding the rectangles. /// Matches SkRegion::op(rect, SkRegion::kUnion_Op) behavior. - explicit DlRegion(const std::vector& rects); + explicit DlRegion(const std::vector& rects); /// Creates region covering area of a rectangle. - explicit DlRegion(const SkIRect& rect); + explicit DlRegion(const DlIRect& rect); DlRegion(const DlRegion&) = default; DlRegion(DlRegion&&) = default; @@ -46,14 +46,17 @@ class DlRegion { /// closely matching SkRegion::Iterator behavior. /// If |deband| is true, matching rectangles from adjacent span lines will be /// merged into single rectangle. - std::vector getRects(bool deband = true) const; + std::vector getRects(bool deband = true) const; /// Returns maximum and minimum axis values of rectangles in this region. /// If region is empty returns SKIRect::MakeEmpty(). - const SkIRect& bounds() const { return bounds_; } + const DlIRect& bounds() const { return bounds_; } /// Returns whether this region intersects with a rectangle. - bool intersects(const SkIRect& rect) const; + bool intersects(const DlIRect& rect) const; + bool intersects(const SkIRect& rect) const { + return intersects(ToDlIRect(rect)); + } /// Returns whether this region intersects with another region. bool intersects(const DlRegion& region) const; @@ -118,7 +121,7 @@ class DlRegion { SpanChunkHandle chunk_handle; }; - void setRects(const std::vector& rects); + void setRects(const std::vector& rects); void appendLine(int32_t top, int32_t bottom, @@ -164,7 +167,7 @@ class DlRegion { std::vector::const_iterator& b_it); std::vector lines_; - SkIRect bounds_ = SkIRect::MakeEmpty(); + DlIRect bounds_; SpanBuffer span_buffer_; }; diff --git a/display_list/geometry/dl_region_unittests.cc b/display_list/geometry/dl_region_unittests.cc index 1f03f89fc6d5a..c2fe9526e0b32 100644 --- a/display_list/geometry/dl_region_unittests.cc +++ b/display_list/geometry/dl_region_unittests.cc @@ -19,107 +19,122 @@ TEST(DisplayListRegion, EmptyRegion) { } TEST(DisplayListRegion, SingleRectangle) { - DlRegion region({SkIRect::MakeLTRB(10, 10, 50, 50)}); + DlRegion region({DlIRect::MakeLTRB(10, 10, 50, 50)}); auto rects = region.getRects(); ASSERT_EQ(rects.size(), 1u); - EXPECT_EQ(rects.front(), SkIRect::MakeLTRB(10, 10, 50, 50)); + EXPECT_EQ(rects.front(), DlIRect::MakeLTRB(10, 10, 50, 50)); } TEST(DisplayListRegion, NonOverlappingRectangles1) { - std::vector rects_in; + std::vector rects_in; for (int i = 0; i < 10; ++i) { - SkIRect rect = SkIRect::MakeXYWH(50 * i, 50 * i, 50, 50); + DlIRect rect = DlIRect::MakeXYWH(50 * i, 50 * i, 50, 50); rects_in.push_back(rect); } DlRegion region(rects_in); auto rects = region.getRects(); - std::vector expected{ - {0, 0, 50, 50}, {50, 50, 100, 100}, {100, 100, 150, 150}, - {150, 150, 200, 200}, {200, 200, 250, 250}, {250, 250, 300, 300}, - {300, 300, 350, 350}, {350, 350, 400, 400}, {400, 400, 450, 450}, - {450, 450, 500, 500}, + std::vector expected{ + DlIRect::MakeLTRB(0, 0, 50, 50), + DlIRect::MakeLTRB(50, 50, 100, 100), + DlIRect::MakeLTRB(100, 100, 150, 150), + DlIRect::MakeLTRB(150, 150, 200, 200), + DlIRect::MakeLTRB(200, 200, 250, 250), + DlIRect::MakeLTRB(250, 250, 300, 300), + DlIRect::MakeLTRB(300, 300, 350, 350), + DlIRect::MakeLTRB(350, 350, 400, 400), + DlIRect::MakeLTRB(400, 400, 450, 450), + DlIRect::MakeLTRB(450, 450, 500, 500), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, NonOverlappingRectangles2) { DlRegion region({ - SkIRect::MakeXYWH(5, 5, 10, 10), - SkIRect::MakeXYWH(25, 5, 10, 10), - SkIRect::MakeXYWH(5, 25, 10, 10), - SkIRect::MakeXYWH(25, 25, 10, 10), + DlIRect::MakeXYWH(5, 5, 10, 10), + DlIRect::MakeXYWH(25, 5, 10, 10), + DlIRect::MakeXYWH(5, 25, 10, 10), + DlIRect::MakeXYWH(25, 25, 10, 10), }); auto rects = region.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(5, 5, 10, 10), - SkIRect::MakeXYWH(25, 5, 10, 10), - SkIRect::MakeXYWH(5, 25, 10, 10), - SkIRect::MakeXYWH(25, 25, 10, 10), + std::vector expected{ + DlIRect::MakeXYWH(5, 5, 10, 10), + DlIRect::MakeXYWH(25, 5, 10, 10), + DlIRect::MakeXYWH(5, 25, 10, 10), + DlIRect::MakeXYWH(25, 25, 10, 10), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, NonOverlappingRectangles3) { DlRegion region({ - SkIRect::MakeXYWH(0, 0, 10, 10), - SkIRect::MakeXYWH(-11, -11, 10, 10), - SkIRect::MakeXYWH(11, 11, 10, 10), - SkIRect::MakeXYWH(-11, 0, 10, 10), - SkIRect::MakeXYWH(0, 11, 10, 10), - SkIRect::MakeXYWH(0, -11, 10, 10), - SkIRect::MakeXYWH(11, 0, 10, 10), - SkIRect::MakeXYWH(11, -11, 10, 10), - SkIRect::MakeXYWH(-11, 11, 10, 10), + DlIRect::MakeXYWH(0, 0, 10, 10), + DlIRect::MakeXYWH(-11, -11, 10, 10), + DlIRect::MakeXYWH(11, 11, 10, 10), + DlIRect::MakeXYWH(-11, 0, 10, 10), + DlIRect::MakeXYWH(0, 11, 10, 10), + DlIRect::MakeXYWH(0, -11, 10, 10), + DlIRect::MakeXYWH(11, 0, 10, 10), + DlIRect::MakeXYWH(11, -11, 10, 10), + DlIRect::MakeXYWH(-11, 11, 10, 10), }); auto rects = region.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(-11, -11, 10, 10), // - SkIRect::MakeXYWH(0, -11, 10, 10), // - SkIRect::MakeXYWH(11, -11, 10, 10), // - SkIRect::MakeXYWH(-11, 0, 10, 10), // - SkIRect::MakeXYWH(0, 0, 10, 10), // - SkIRect::MakeXYWH(11, 0, 10, 10), // - SkIRect::MakeXYWH(-11, 11, 10, 10), // - SkIRect::MakeXYWH(0, 11, 10, 10), // - SkIRect::MakeXYWH(11, 11, 10, 10), + std::vector expected{ + DlIRect::MakeXYWH(-11, -11, 10, 10), // + DlIRect::MakeXYWH(0, -11, 10, 10), // + DlIRect::MakeXYWH(11, -11, 10, 10), // + DlIRect::MakeXYWH(-11, 0, 10, 10), // + DlIRect::MakeXYWH(0, 0, 10, 10), // + DlIRect::MakeXYWH(11, 0, 10, 10), // + DlIRect::MakeXYWH(-11, 11, 10, 10), // + DlIRect::MakeXYWH(0, 11, 10, 10), // + DlIRect::MakeXYWH(11, 11, 10, 10), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, MergeTouchingRectangles) { DlRegion region({ - SkIRect::MakeXYWH(0, 0, 10, 10), - SkIRect::MakeXYWH(-10, -10, 10, 10), - SkIRect::MakeXYWH(10, 10, 10, 10), - SkIRect::MakeXYWH(-10, 0, 10, 10), - SkIRect::MakeXYWH(0, 10, 10, 10), - SkIRect::MakeXYWH(0, -10, 10, 10), - SkIRect::MakeXYWH(10, 0, 10, 10), - SkIRect::MakeXYWH(10, -10, 10, 10), - SkIRect::MakeXYWH(-10, 10, 10, 10), + DlIRect::MakeXYWH(0, 0, 10, 10), + DlIRect::MakeXYWH(-10, -10, 10, 10), + DlIRect::MakeXYWH(10, 10, 10, 10), + DlIRect::MakeXYWH(-10, 0, 10, 10), + DlIRect::MakeXYWH(0, 10, 10, 10), + DlIRect::MakeXYWH(0, -10, 10, 10), + DlIRect::MakeXYWH(10, 0, 10, 10), + DlIRect::MakeXYWH(10, -10, 10, 10), + DlIRect::MakeXYWH(-10, 10, 10, 10), }); auto rects = region.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(-10, -10, 30, 30), + std::vector expected{ + DlIRect::MakeXYWH(-10, -10, 30, 30), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, OverlappingRectangles) { - std::vector rects_in; + std::vector rects_in; for (int i = 0; i < 10; ++i) { - SkIRect rect = SkIRect::MakeXYWH(10 * i, 10 * i, 50, 50); + DlIRect rect = DlIRect::MakeXYWH(10 * i, 10 * i, 50, 50); rects_in.push_back(rect); } DlRegion region(rects_in); auto rects = region.getRects(); - std::vector expected{ - {0, 0, 50, 10}, {0, 10, 60, 20}, {0, 20, 70, 30}, - {0, 30, 80, 40}, {0, 40, 90, 50}, {10, 50, 100, 60}, - {20, 60, 110, 70}, {30, 70, 120, 80}, {40, 80, 130, 90}, - {50, 90, 140, 100}, {60, 100, 140, 110}, {70, 110, 140, 120}, - {80, 120, 140, 130}, {90, 130, 140, 140}, + std::vector expected{ + DlIRect::MakeLTRB(0, 0, 50, 10), + DlIRect::MakeLTRB(0, 10, 60, 20), + DlIRect::MakeLTRB(0, 20, 70, 30), + DlIRect::MakeLTRB(0, 30, 80, 40), + DlIRect::MakeLTRB(0, 40, 90, 50), + DlIRect::MakeLTRB(10, 50, 100, 60), + DlIRect::MakeLTRB(20, 60, 110, 70), + DlIRect::MakeLTRB(30, 70, 120, 80), + DlIRect::MakeLTRB(40, 80, 130, 90), + DlIRect::MakeLTRB(50, 90, 140, 100), + DlIRect::MakeLTRB(60, 100, 140, 110), + DlIRect::MakeLTRB(70, 110, 140, 120), + DlIRect::MakeLTRB(80, 120, 140, 130), + DlIRect::MakeLTRB(90, 130, 140, 140), }; EXPECT_EQ(rects, expected); @@ -127,38 +142,38 @@ TEST(DisplayListRegion, OverlappingRectangles) { TEST(DisplayListRegion, Deband) { DlRegion region({ - SkIRect::MakeXYWH(0, 0, 50, 50), - SkIRect::MakeXYWH(60, 0, 20, 20), - SkIRect::MakeXYWH(90, 0, 50, 50), + DlIRect::MakeXYWH(0, 0, 50, 50), + DlIRect::MakeXYWH(60, 0, 20, 20), + DlIRect::MakeXYWH(90, 0, 50, 50), }); auto rects_with_deband = region.getRects(true); - std::vector expected{ - SkIRect::MakeXYWH(60, 0, 20, 20), - SkIRect::MakeXYWH(0, 0, 50, 50), - SkIRect::MakeXYWH(90, 0, 50, 50), + std::vector expected{ + DlIRect::MakeXYWH(60, 0, 20, 20), + DlIRect::MakeXYWH(0, 0, 50, 50), + DlIRect::MakeXYWH(90, 0, 50, 50), }; EXPECT_EQ(rects_with_deband, expected); auto rects_without_deband = region.getRects(false); - std::vector expected_without_deband{ - SkIRect::MakeXYWH(0, 0, 50, 20), // - SkIRect::MakeXYWH(60, 0, 20, 20), // - SkIRect::MakeXYWH(90, 0, 50, 20), // - SkIRect::MakeXYWH(0, 20, 50, 30), // - SkIRect::MakeXYWH(90, 20, 50, 30), + std::vector expected_without_deband{ + DlIRect::MakeXYWH(0, 0, 50, 20), // + DlIRect::MakeXYWH(60, 0, 20, 20), // + DlIRect::MakeXYWH(90, 0, 50, 20), // + DlIRect::MakeXYWH(0, 20, 50, 30), // + DlIRect::MakeXYWH(90, 20, 50, 30), }; EXPECT_EQ(rects_without_deband, expected_without_deband); } TEST(DisplayListRegion, Intersects1) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(20, 0, 20, 20), - SkIRect::MakeXYWH(0, 20, 20, 20), + DlIRect::MakeXYWH(20, 0, 20, 20), + DlIRect::MakeXYWH(0, 20, 20, 20), }); EXPECT_FALSE(region1.intersects(region2)); EXPECT_FALSE(region2.intersects(region1)); @@ -166,29 +181,29 @@ TEST(DisplayListRegion, Intersects1) { EXPECT_TRUE(region1.intersects(region2.bounds())); EXPECT_TRUE(region2.intersects(region1.bounds())); - EXPECT_TRUE(region1.intersects(SkIRect::MakeXYWH(0, 0, 20, 20))); - EXPECT_FALSE(region1.intersects(SkIRect::MakeXYWH(20, 0, 20, 20))); + EXPECT_TRUE(region1.intersects(DlIRect::MakeXYWH(0, 0, 20, 20))); + EXPECT_FALSE(region1.intersects(DlIRect::MakeXYWH(20, 0, 20, 20))); EXPECT_TRUE(region1.intersects( - DlRegion(std::vector{SkIRect::MakeXYWH(0, 0, 20, 20)}))); + DlRegion(std::vector{DlIRect::MakeXYWH(0, 0, 20, 20)}))); EXPECT_FALSE(region1.intersects( - DlRegion(std::vector{SkIRect::MakeXYWH(20, 0, 20, 20)}))); + DlRegion(std::vector{DlIRect::MakeXYWH(20, 0, 20, 20)}))); - EXPECT_FALSE(region1.intersects(SkIRect::MakeXYWH(-1, -1, 1, 1))); - EXPECT_TRUE(region1.intersects(SkIRect::MakeXYWH(0, 0, 1, 1))); + EXPECT_FALSE(region1.intersects(DlIRect::MakeXYWH(-1, -1, 1, 1))); + EXPECT_TRUE(region1.intersects(DlIRect::MakeXYWH(0, 0, 1, 1))); - EXPECT_FALSE(region1.intersects(SkIRect::MakeXYWH(40, 40, 1, 1))); - EXPECT_TRUE(region1.intersects(SkIRect::MakeXYWH(39, 39, 1, 1))); + EXPECT_FALSE(region1.intersects(DlIRect::MakeXYWH(40, 40, 1, 1))); + EXPECT_TRUE(region1.intersects(DlIRect::MakeXYWH(39, 39, 1, 1))); } TEST(DisplayListRegion, Intersects2) { DlRegion region1({ - SkIRect::MakeXYWH(-10, -10, 20, 20), - SkIRect::MakeXYWH(-30, -30, 20, 20), + DlIRect::MakeXYWH(-10, -10, 20, 20), + DlIRect::MakeXYWH(-30, -30, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(20, 20, 5, 5), - SkIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 5, 5), + DlIRect::MakeXYWH(0, 0, 20, 20), }); EXPECT_TRUE(region1.intersects(region2)); EXPECT_TRUE(region2.intersects(region1)); @@ -196,15 +211,15 @@ TEST(DisplayListRegion, Intersects2) { TEST(DisplayListRegion, Intersection1) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(20, 0, 20, 20), - SkIRect::MakeXYWH(0, 20, 20, 20), + DlIRect::MakeXYWH(20, 0, 20, 20), + DlIRect::MakeXYWH(0, 20, 20, 20), }); DlRegion i = DlRegion::MakeIntersection(region1, region2); - EXPECT_EQ(i.bounds(), SkIRect::MakeEmpty()); + EXPECT_EQ(i.bounds(), DlIRect()); EXPECT_TRUE(i.isEmpty()); auto rects = i.getRects(); EXPECT_TRUE(rects.empty()); @@ -212,146 +227,146 @@ TEST(DisplayListRegion, Intersection1) { TEST(DisplayListRegion, Intersection2) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }); DlRegion i = DlRegion::MakeIntersection(region1, region2); - EXPECT_EQ(i.bounds(), SkIRect::MakeXYWH(0, 0, 40, 40)); + EXPECT_EQ(i.bounds(), DlIRect::MakeXYWH(0, 0, 40, 40)); auto rects = i.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, Intersection3) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(-10, -10, 20, 20), - SkIRect::MakeXYWH(10, 10, 20, 20), + DlIRect::MakeXYWH(-10, -10, 20, 20), + DlIRect::MakeXYWH(10, 10, 20, 20), }); DlRegion i = DlRegion::MakeIntersection(region1, region2); - EXPECT_EQ(i.bounds(), SkIRect::MakeXYWH(0, 0, 20, 20)); + EXPECT_EQ(i.bounds(), DlIRect::MakeXYWH(0, 0, 20, 20)); auto rects = i.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 10, 10), - SkIRect::MakeXYWH(10, 10, 10, 10), + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 10, 10), + DlIRect::MakeXYWH(10, 10, 10, 10), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, Union1) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(20, 20, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(20, 20, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(20, 0, 20, 20), - SkIRect::MakeXYWH(0, 20, 20, 20), + DlIRect::MakeXYWH(20, 0, 20, 20), + DlIRect::MakeXYWH(0, 20, 20, 20), }); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeXYWH(0, 0, 40, 40)); + EXPECT_EQ(u.bounds(), DlIRect::MakeXYWH(0, 0, 40, 40)); EXPECT_TRUE(u.isSimple()); auto rects = u.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 40, 40), // + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 40, 40), // }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, Union2) { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(21, 21, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(21, 21, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(21, 0, 20, 20), - SkIRect::MakeXYWH(0, 21, 20, 20), + DlIRect::MakeXYWH(21, 0, 20, 20), + DlIRect::MakeXYWH(0, 21, 20, 20), }); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeXYWH(0, 0, 41, 41)); + EXPECT_EQ(u.bounds(), DlIRect::MakeXYWH(0, 0, 41, 41)); auto rects = u.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 20, 20), - SkIRect::MakeXYWH(21, 0, 20, 20), - SkIRect::MakeXYWH(0, 21, 20, 20), - SkIRect::MakeXYWH(21, 21, 20, 20), + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(21, 0, 20, 20), + DlIRect::MakeXYWH(0, 21, 20, 20), + DlIRect::MakeXYWH(21, 21, 20, 20), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, Union3) { DlRegion region1({ - SkIRect::MakeXYWH(-10, -10, 20, 20), + DlIRect::MakeXYWH(-10, -10, 20, 20), }); DlRegion region2({ - SkIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), }); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeXYWH(-10, -10, 30, 30)); + EXPECT_EQ(u.bounds(), DlIRect::MakeXYWH(-10, -10, 30, 30)); auto rects = u.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(-10, -10, 20, 10), - SkIRect::MakeXYWH(-10, 0, 30, 10), - SkIRect::MakeXYWH(0, 10, 20, 10), + std::vector expected{ + DlIRect::MakeXYWH(-10, -10, 20, 10), + DlIRect::MakeXYWH(-10, 0, 30, 10), + DlIRect::MakeXYWH(0, 10, 20, 10), }; EXPECT_EQ(rects, expected); } TEST(DisplayListRegion, UnionEmpty) { { - DlRegion region1(std::vector{}); - DlRegion region2(std::vector{}); + DlRegion region1(std::vector{}); + DlRegion region2(std::vector{}); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeEmpty()); + EXPECT_EQ(u.bounds(), DlIRect()); EXPECT_TRUE(u.isEmpty()); auto rects = u.getRects(); EXPECT_TRUE(rects.empty()); } { - DlRegion region1(std::vector{}); + DlRegion region1(std::vector{}); DlRegion region2({ - SkIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), }); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeXYWH(0, 0, 20, 20)); + EXPECT_EQ(u.bounds(), DlIRect::MakeXYWH(0, 0, 20, 20)); auto rects = u.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 20, 20), + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 20, 20), }; } { DlRegion region1({ - SkIRect::MakeXYWH(0, 0, 20, 20), + DlIRect::MakeXYWH(0, 0, 20, 20), }); - DlRegion region2(std::vector{}); + DlRegion region2(std::vector{}); DlRegion u = DlRegion::MakeUnion(region1, region2); - EXPECT_EQ(u.bounds(), SkIRect::MakeXYWH(0, 0, 20, 20)); + EXPECT_EQ(u.bounds(), DlIRect::MakeXYWH(0, 0, 20, 20)); auto rects = u.getRects(); - std::vector expected{ - SkIRect::MakeXYWH(0, 0, 20, 20), + std::vector expected{ + DlIRect::MakeXYWH(0, 0, 20, 20), }; } } void CheckEquality(const DlRegion& dl_region, const SkRegion& sk_region) { - EXPECT_EQ(dl_region.bounds(), sk_region.getBounds()); + EXPECT_EQ(dl_region.bounds(), ToDlIRect(sk_region.getBounds())); // Do not deband the rectangles - identical to SkRegion::Iterator auto rects = dl_region.getRects(false); - std::vector skia_rects; + std::vector skia_rects; auto iterator = SkRegion::Iterator(sk_region); while (!iterator.done()) { - skia_rects.push_back(iterator.rect()); + skia_rects.push_back(ToDlIRect(iterator.rect())); iterator.next(); } @@ -379,27 +394,27 @@ TEST(DisplayListRegion, TestAgainstSkRegion) { std::uniform_int_distribution pos(0, 4000); std::uniform_int_distribution size(1, settings.max_size); - std::vector rects_in1; - std::vector rects_in2; + std::vector rects_in1; + std::vector rects_in2; for (size_t i = 0; i < iterations_1; ++i) { - SkIRect rect = - SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = + DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects_in1.push_back(rect); } for (size_t i = 0; i < iterations_2; ++i) { - SkIRect rect = - SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); + DlIRect rect = + DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng)); rects_in2.push_back(rect); } DlRegion region1(rects_in1); - sk_region1.setRects(rects_in1.data(), rects_in1.size()); + sk_region1.setRects(ToSkIRects(rects_in1.data()), rects_in1.size()); CheckEquality(region1, sk_region1); DlRegion region2(rects_in2); - sk_region2.setRects(rects_in2.data(), rects_in2.size()); + sk_region2.setRects(ToSkIRects(rects_in2.data()), rects_in2.size()); CheckEquality(region2, sk_region2); auto intersects_1 = region1.intersects(region2); @@ -411,7 +426,8 @@ TEST(DisplayListRegion, TestAgainstSkRegion) { { auto rects = region2.getRects(true); for (const auto& r : rects) { - EXPECT_EQ(region1.intersects(r), sk_region1.intersects(r)); + EXPECT_EQ(region1.intersects(r), + sk_region1.intersects(ToSkIRect(r))); } } diff --git a/display_list/geometry/dl_rtree.cc b/display_list/geometry/dl_rtree.cc index 1b51a436e2a33..55d5c89638522 100644 --- a/display_list/geometry/dl_rtree.cc +++ b/display_list/geometry/dl_rtree.cc @@ -9,7 +9,7 @@ namespace flutter { -DlRTree::DlRTree(const SkRect rects[], +DlRTree::DlRTree(const DlRect rects[], int N, const int ids[], bool p(int), @@ -26,7 +26,7 @@ DlRTree::DlRTree(const SkRect rects[], // ID is not filtered by the predicate. int leaf_count = 0; for (int i = 0; i < N; i++) { - if (!rects[i].isEmpty()) { + if (!rects[i].IsEmpty()) { if (ids == nullptr || p(ids[i])) { leaf_count++; } @@ -51,7 +51,7 @@ DlRTree::DlRTree(const SkRect rects[], int leaf_index = 0; int id = invalid_id; for (int i = 0; i < N; i++) { - if (!rects[i].isEmpty()) { + if (!rects[i].IsEmpty()) { if (ids == nullptr || p(id = ids[i])) { Node& node = nodes_[leaf_index++]; node.bounds = rects[i]; @@ -122,12 +122,12 @@ DlRTree::DlRTree(const SkRect rects[], D -= gen_count; FML_DCHECK(parent_index < gen_end + family_count); parent = &nodes_[parent_index++]; - parent->bounds.setEmpty(); + parent->bounds = kEmpty; parent->child.index = sibling_index; parent->child.count = 0; } FML_DCHECK(parent != nullptr); - parent->bounds.join(nodes_[sibling_index++].bounds); + parent->bounds = parent->bounds.Union(nodes_[sibling_index++].bounds); parent->child.count++; } FML_DCHECK(D == 0); @@ -139,9 +139,9 @@ DlRTree::DlRTree(const SkRect rects[], FML_DCHECK(gen_start + gen_count == total_node_count); } -void DlRTree::search(const SkRect& query, std::vector* results) const { +void DlRTree::search(const DlRect& query, std::vector* results) const { FML_DCHECK(results != nullptr); - if (query.isEmpty()) { + if (query.IsEmpty()) { return; } if (nodes_.size() <= 0) { @@ -149,7 +149,7 @@ void DlRTree::search(const SkRect& query, std::vector* results) const { return; } const Node& root = nodes_.back(); - if (root.bounds.intersects(query)) { + if (root.bounds.IntersectsWithRect(query)) { if (nodes_.size() == 1) { FML_DCHECK(leaf_count_ == 1); // The root node is the only node and it is a leaf node @@ -160,38 +160,37 @@ void DlRTree::search(const SkRect& query, std::vector* results) const { } } -std::list DlRTree::searchAndConsolidateRects(const SkRect& query, +std::list DlRTree::searchAndConsolidateRects(const DlRect& query, bool deband) const { // Get the indexes for the operations that intersect with the query rect. std::vector intermediary_results; search(query, &intermediary_results); - std::vector rects; + std::vector rects; rects.reserve(intermediary_results.size()); for (int index : intermediary_results) { - SkIRect current_record_rect; - bounds(index).roundOut(¤t_record_rect); + DlIRect current_record_rect = DlIRect::RoundOut(bounds(index)); rects.push_back(current_record_rect); } DlRegion region(rects); auto non_overlapping_rects = region.getRects(deband); - std::list final_results; + std::list final_results; for (const auto& rect : non_overlapping_rects) { - final_results.push_back(SkRect::Make(rect)); + final_results.push_back(DlRect::Make(rect)); } return final_results; } void DlRTree::search(const Node& parent, - const SkRect& query, + const DlRect& query, std::vector* results) const { // Caller protects against empty query int start = parent.child.index; int end = start + parent.child.count; for (int i = start; i < end; i++) { const Node& node = nodes_[i]; - if (node.bounds.intersects(query)) { + if (node.bounds.IntersectsWithRect(query)) { if (i < leaf_count_) { results->push_back(i); } else { @@ -203,17 +202,17 @@ void DlRTree::search(const Node& parent, const DlRegion& DlRTree::region() const { if (!region_) { - std::vector rects; + std::vector rects; rects.resize(leaf_count_); for (int i = 0; i < leaf_count_; i++) { - nodes_[i].bounds.roundOut(&rects[i]); + rects[i] = DlIRect::RoundOut(nodes_[i].bounds); } region_.emplace(rects); } return *region_; } -const SkRect& DlRTree::bounds() const { +const DlRect& DlRTree::bounds() const { if (!nodes_.empty()) { return nodes_.back().bounds; } else { diff --git a/display_list/geometry/dl_rtree.h b/display_list/geometry/dl_rtree.h index a60e4e9d77c44..d3ccb3f894582 100644 --- a/display_list/geometry/dl_rtree.h +++ b/display_list/geometry/dl_rtree.h @@ -11,8 +11,6 @@ #include "flutter/display_list/geometry/dl_region.h" #include "flutter/fml/logging.h" -#include "third_party/skia/include/core/SkColorSpace.h" -#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRefCnt.h" namespace flutter { @@ -33,7 +31,7 @@ class DlRTree : public SkRefCnt { // Leaf nodes at start of vector have an ID, // Internal nodes after that have child index and count. struct Node { - SkRect bounds; + DlRect bounds; union { struct { uint32_t index; @@ -62,7 +60,7 @@ class DlRTree : public SkRefCnt { /// way except to eliminate invalid rectangles and IDs that are rejected /// by the optional predicate function. DlRTree( - const SkRect rects[], + const DlRect rects[], int N, const int ids[] = nullptr, bool predicate(int id) = [](int) { return true; }, @@ -78,7 +76,7 @@ class DlRTree : public SkRefCnt { /// which they were passed into the constructor. The actual rectangle /// and ID associated with each index can be retrieved using the /// |DlRTree::id| and |DlRTree::bounds| methods. - void search(const SkRect& query, std::vector* results) const; + void search(const DlRect& query, std::vector* results) const; /// Return the ID for the indicated result of a query or /// invalid_id if the index is not a valid leaf node index. @@ -89,12 +87,12 @@ class DlRTree : public SkRefCnt { } /// Returns maximum and minimum axis values of rectangles in this R-Tree. - /// If R-Tree is empty returns an empty SkRect. - const SkRect& bounds() const; + /// If R-Tree is empty returns an empty DlRect. + const DlRect& bounds() const; /// Return the rectangle bounds for the indicated result of a query /// or an empty rect if the index is not a valid leaf node index. - const SkRect& bounds(int result_index) const { + const DlRect& bounds(int result_index) const { return (result_index >= 0 && result_index < leaf_count_) ? nodes_[result_index].bounds : kEmpty; @@ -123,7 +121,7 @@ class DlRTree : public SkRefCnt { /// If |deband| is true, then matching rectangles from adjacent DlRegion /// spanlines will be joined together. This reduces the number of /// rectangles returned, but requires some extra computation. - std::list searchAndConsolidateRects(const SkRect& query, + std::list searchAndConsolidateRects(const DlRect& query, bool deband = true) const; /// Returns DlRegion that represents the union of all rectangles in the @@ -132,15 +130,16 @@ class DlRTree : public SkRefCnt { /// Returns DlRegion that represents the union of all rectangles in the /// R-Tree intersected with the query rect. - DlRegion region(const SkRect& query) const { - return DlRegion::MakeIntersection(region(), DlRegion(query.roundOut())); + DlRegion region(const DlRect& query) const { + return DlRegion::MakeIntersection(region(), + DlRegion(DlIRect::RoundOut(query))); } private: - static constexpr SkRect kEmpty = SkRect::MakeEmpty(); + static constexpr DlRect kEmpty = DlRect(); void search(const Node& parent, - const SkRect& query, + const DlRect& query, std::vector* results) const; std::vector nodes_; diff --git a/display_list/geometry/dl_rtree_unittests.cc b/display_list/geometry/dl_rtree_unittests.cc index bc19fec8a5f79..63fb09186ecb0 100644 --- a/display_list/geometry/dl_rtree_unittests.cc +++ b/display_list/geometry/dl_rtree_unittests.cc @@ -5,8 +5,6 @@ #include "flutter/display_list/geometry/dl_rtree.h" #include "gtest/gtest.h" -#include "third_party/skia/include/core/SkRect.h" - namespace flutter { namespace testing { @@ -21,7 +19,7 @@ TEST(DisplayListRTree, NegativeCount) { TEST(DisplayListRTree, NullSearchResultVector) { DlRTree tree(nullptr, 0); - EXPECT_DEATH_IF_SUPPORTED(tree.search(SkRect::MakeLTRB(0, 0, 1, 1), nullptr), + EXPECT_DEATH_IF_SUPPORTED(tree.search(DlRect::MakeLTRB(0, 0, 1, 1), nullptr), "results != nullptr"); } #endif @@ -31,7 +29,7 @@ TEST(DisplayListRTree, NullRectListZeroCount) { EXPECT_EQ(tree.leaf_count(), 0); EXPECT_EQ(tree.node_count(), 0); std::vector results; - auto huge = SkRect::MakeLTRB(-1e6, -1e6, 1e6, 1e6); + auto huge = DlRect::MakeLTRB(-1e6, -1e6, 1e6, 1e6); tree.search(huge, &results); EXPECT_EQ(results.size(), 0u); auto list = tree.searchAndConsolidateRects(huge); @@ -45,10 +43,10 @@ TEST(DisplayListRTree, ManySizes) { // Rect 2 goes from 20 to 30 // etc. in both dimensions const int kMaxN = 250; - SkRect rects[kMaxN + 1]; + DlRect rects[kMaxN + 1]; int ids[kMaxN + 1]; for (int i = 0; i <= kMaxN; i++) { - rects[i].setXYWH(i * 20, i * 20, 10, 10); + rects[i] = DlRect::MakeXYWH(i * 20, i * 20, 10, 10); ids[i] = i + 42; } std::vector results; @@ -58,14 +56,14 @@ TEST(DisplayListRTree, ManySizes) { EXPECT_EQ(tree.leaf_count(), N) << desc; EXPECT_GE(tree.node_count(), N) << desc; EXPECT_EQ(tree.id(-1), -1) << desc; - EXPECT_EQ(tree.bounds(-1), SkRect::MakeEmpty()) << desc; + EXPECT_EQ(tree.bounds(-1), DlRect()) << desc; EXPECT_EQ(tree.id(N), -1) << desc; - EXPECT_EQ(tree.bounds(N), SkRect::MakeEmpty()) << desc; + EXPECT_EQ(tree.bounds(N), DlRect()) << desc; results.clear(); - tree.search(SkRect::MakeEmpty(), &results); + tree.search(DlRect(), &results); EXPECT_EQ(results.size(), 0u) << desc; results.clear(); - tree.search(SkRect::MakeLTRB(2, 2, 8, 8), &results); + tree.search(DlRect::MakeLTRB(2, 2, 8, 8), &results); if (N == 0) { EXPECT_EQ(results.size(), 0u) << desc; } else { @@ -75,7 +73,7 @@ TEST(DisplayListRTree, ManySizes) { EXPECT_EQ(tree.bounds(results[0]), rects[0]) << desc; for (int i = 1; i < N; i++) { results.clear(); - auto query = SkRect::MakeXYWH(i * 20 + 2, i * 20 + 2, 6, 6); + auto query = DlRect::MakeXYWH(i * 20 + 2, i * 20 + 2, 6, 6); tree.search(query, &results); EXPECT_EQ(results.size(), 1u) << desc; EXPECT_EQ(results[0], i) << desc; @@ -96,25 +94,25 @@ TEST(DisplayListRTree, HugeSize) { // Rect 2 goes from 20 to 30 // etc. in both dimensions const int N = 10000; - SkRect rects[N]; + DlRect rects[N]; int ids[N]; for (int i = 0; i < N; i++) { - rects[i].setXYWH(i * 20, i * 20, 10, 10); + rects[i] = DlRect::MakeXYWH(i * 20, i * 20, 10, 10); ids[i] = i + 42; } DlRTree tree(rects, N, ids); EXPECT_EQ(tree.leaf_count(), N); EXPECT_GE(tree.node_count(), N); EXPECT_EQ(tree.id(-1), -1); - EXPECT_EQ(tree.bounds(-1), SkRect::MakeEmpty()); + EXPECT_EQ(tree.bounds(-1), DlRect()); EXPECT_EQ(tree.id(N), -1); - EXPECT_EQ(tree.bounds(N), SkRect::MakeEmpty()); + EXPECT_EQ(tree.bounds(N), DlRect()); std::vector results; - tree.search(SkRect::MakeEmpty(), &results); + tree.search(DlRect(), &results); EXPECT_EQ(results.size(), 0u); for (int i = 0; i < N; i++) { results.clear(); - tree.search(SkRect::MakeXYWH(i * 20 + 2, i * 20 + 2, 6, 6), &results); + tree.search(DlRect::MakeXYWH(i * 20 + 2, i * 20 + 2, 6, 6), &results); EXPECT_EQ(results.size(), 1u); EXPECT_EQ(results[0], i); EXPECT_EQ(tree.id(results[0]), ids[i]); @@ -131,14 +129,14 @@ TEST(DisplayListRTree, Grid) { const int ROWS = 10; const int COLS = 10; const int N = ROWS * COLS; - SkRect rects[N]; + DlRect rects[N]; int ids[N]; for (int r = 0; r < ROWS; r++) { int y = r * 20 + 5; for (int c = 0; c < COLS; c++) { int x = c * 20 + 5; int i = r * COLS + c; - rects[i] = SkRect::MakeXYWH(x, y, 10, 10); + rects[i] = DlRect::MakeXYWH(x, y, 10, 10); ids[i] = i + 42; } } @@ -146,11 +144,11 @@ TEST(DisplayListRTree, Grid) { EXPECT_EQ(tree.leaf_count(), N); EXPECT_GE(tree.node_count(), N); EXPECT_EQ(tree.id(-1), -1); - EXPECT_EQ(tree.bounds(-1), SkRect::MakeEmpty()); + EXPECT_EQ(tree.bounds(-1), DlRect()); EXPECT_EQ(tree.id(N), -1); - EXPECT_EQ(tree.bounds(N), SkRect::MakeEmpty()); + EXPECT_EQ(tree.bounds(N), DlRect()); std::vector results; - tree.search(SkRect::MakeEmpty(), &results); + tree.search(DlRect(), &results); EXPECT_EQ(results.size(), 0u); // Testing eqch rect for a single hit for (int r = 0; r < ROWS; r++) { @@ -161,7 +159,7 @@ TEST(DisplayListRTree, Grid) { auto desc = "row " + std::to_string(r + 1) + ", col " + std::to_string(c + 1); results.clear(); - auto query = SkRect::MakeXYWH(x + 2, y + 2, 6, 6); + auto query = DlRect::MakeXYWH(x + 2, y + 2, 6, 6); tree.search(query, &results); EXPECT_EQ(results.size(), 1u) << desc; EXPECT_EQ(results[0], i) << desc; @@ -180,7 +178,7 @@ TEST(DisplayListRTree, Grid) { auto desc = "row " + std::to_string(r + 1) + ", col " + std::to_string(c + 1); results.clear(); - auto query = SkRect::MakeXYWH(x - 8, y - 8, 6, 6); + auto query = DlRect::MakeXYWH(x - 8, y - 8, 6, 6); tree.search(query, &results); EXPECT_EQ(results.size(), 0u) << desc; auto list = tree.searchAndConsolidateRects(query); @@ -197,7 +195,7 @@ TEST(DisplayListRTree, Grid) { auto desc = "row " + std::to_string(r + 1) + ", col " + std::to_string(c + 1); results.clear(); - auto query = SkRect::MakeXYWH(x - 11, y - 11, 12, 12); + auto query = DlRect::MakeXYWH(x - 11, y - 11, 12, 12); tree.search(query, &results); EXPECT_EQ(results.size(), 4u) << desc; @@ -254,12 +252,12 @@ TEST(DisplayListRTree, OverlappingRects) { // | rect2 | // | 2 & 3 | // | rect3 | - SkRect rects[9]; + DlRect rects[9]; for (int r = 0; r < 3; r++) { int y = 15 + 20 * r; for (int c = 0; c < 3; c++) { int x = 15 + 20 * c; - rects[r * 3 + c].setLTRB(x - 15, y - 15, x + 15, y + 15); + rects[r * 3 + c] = DlRect::MakeLTRB(x - 15, y - 15, x + 15, y + 15); } } DlRTree tree(rects, 9); @@ -268,7 +266,7 @@ TEST(DisplayListRTree, OverlappingRects) { int y = 15 + 20 * r; for (int c = 0; c < 3; c++) { int x = 15 + 20 * c; - auto query = SkRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1); + auto query = DlRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1); auto list = tree.searchAndConsolidateRects(query); EXPECT_EQ(list.size(), 1u); EXPECT_EQ(list.front(), rects[r * 3 + c]); @@ -279,42 +277,42 @@ TEST(DisplayListRTree, OverlappingRects) { int c = 1; int y = 15 + 20 * r; int x = 15 + 20 * c; - auto query = SkRect::MakeLTRB(x - 6, y - 1, x + 6, y + 1); + auto query = DlRect::MakeLTRB(x - 6, y - 1, x + 6, y + 1); auto list = tree.searchAndConsolidateRects(query); EXPECT_EQ(list.size(), 1u); - EXPECT_EQ(list.front(), SkRect::MakeLTRB(x - 35, y - 15, x + 35, y + 15)); + EXPECT_EQ(list.front(), DlRect::MakeLTRB(x - 35, y - 15, x + 35, y + 15)); } // Tall rects intersecting 3 source rects vertically for (int c = 0; c < 3; c++) { int r = 1; int x = 15 + 20 * c; int y = 15 + 20 * r; - auto query = SkRect::MakeLTRB(x - 1, y - 6, x + 1, y + 6); + auto query = DlRect::MakeLTRB(x - 1, y - 6, x + 1, y + 6); auto list = tree.searchAndConsolidateRects(query); EXPECT_EQ(list.size(), 1u); - EXPECT_EQ(list.front(), SkRect::MakeLTRB(x - 15, y - 35, x + 15, y + 35)); + EXPECT_EQ(list.front(), DlRect::MakeLTRB(x - 15, y - 35, x + 15, y + 35)); } // Finally intersecting all 9 rects - auto query = SkRect::MakeLTRB(35 - 6, 35 - 6, 35 + 6, 35 + 6); + auto query = DlRect::MakeLTRB(35 - 6, 35 - 6, 35 + 6, 35 + 6); auto list = tree.searchAndConsolidateRects(query); EXPECT_EQ(list.size(), 1u); - EXPECT_EQ(list.front(), SkRect::MakeLTRB(0, 0, 70, 70)); + EXPECT_EQ(list.front(), DlRect::MakeLTRB(0, 0, 70, 70)); } TEST(DisplayListRTree, Region) { - SkRect rect[9]; + DlRect rect[9]; for (int i = 0; i < 9; i++) { - rect[i] = SkRect::MakeXYWH(i * 10, i * 10, 20, 20); + rect[i] = DlRect::MakeXYWH(i * 10, i * 10, 20, 20); } DlRTree rtree(rect, 9); const auto& region = rtree.region(); auto rects = region.getRects(true); - std::vector expected_rects{ - SkIRect::MakeLTRB(0, 0, 20, 10), SkIRect::MakeLTRB(0, 10, 30, 20), - SkIRect::MakeLTRB(10, 20, 40, 30), SkIRect::MakeLTRB(20, 30, 50, 40), - SkIRect::MakeLTRB(30, 40, 60, 50), SkIRect::MakeLTRB(40, 50, 70, 60), - SkIRect::MakeLTRB(50, 60, 80, 70), SkIRect::MakeLTRB(60, 70, 90, 80), - SkIRect::MakeLTRB(70, 80, 100, 90), SkIRect::MakeLTRB(80, 90, 100, 100), + std::vector expected_rects{ + DlIRect::MakeLTRB(0, 0, 20, 10), DlIRect::MakeLTRB(0, 10, 30, 20), + DlIRect::MakeLTRB(10, 20, 40, 30), DlIRect::MakeLTRB(20, 30, 50, 40), + DlIRect::MakeLTRB(30, 40, 60, 50), DlIRect::MakeLTRB(40, 50, 70, 60), + DlIRect::MakeLTRB(50, 60, 80, 70), DlIRect::MakeLTRB(60, 70, 90, 80), + DlIRect::MakeLTRB(70, 80, 100, 90), DlIRect::MakeLTRB(80, 90, 100, 100), }; EXPECT_EQ(rects.size(), expected_rects.size()); } diff --git a/display_list/utils/dl_matrix_clip_tracker.cc b/display_list/utils/dl_matrix_clip_tracker.cc index a7f4c316190f7..7e43e585415db 100644 --- a/display_list/utils/dl_matrix_clip_tracker.cc +++ b/display_list/utils/dl_matrix_clip_tracker.cc @@ -66,6 +66,18 @@ bool DisplayListMatrixClipState::mapAndClipRect(const SkRect& src, return false; } +bool DisplayListMatrixClipState::mapAndClipRect(const DlRect& src, + DlRect* mapped) const { + DlRect dl_mapped = src.TransformAndClipBounds(matrix_); + auto dl_intersected = dl_mapped.Intersection(cull_rect_); + if (dl_intersected.has_value()) { + *mapped = dl_intersected.value(); + return true; + } + *mapped = DlRect(); + return false; +} + void DisplayListMatrixClipState::clipRect(const DlRect& rect, ClipOp op, bool is_aa) { diff --git a/display_list/utils/dl_matrix_clip_tracker.h b/display_list/utils/dl_matrix_clip_tracker.h index 1bcf67b6978d9..a94d4ea4514c9 100644 --- a/display_list/utils/dl_matrix_clip_tracker.h +++ b/display_list/utils/dl_matrix_clip_tracker.h @@ -149,6 +149,10 @@ class DisplayListMatrixClipState { return mapAndClipRect(*rect, rect); } bool mapAndClipRect(const SkRect& src, SkRect* mapped) const; + bool mapAndClipRect(DlRect* rect) const { + return mapAndClipRect(*rect, rect); + } + bool mapAndClipRect(const DlRect& src, DlRect* mapped) const; void clipRect(const DlRect& rect, ClipOp op, bool is_aa); void clipRect(const SkRect& rect, ClipOp op, bool is_aa) { diff --git a/flow/embedded_views.h b/flow/embedded_views.h index fc77f14f87d7b..88d707fd40b58 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -347,8 +347,9 @@ class EmbedderViewSlice { virtual DlCanvas* canvas() = 0; virtual void end_recording() = 0; virtual const DlRegion& getRegion() const = 0; - DlRegion region(const SkRect& query) const { - return DlRegion::MakeIntersection(getRegion(), DlRegion(query.roundOut())); + DlRegion region(const DlRect& query) const { + DlRegion rquery = DlRegion(DlIRect::RoundOut(query)); + return DlRegion::MakeIntersection(getRegion(), rquery); } virtual void render_into(DlCanvas* canvas) = 0; diff --git a/flow/layers/display_list_layer_unittests.cc b/flow/layers/display_list_layer_unittests.cc index 34a01c6d2c097..32200812b692d 100644 --- a/flow/layers/display_list_layer_unittests.cc +++ b/flow/layers/display_list_layer_unittests.cc @@ -322,10 +322,9 @@ TEST_F(DisplayListLayerTest, RasterCachePreservesRTree) { false)); auto root_canvas_dl = expected_root_canvas.Build(); const auto root_canvas_rects = - root_canvas_dl->rtree()->searchAndConsolidateRects(ToSkRect(kGiantRect), - true); - std::list root_canvas_rects_expected = { - SkRect::MakeLTRB(26, 26, 56, 56), + root_canvas_dl->rtree()->searchAndConsolidateRects(kGiantRect, true); + std::list root_canvas_rects_expected = { + DlRect::MakeLTRB(26, 26, 56, 56), }; EXPECT_EQ(root_canvas_rects_expected, root_canvas_rects); @@ -336,14 +335,13 @@ TEST_F(DisplayListLayerTest, RasterCachePreservesRTree) { true)); auto overlay_canvas_dl = expected_overlay_canvas.Build(); const auto overlay_canvas_rects = - overlay_canvas_dl->rtree()->searchAndConsolidateRects( - ToSkRect(kGiantRect), true); + overlay_canvas_dl->rtree()->searchAndConsolidateRects(kGiantRect, true); // Same bounds as root canvas, but preserves individual rects. - std::list overlay_canvas_rects_expected = { - SkRect::MakeLTRB(26, 26, 46, 36), - SkRect::MakeLTRB(26, 36, 56, 46), - SkRect::MakeLTRB(36, 46, 56, 56), + std::list overlay_canvas_rects_expected = { + DlRect::MakeLTRB(26, 26, 46, 36), + DlRect::MakeLTRB(26, 36, 56, 46), + DlRect::MakeLTRB(36, 46, 56, 56), }; EXPECT_EQ(overlay_canvas_rects_expected, overlay_canvas_rects); }; diff --git a/flow/layers/display_list_raster_cache_item.cc b/flow/layers/display_list_raster_cache_item.cc index 930bbfd541cd3..31ef3997fd36d 100644 --- a/flow/layers/display_list_raster_cache_item.cc +++ b/flow/layers/display_list_raster_cache_item.cc @@ -16,7 +16,8 @@ #include "flutter/flow/raster_cache_item.h" #include "flutter/flow/raster_cache_key.h" #include "flutter/flow/raster_cache_util.h" -#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" +#include "flutter/third_party/skia/include/core/SkColorSpace.h" +#include "flutter/third_party/skia/include/gpu/ganesh/GrDirectContext.h" namespace flutter { diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index 854b423edf844..fe9ca548164a0 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -58,11 +58,11 @@ void RasterCacheResult::draw(DlCanvas& canvas, canvas.Translate(bounds.fLeft, bounds.fTop); - SkRect rtree_bounds = - RasterCacheUtil::GetRoundedOutDeviceBounds(rtree_->bounds(), matrix); + SkRect rtree_bounds = RasterCacheUtil::GetRoundedOutDeviceBounds( + ToSkRect(rtree_->bounds()), matrix); for (auto rect : rects) { SkRect device_rect = RasterCacheUtil::GetRoundedOutDeviceBounds( - SkRect::Make(rect), matrix); + SkRect::Make(ToSkIRect(rect)), matrix); device_rect.offset(-rtree_bounds.fLeft, -rtree_bounds.fTop); canvas.DrawImageRect(image_, device_rect, device_rect, DlImageSampling::kNearestNeighbor, paint); diff --git a/flow/view_slicer.cc b/flow/view_slicer.cc index b18aa34cada04..9d5012b8af0ba 100644 --- a/flow/view_slicer.cc +++ b/flow/view_slicer.cc @@ -33,7 +33,7 @@ std::unordered_map SliceViews( slice->end_recording(); - SkRect full_joined_rect = SkRect::MakeEmpty(); + DlRect full_joined_rect; // Determinate if Flutter UI intersects with any of the previous // platform views stacked by z position. @@ -49,12 +49,15 @@ std::unordered_map SliceViews( continue; } - SkRect current_view_rect = maybe_rect->second; - const SkIRect rounded_in_platform_view_rect = current_view_rect.roundIn(); + const SkRect current_view_rect = maybe_rect->second; + const DlIRect rounded_in_platform_view_rect = + DlIRect::RoundIn(ToDlRect(current_view_rect)); + const DlRect rounded_out_platform_view_rect = + DlRect::RoundOut(ToDlRect(current_view_rect)); // Each rect corresponds to a native view that renders Flutter UI. - std::vector intersection_rects = - slice->region(current_view_rect).getRects(); + std::vector intersection_rects = + slice->region(ToDlRect(current_view_rect)).getRects(); // Ignore intersections of single width/height on the edge of the platform // view. @@ -72,7 +75,7 @@ std::unordered_map SliceViews( // If intersection_rect does not intersect with the *rounded in* // platform view rect, then the intersection must be a single pixel // width (or height) on edge. - if (!SkIRect::Intersects(*it, rounded_in_platform_view_rect)) { + if (!it->IntersectsWithRect(rounded_in_platform_view_rect)) { it = intersection_rects.erase(it); } else { ++it; @@ -83,14 +86,14 @@ std::unordered_map SliceViews( // // In this case, the rects are merged into a single one that is the union // of all the rects. - SkRect partial_joined_rect = SkRect::MakeEmpty(); - for (const SkIRect& rect : intersection_rects) { - partial_joined_rect.join(SkRect::Make(rect)); + DlRect partial_joined_rect; + for (const DlIRect& rect : intersection_rects) { + partial_joined_rect = partial_joined_rect.Union(DlRect::Make(rect)); } // Get the intersection rect with the `current_view_rect`, - if (partial_joined_rect.intersect( - SkRect::Make(current_view_rect.roundOut()))) { + if (partial_joined_rect.IntersectsWithRect( + rounded_out_platform_view_rect)) { // Join the `partial_joined_rect` into `full_joined_rect` to get the // rect above the current `slice`, only if it intersects the indicated // view. This should always be the case because we just deleted any @@ -100,12 +103,12 @@ std::unordered_map SliceViews( // penalty for not checking the return value of the intersect method // would be to join a non-overlapping rectangle into the overlay // bounds - if the above implementation ever changes - so we check it. - full_joined_rect.join(partial_joined_rect); + full_joined_rect = full_joined_rect.Union(partial_joined_rect); } } - if (!full_joined_rect.isEmpty()) { - overlay_layers.insert({view_id, full_joined_rect}); + if (!full_joined_rect.IsEmpty()) { + overlay_layers.insert({view_id, ToSkRect(full_joined_rect)}); // Clip the background canvas, so it doesn't contain any of the pixels // drawn on the overlay layer. diff --git a/impeller/geometry/rect.h b/impeller/geometry/rect.h index 860a8747ceb28..111ca30c99035 100644 --- a/impeller/geometry/rect.h +++ b/impeller/geometry/rect.h @@ -687,6 +687,14 @@ struct TRect { saturated::Cast(ceil(r.GetBottom()))); } + ONLY_ON_FLOAT_M([[nodiscard]] constexpr static, TRect) + RoundIn(const TRect& r) { + return TRect::MakeLTRB(saturated::Cast(ceil(r.GetLeft())), + saturated::Cast(ceil(r.GetTop())), + saturated::Cast(floor(r.GetRight())), + saturated::Cast(floor(r.GetBottom()))); + } + ONLY_ON_FLOAT_M([[nodiscard]] constexpr static, TRect) Round(const TRect& r) { return TRect::MakeLTRB(saturated::Cast(round(r.GetLeft())), diff --git a/shell/platform/android/surface_texture_external_texture_gl_skia.cc b/shell/platform/android/surface_texture_external_texture_gl_skia.cc index 599c5a5df16ff..dfa5797e50cc5 100644 --- a/shell/platform/android/surface_texture_external_texture_gl_skia.cc +++ b/shell/platform/android/surface_texture_external_texture_gl_skia.cc @@ -8,6 +8,7 @@ #define GL_GLEXT_PROTOTYPES #include +#include "flutter/third_party/skia/include/core/SkColorSpace.h" #include "flutter/third_party/skia/include/gpu/ganesh/GrBackendSurface.h" #include "flutter/third_party/skia/include/gpu/ganesh/GrDirectContext.h" #include "flutter/third_party/skia/include/gpu/ganesh/SkImageGanesh.h" diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm index aba83b7d83bb2..cfc05b8f0b560 100644 --- a/shell/platform/darwin/ios/ios_surface_software.mm +++ b/shell/platform/darwin/ios/ios_surface_software.mm @@ -12,6 +12,7 @@ #include "flutter/fml/platform/darwin/cf_utils.h" #include "flutter/fml/trace_event.h" +#include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/utils/mac/SkCGUtils.h" diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index a4caecfd68bd1..bddf7d3feaa48 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -268,7 +268,7 @@ class Layer { EmbedderRenderTarget* render_target() { return render_target_.get(); } - std::vector coverage() { + std::vector coverage() { return flutter_contents_region_.getRects(); } diff --git a/shell/platform/embedder/embedder_layers.cc b/shell/platform/embedder/embedder_layers.cc index 6759350cfe8d7..7f80f7f6d352a 100644 --- a/shell/platform/embedder/embedder_layers.cc +++ b/shell/platform/embedder/embedder_layers.cc @@ -21,7 +21,7 @@ EmbedderLayers::~EmbedderLayers() = default; void EmbedderLayers::PushBackingStoreLayer( const FlutterBackingStore* store, - const std::vector& paint_region_vec) { + const std::vector& paint_region_vec) { FlutterLayer layer = {}; layer.struct_size = sizeof(FlutterLayer); @@ -44,7 +44,7 @@ void EmbedderLayers::PushBackingStoreLayer( for (const auto& rect : paint_region_vec) { auto transformed_rect = - root_surface_transformation_.mapRect(SkRect::Make(rect)); + root_surface_transformation_.mapRect(SkRect::Make(ToSkIRect(rect))); paint_region_rects->push_back(FlutterRect{ transformed_rect.x(), transformed_rect.y(), diff --git a/shell/platform/embedder/embedder_layers.h b/shell/platform/embedder/embedder_layers.h index 49fd9204f582f..081305cafeace 100644 --- a/shell/platform/embedder/embedder_layers.h +++ b/shell/platform/embedder/embedder_layers.h @@ -26,7 +26,7 @@ class EmbedderLayers { ~EmbedderLayers(); void PushBackingStoreLayer(const FlutterBackingStore* store, - const std::vector& drawn_region); + const std::vector& drawn_region); void PushPlatformViewLayer(FlutterPlatformViewIdentifier identifier, const EmbeddedViewParams& params); diff --git a/shell/platform/fuchsia/flutter/rtree.cc b/shell/platform/fuchsia/flutter/rtree.cc index c0b1aa3ab08bf..576cb3b630729 100644 --- a/shell/platform/fuchsia/flutter/rtree.cc +++ b/shell/platform/fuchsia/flutter/rtree.cc @@ -42,7 +42,7 @@ std::list RTree::searchNonOverlappingDrawnRects( std::vector intermediary_results; search(query, &intermediary_results); - std::vector rects; + std::vector rects; for (int index : intermediary_results) { auto draw_op = draw_op_.find(index); // Ignore records that don't draw anything. @@ -51,14 +51,14 @@ std::list RTree::searchNonOverlappingDrawnRects( } SkIRect current_record_rect; draw_op->second.roundOut(¤t_record_rect); - rects.push_back(current_record_rect); + rects.push_back(ToDlIRect(current_record_rect)); } DlRegion region(rects); auto non_overlapping_rects = region.getRects(true); std::list final_results; for (const auto& rect : non_overlapping_rects) { - final_results.push_back(SkRect::Make(rect)); + final_results.push_back(SkRect::Make(ToSkIRect(rect))); } return final_results; }