Skip to content

Commit 042bc62

Browse files
bderoRicardo Amador
authored and
Ricardo Amador
committed
[Impeller] Linear sample atlas glyphs when the CTM isn't translation/scale only (flutter#39112)
1 parent fdeb1a9 commit 042bc62

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

impeller/entity/contents/text_contents.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,18 @@ static bool CommonRender(
7878
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
7979

8080
SamplerDescriptor sampler_desc;
81-
sampler_desc.min_filter = MinMagFilter::kNearest;
82-
sampler_desc.mag_filter = MinMagFilter::kNearest;
81+
if (entity.GetTransformation().IsTranslationScaleOnly()) {
82+
sampler_desc.min_filter = MinMagFilter::kNearest;
83+
sampler_desc.mag_filter = MinMagFilter::kNearest;
84+
} else {
85+
// Currently, we only propagate the scale of the transform to the atlas
86+
// renderer, so if the transform has more than just a translation, we turn
87+
// on linear sampling to prevent crunchiness caused by the pixel grid not
88+
// being perfectly aligned.
89+
// The downside is that this slightly over-blurs rotated/skewed text.
90+
sampler_desc.min_filter = MinMagFilter::kLinear;
91+
sampler_desc.mag_filter = MinMagFilter::kLinear;
92+
}
8393
sampler_desc.mip_filter = MipFilter::kNone;
8494

8595
typename FS::FragInfo frag_info;

impeller/geometry/geometry_unittests.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,32 @@ TEST(GeometryTest, MatrixIsAligned) {
444444
}
445445
}
446446

447+
TEST(GeometryTest, MatrixTranslationScaleOnly) {
448+
{
449+
auto m = Matrix();
450+
bool result = m.IsTranslationScaleOnly();
451+
ASSERT_TRUE(result);
452+
}
453+
454+
{
455+
auto m = Matrix::MakeScale(Vector3(2, 3, 4));
456+
bool result = m.IsTranslationScaleOnly();
457+
ASSERT_TRUE(result);
458+
}
459+
460+
{
461+
auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
462+
bool result = m.IsTranslationScaleOnly();
463+
ASSERT_TRUE(result);
464+
}
465+
466+
{
467+
auto m = Matrix::MakeRotationZ(Degrees(10));
468+
bool result = m.IsTranslationScaleOnly();
469+
ASSERT_FALSE(result);
470+
}
471+
}
472+
447473
TEST(GeometryTest, MatrixLookAt) {
448474
{
449475
auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),

impeller/geometry/matrix.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,19 @@ struct Matrix {
347347
);
348348
}
349349

350+
/// @brief Returns true if the matrix has a scale-only basis and is
351+
/// non-projective. Note that an identity matrix meets this criteria.
352+
constexpr bool IsTranslationScaleOnly() const {
353+
return (
354+
// clang-format off
355+
m[0] != 0.0 && m[1] == 0.0 && m[2] == 0.0 && m[3] == 0.0 &&
356+
m[4] == 0.0 && m[5] != 0.0 && m[6] == 0.0 && m[7] == 0.0 &&
357+
m[8] == 0.0 && m[9] == 0.0 && m[10] != 0.0 && m[11] == 0.0 &&
358+
m[15] == 1.0
359+
// clang-format on
360+
);
361+
}
362+
350363
std::optional<MatrixDecomposition> Decompose() const;
351364

352365
constexpr bool operator==(const Matrix& m) const {

0 commit comments

Comments
 (0)