diff --git a/impeller/entity/contents/text_contents.cc b/impeller/entity/contents/text_contents.cc index 64b5d49bd971d..e6d0d7ac54abe 100644 --- a/impeller/entity/contents/text_contents.cc +++ b/impeller/entity/contents/text_contents.cc @@ -78,8 +78,18 @@ static bool CommonRender( VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); SamplerDescriptor sampler_desc; - sampler_desc.min_filter = MinMagFilter::kNearest; - sampler_desc.mag_filter = MinMagFilter::kNearest; + if (entity.GetTransformation().IsTranslationScaleOnly()) { + sampler_desc.min_filter = MinMagFilter::kNearest; + sampler_desc.mag_filter = MinMagFilter::kNearest; + } else { + // Currently, we only propagate the scale of the transform to the atlas + // renderer, so if the transform has more than just a translation, we turn + // on linear sampling to prevent crunchiness caused by the pixel grid not + // being perfectly aligned. + // The downside is that this slightly over-blurs rotated/skewed text. + sampler_desc.min_filter = MinMagFilter::kLinear; + sampler_desc.mag_filter = MinMagFilter::kLinear; + } sampler_desc.mip_filter = MipFilter::kNone; typename FS::FragInfo frag_info; diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 72d09f1ab5b21..2d40b7eac8ed7 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -424,6 +424,32 @@ TEST(GeometryTest, MatrixIsAligned) { } } +TEST(GeometryTest, MatrixTranslationScaleOnly) { + { + auto m = Matrix(); + bool result = m.IsTranslationScaleOnly(); + ASSERT_TRUE(result); + } + + { + auto m = Matrix::MakeScale(Vector3(2, 3, 4)); + bool result = m.IsTranslationScaleOnly(); + ASSERT_TRUE(result); + } + + { + auto m = Matrix::MakeTranslation(Vector3(2, 3, 4)); + bool result = m.IsTranslationScaleOnly(); + ASSERT_TRUE(result); + } + + { + auto m = Matrix::MakeRotationZ(Degrees(10)); + bool result = m.IsTranslationScaleOnly(); + ASSERT_FALSE(result); + } +} + TEST(GeometryTest, MatrixLookAt) { { auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1), diff --git a/impeller/geometry/matrix.h b/impeller/geometry/matrix.h index 2d50f3045007b..30d6636f9af79 100644 --- a/impeller/geometry/matrix.h +++ b/impeller/geometry/matrix.h @@ -322,6 +322,19 @@ struct Matrix { ); } + /// @brief Returns true if the matrix has a scale-only basis and is + /// non-projective. Note that an identity matrix meets this criteria. + constexpr bool IsTranslationScaleOnly() const { + return ( + // clang-format off + m[0] != 0.0 && m[1] == 0.0 && m[2] == 0.0 && m[3] == 0.0 && + m[4] == 0.0 && m[5] != 0.0 && m[6] == 0.0 && m[7] == 0.0 && + m[8] == 0.0 && m[9] == 0.0 && m[10] != 0.0 && m[11] == 0.0 && + m[15] == 1.0 + // clang-format on + ); + } + std::optional Decompose() const; constexpr bool operator==(const Matrix& m) const {