diff --git a/engine/src/flutter/impeller/geometry/geometry_unittests.cc b/engine/src/flutter/impeller/geometry/geometry_unittests.cc index 18b72c15466..1f30d464585 100644 --- a/engine/src/flutter/impeller/geometry/geometry_unittests.cc +++ b/engine/src/flutter/impeller/geometry/geometry_unittests.cc @@ -578,16 +578,16 @@ TEST(GeometryTest, QuaternionVectorMultiply) { } TEST(GeometryTest, CanGenerateMipCounts) { - 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); - ASSERT_EQ((Size{1, 1}.MipCount()), 1u); - ASSERT_EQ((Size{0, 0}.MipCount()), 1u); + EXPECT_EQ((Size{128, 128}.MipCount()), 7u); + EXPECT_EQ((Size{128, 256}.MipCount()), 7u); + EXPECT_EQ((Size{128, 130}.MipCount()), 7u); + EXPECT_EQ((Size{128, 257}.MipCount()), 7u); + EXPECT_EQ((Size{257, 128}.MipCount()), 7u); + EXPECT_EQ((Size{128, 0}.MipCount()), 1u); + EXPECT_EQ((Size{128, -25}.MipCount()), 1u); + EXPECT_EQ((Size{-128, 25}.MipCount()), 1u); + EXPECT_EQ((Size{1, 1}.MipCount()), 1u); + EXPECT_EQ((Size{0, 0}.MipCount()), 1u); } TEST(GeometryTest, CanConvertTTypesExplicitly) { diff --git a/engine/src/flutter/impeller/geometry/size.h b/engine/src/flutter/impeller/geometry/size.h index 9090d6a1c85..de2ade7524e 100644 --- a/engine/src/flutter/impeller/geometry/size.h +++ b/engine/src/flutter/impeller/geometry/size.h @@ -134,24 +134,12 @@ struct TSize { } /// 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()) { + if (IsEmpty() || width <= 0 || height <= 0) { 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; - } + size_t result = std::min(log2(width), log2(height)); return std::max(result, minimum_mip); } }; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc index 4321c3b808c..8dbae970e14 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc @@ -403,7 +403,7 @@ bool BlitPassVK::OnGenerateMipmapCommand(std::shared_ptr texture, const auto size = src.GetTextureDescriptor().size; uint32_t mip_count = src.GetTextureDescriptor().mip_count; - if (mip_count < 2u || workarounds_.broken_mipmap_generation) { + if (mip_count < 2u) { return true; } @@ -478,6 +478,9 @@ bool BlitPassVK::OnGenerateMipmapCommand(std::shared_ptr texture, width = width / 2; height = height / 2; + if (width <= 1 || height <= 1) { + break; + } // offsets[0] is origin. blit.dstOffsets[1].x = std::max(width, 1u);