diff --git a/engine/src/flutter/impeller/geometry/geometry_unittests.cc b/engine/src/flutter/impeller/geometry/geometry_unittests.cc index 3a88ff85a8..18b72c1546 100644 --- a/engine/src/flutter/impeller/geometry/geometry_unittests.cc +++ b/engine/src/flutter/impeller/geometry/geometry_unittests.cc @@ -578,11 +578,11 @@ TEST(GeometryTest, QuaternionVectorMultiply) { } TEST(GeometryTest, CanGenerateMipCounts) { - ASSERT_EQ((Size{128, 128}.MipCount()), 7u); - ASSERT_EQ((Size{128, 256}.MipCount()), 8u); - ASSERT_EQ((Size{128, 130}.MipCount()), 8u); - ASSERT_EQ((Size{128, 257}.MipCount()), 9u); - ASSERT_EQ((Size{257, 128}.MipCount()), 9u); + ASSERT_EQ((Size{128, 128}.MipCount()), 6u); + ASSERT_EQ((Size{128, 256}.MipCount()), 7u); + ASSERT_EQ((Size{128, 130}.MipCount()), 7u); + ASSERT_EQ((Size{128, 257}.MipCount()), 8u); + ASSERT_EQ((Size{257, 128}.MipCount()), 8u); ASSERT_EQ((Size{128, 0}.MipCount()), 1u); ASSERT_EQ((Size{128, -25}.MipCount()), 1u); ASSERT_EQ((Size{-128, 25}.MipCount()), 1u); diff --git a/engine/src/flutter/impeller/geometry/size.h b/engine/src/flutter/impeller/geometry/size.h index 2c609cddad..524c52f63e 100644 --- a/engine/src/flutter/impeller/geometry/size.h +++ b/engine/src/flutter/impeller/geometry/size.h @@ -131,12 +131,25 @@ struct TSize { static_cast(std::ceil(other.height))}; } + /// Return the mip count of the texture. + /// + /// Note: does not count the final 1x1 mip level, both for practical reasons + /// and to workaround driver bugs. constexpr size_t MipCount() const { constexpr size_t minimum_mip = 1u; if (IsEmpty()) { return minimum_mip; } size_t result = std::max(ceil(log2(width)), ceil(log2(height))); + // This check avoids creating 1x1 mip levels, which are both pointless + // and cause rendering problems on some Adreno GPUs. + // See: + // * https://github.com/flutter/flutter/issues/160441 + // * https://github.com/flutter/flutter/issues/159876 + // * https://github.com/flutter/flutter/issues/160587 + if (result > 1) { + result -= 1; + } return std::max(result, minimum_mip); } };