Skip to content

Commit 434ca75

Browse files
author
Jonah Williams
authored
[Impeller] dont generate final 1x1 mip level to work around Adreno GPU bug (#161192)
Generating the final 1x1 mip level of a texture causes the entire texture to become corrupted on some Adreno GPUs. flutter/flutter#160441 flutter/flutter#159876 flutter/flutter#160587
1 parent 16b9fe0 commit 434ca75

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

engine/src/flutter/impeller/geometry/geometry_unittests.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,11 @@ TEST(GeometryTest, QuaternionVectorMultiply) {
578578
}
579579

580580
TEST(GeometryTest, CanGenerateMipCounts) {
581-
ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
582-
ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
583-
ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
584-
ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
585-
ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
581+
ASSERT_EQ((Size{128, 128}.MipCount()), 6u);
582+
ASSERT_EQ((Size{128, 256}.MipCount()), 7u);
583+
ASSERT_EQ((Size{128, 130}.MipCount()), 7u);
584+
ASSERT_EQ((Size{128, 257}.MipCount()), 8u);
585+
ASSERT_EQ((Size{257, 128}.MipCount()), 8u);
586586
ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
587587
ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
588588
ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);

engine/src/flutter/impeller/geometry/size.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,25 @@ struct TSize {
131131
static_cast<Type>(std::ceil(other.height))};
132132
}
133133

134+
/// Return the mip count of the texture.
135+
///
136+
/// Note: does not count the final 1x1 mip level, both for practical reasons
137+
/// and to workaround driver bugs.
134138
constexpr size_t MipCount() const {
135139
constexpr size_t minimum_mip = 1u;
136140
if (IsEmpty()) {
137141
return minimum_mip;
138142
}
139143
size_t result = std::max(ceil(log2(width)), ceil(log2(height)));
144+
// This check avoids creating 1x1 mip levels, which are both pointless
145+
// and cause rendering problems on some Adreno GPUs.
146+
// See:
147+
// * https://github.com/flutter/flutter/issues/160441
148+
// * https://github.com/flutter/flutter/issues/159876
149+
// * https://github.com/flutter/flutter/issues/160587
150+
if (result > 1) {
151+
result -= 1;
152+
}
140153
return std::max(result, minimum_mip);
141154
}
142155
};

0 commit comments

Comments
 (0)