From 483ca29940fbc3d48a5e9fceeee8b11928e1ca44 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 31 Oct 2023 16:57:58 -0700 Subject: [PATCH] [Impeller] Place Rect statics under the Rect template. (flutter/engine#47529) `Rect::Intersection(a, b)` instead of `Intersection(a, b)`, etc. Make them usable with other Rect variants, although `RoundOut` is not useful for integer rectangles, for example. --- .../contents/filters/filter_contents.cc | 2 +- .../flutter/impeller/entity/entity_pass.cc | 2 +- .../impeller/geometry/geometry_unittests.cc | 70 +++++++++--------- engine/src/flutter/impeller/geometry/rect.h | 73 ++++++++++--------- 4 files changed, 76 insertions(+), 71 deletions(-) diff --git a/engine/src/flutter/impeller/entity/contents/filters/filter_contents.cc b/engine/src/flutter/impeller/entity/contents/filters/filter_contents.cc index 25eb7f1bd86..65b980da197 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/filter_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/filters/filter_contents.cc @@ -246,7 +246,7 @@ std::optional FilterContents::GetSourceCoverage( if (!input_coverage.has_value()) { return std::nullopt; } - inputs_coverage = Union(inputs_coverage, input_coverage.value()); + inputs_coverage = Rect::Union(inputs_coverage, input_coverage.value()); } return inputs_coverage; } diff --git a/engine/src/flutter/impeller/entity/entity_pass.cc b/engine/src/flutter/impeller/entity/entity_pass.cc index e79b191da5e..1948a72a69d 100644 --- a/engine/src/flutter/impeller/entity/entity_pass.cc +++ b/engine/src/flutter/impeller/entity/entity_pass.cc @@ -616,7 +616,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( return EntityPass::EntityResult::Skip(); } - subpass_coverage = RoundOut(subpass_coverage.value()); + subpass_coverage = Rect::RoundOut(subpass_coverage.value()); auto subpass_size = ISize(subpass_coverage->size); if (subpass_size.IsEmpty()) { diff --git a/engine/src/flutter/impeller/geometry/geometry_unittests.cc b/engine/src/flutter/impeller/geometry/geometry_unittests.cc index f1efdb97d09..d81ec54131c 100644 --- a/engine/src/flutter/impeller/geometry/geometry_unittests.cc +++ b/engine/src/flutter/impeller/geometry/geometry_unittests.cc @@ -1650,25 +1650,25 @@ TEST(GeometryTest, OptRectUnion) { Rect c = Rect::MakeLTRB(100, 0, 200, 100); // NullOpt, NullOpt - EXPECT_FALSE(Union(std::nullopt, std::nullopt).has_value()); - EXPECT_EQ(Union(std::nullopt, std::nullopt), std::nullopt); + EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value()); + EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt); auto test1 = [](const Rect& r) { // Rect, NullOpt - EXPECT_TRUE(Union(r, std::nullopt).has_value()); - EXPECT_EQ(Union(r, std::nullopt).value(), r); + EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value()); + EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r); // OptRect, NullOpt - EXPECT_TRUE(Union(std::optional(r), std::nullopt).has_value()); - EXPECT_EQ(Union(std::optional(r), std::nullopt).value(), r); + EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value()); + EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r); // NullOpt, Rect - EXPECT_TRUE(Union(std::nullopt, r).has_value()); - EXPECT_EQ(Union(std::nullopt, r).value(), r); + EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value()); + EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r); // NullOpt, OptRect - EXPECT_TRUE(Union(std::nullopt, std::optional(r)).has_value()); - EXPECT_EQ(Union(std::nullopt, std::optional(r)).value(), r); + EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value()); + EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r); }; test1(a); @@ -1679,16 +1679,16 @@ TEST(GeometryTest, OptRectUnion) { ASSERT_EQ(a.Union(b), u); // Rect, OptRect - EXPECT_TRUE(Union(a, std::optional(b)).has_value()); - EXPECT_EQ(Union(a, std::optional(b)).value(), u); + EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value()); + EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u); // OptRect, Rect - EXPECT_TRUE(Union(std::optional(a), b).has_value()); - EXPECT_EQ(Union(std::optional(a), b).value(), u); + EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value()); + EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u); // OptRect, OptRect - EXPECT_TRUE(Union(std::optional(a), std::optional(b)).has_value()); - EXPECT_EQ(Union(std::optional(a), std::optional(b)).value(), u); + EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value()); + EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u); }; test2(a, b, Rect::MakeLTRB(0, 0, 200, 200)); @@ -1751,25 +1751,25 @@ TEST(GeometryTest, OptRectIntersection) { Rect c = Rect::MakeLTRB(100, 0, 200, 110); // NullOpt, NullOpt - EXPECT_FALSE(Intersection(std::nullopt, std::nullopt).has_value()); - EXPECT_EQ(Intersection(std::nullopt, std::nullopt), std::nullopt); + EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value()); + EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt); auto test1 = [](const Rect& r) { // Rect, NullOpt - EXPECT_TRUE(Intersection(r, std::nullopt).has_value()); - EXPECT_EQ(Intersection(r, std::nullopt).value(), r); + EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value()); + EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r); // OptRect, NullOpt - EXPECT_TRUE(Intersection(std::optional(r), std::nullopt).has_value()); - EXPECT_EQ(Intersection(std::optional(r), std::nullopt).value(), r); + EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value()); + EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r); // NullOpt, Rect - EXPECT_TRUE(Intersection(std::nullopt, r).has_value()); - EXPECT_EQ(Intersection(std::nullopt, r).value(), r); + EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value()); + EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r); // NullOpt, OptRect - EXPECT_TRUE(Intersection(std::nullopt, std::optional(r)).has_value()); - EXPECT_EQ(Intersection(std::nullopt, std::optional(r)).value(), r); + EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value()); + EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r); }; test1(a); @@ -1780,16 +1780,18 @@ TEST(GeometryTest, OptRectIntersection) { ASSERT_EQ(a.Intersection(b), i); // Rect, OptRect - EXPECT_TRUE(Intersection(a, std::optional(b)).has_value()); - EXPECT_EQ(Intersection(a, std::optional(b)).value(), i); + EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value()); + EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i); // OptRect, Rect - EXPECT_TRUE(Intersection(std::optional(a), b).has_value()); - EXPECT_EQ(Intersection(std::optional(a), b).value(), i); + EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value()); + EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i); // OptRect, OptRect - EXPECT_TRUE(Intersection(std::optional(a), std::optional(b)).has_value()); - EXPECT_EQ(Intersection(std::optional(a), std::optional(b)).value(), i); + EXPECT_TRUE( + Rect::Intersection(std::optional(a), std::optional(b)).has_value()); + EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(), + i); }; test2(a, b, Rect::MakeLTRB(100, 100, 110, 110)); @@ -2117,11 +2119,11 @@ TEST(GeometryTest, RectProject) { TEST(GeometryTest, RectRoundOut) { { auto r = Rect::MakeLTRB(-100, -100, 100, 100); - ASSERT_EQ(RoundOut(r), r); + ASSERT_EQ(Rect::RoundOut(r), r); } { auto r = Rect::MakeLTRB(-100.1, -100.1, 100.1, 100.1); - ASSERT_EQ(RoundOut(r), Rect::MakeLTRB(-101, -101, 101, 101)); + ASSERT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -101, 101, 101)); } } diff --git a/engine/src/flutter/impeller/geometry/rect.h b/engine/src/flutter/impeller/geometry/rect.h index b92a332a47d..108aca97e43 100644 --- a/engine/src/flutter/impeller/geometry/rect.h +++ b/engine/src/flutter/impeller/geometry/rect.h @@ -325,46 +325,49 @@ struct TRect { TSize(1.0 / static_cast(size.width), 1.0 / static_cast(size.height))); } + + constexpr static TRect RoundOut(const TRect& r) { + return TRect::MakeLTRB(floor(r.GetLeft()), floor(r.GetTop()), + ceil(r.GetRight()), ceil(r.GetBottom())); + } + + constexpr static std::optional Union(const TRect& a, + const std::optional b) { + return b.has_value() ? a.Union(b.value()) : a; + } + + constexpr static std::optional Union(const std::optional a, + const TRect& b) { + return Union(b, a); + } + + constexpr static std::optional Union(const std::optional a, + const std::optional b) { + return a.has_value() ? Union(a.value(), b) : b; + } + + constexpr static std::optional Intersection( + const TRect& a, + const std::optional b) { + return b.has_value() ? a.Intersection(b.value()) : a; + } + + constexpr static std::optional Intersection( + const std::optional a, + const TRect& b) { + return Intersection(b, a); + } + + constexpr static std::optional Intersection( + const std::optional a, + const std::optional b) { + return a.has_value() ? Intersection(a.value(), b) : b; + } }; using Rect = TRect; using IRect = TRect; -constexpr inline Rect RoundOut(const Rect& r) { - return Rect::MakeLTRB(floor(r.GetLeft()), floor(r.GetTop()), - ceil(r.GetRight()), ceil(r.GetBottom())); -} - -constexpr inline std::optional Union(const Rect& a, - const std::optional b) { - return b.has_value() ? a.Union(b.value()) : a; -} - -constexpr inline std::optional Union(const std::optional a, - const Rect& b) { - return Union(b, a); -} - -constexpr inline std::optional Union(const std::optional a, - const std::optional b) { - return a.has_value() ? Union(a.value(), b) : b; -} - -constexpr inline std::optional Intersection(const Rect& a, - const std::optional b) { - return b.has_value() ? a.Intersection(b.value()) : a; -} - -constexpr inline std::optional Intersection(const std::optional a, - const Rect& b) { - return Intersection(b, a); -} - -constexpr inline std::optional Intersection(const std::optional a, - const std::optional b) { - return a.has_value() ? Intersection(a.value(), b) : b; -} - } // namespace impeller namespace std {