From ead393115ff10df6db36e263d27714bac9494994 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Tue, 6 Jun 2023 20:36:43 +0800 Subject: [PATCH] [Impeller] Fix the rendering issue when the tile mode of gradient is set to 'decal' --- impeller/aiks/aiks_unittests.cc | 31 +++++++++++++++++++ .../contents/linear_gradient_contents.cc | 2 +- .../contents/radial_gradient_contents.cc | 2 +- .../contents/sweep_gradient_contents.cc | 2 +- .../entity/contents/tiled_texture_contents.cc | 3 +- impeller/entity/entity_unittests.cc | 9 ++++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index a45622d58fb53..c6f0bb183c717 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -791,6 +791,37 @@ TEST_P(AiksTest, CanRenderConicalGradient) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +TEST_P(AiksTest, CanRenderGradientDecalWithBackground) { + std::vector colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF), + Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF), + Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF), + Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)}; + std::vector stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0}; + + std::array color_sources = { + ColorSource::MakeLinearGradient({0, 0}, {100, 100}, colors, stops, + Entity::TileMode::kDecal, {}), + ColorSource::MakeRadialGradient({100, 100}, 100, colors, stops, + Entity::TileMode::kDecal, {}), + ColorSource::MakeSweepGradient({100, 100}, Degrees(45), Degrees(135), + colors, stops, Entity::TileMode::kDecal, + {}), + }; + + Canvas canvas; + Paint paint; + paint.color = Color::White(); + canvas.DrawRect(Rect::MakeLTRB(0, 0, 605, 205), paint); + for (int i = 0; i < 3; i++) { + canvas.Save(); + canvas.Translate({i * 200.0f, 0, 0}); + paint.color_source = color_sources[i]; + canvas.DrawRect(Rect::MakeLTRB(0, 0, 200, 200), paint); + canvas.Restore(); + } + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, CanRenderDifferentShapesWithSameColorSource) { Canvas canvas; Paint paint; diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index bdfc3407b2dc6..9660304e7ab75 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -45,7 +45,7 @@ void LinearGradientContents::SetTileMode(Entity::TileMode tile_mode) { } bool LinearGradientContents::IsOpaque() const { - if (GetOpacity() < 1) { + if (GetOpacity() < 1 || tile_mode_ == Entity::TileMode::kDecal) { return false; } for (auto color : colors_) { diff --git a/impeller/entity/contents/radial_gradient_contents.cc b/impeller/entity/contents/radial_gradient_contents.cc index c24e7df158b79..48185e87f3249 100644 --- a/impeller/entity/contents/radial_gradient_contents.cc +++ b/impeller/entity/contents/radial_gradient_contents.cc @@ -46,7 +46,7 @@ const std::vector& RadialGradientContents::GetStops() const { } bool RadialGradientContents::IsOpaque() const { - if (GetOpacity() < 1) { + if (GetOpacity() < 1 || tile_mode_ == Entity::TileMode::kDecal) { return false; } for (auto color : colors_) { diff --git a/impeller/entity/contents/sweep_gradient_contents.cc b/impeller/entity/contents/sweep_gradient_contents.cc index a70ff716d0092..1979d612ab743 100644 --- a/impeller/entity/contents/sweep_gradient_contents.cc +++ b/impeller/entity/contents/sweep_gradient_contents.cc @@ -51,7 +51,7 @@ const std::vector& SweepGradientContents::GetStops() const { } bool SweepGradientContents::IsOpaque() const { - if (GetOpacity() < 1) { + if (GetOpacity() < 1 || tile_mode_ == Entity::TileMode::kDecal) { return false; } for (auto color : colors_) { diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index 66e22672fb188..e302cb5eb5db7 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -103,7 +103,8 @@ bool TiledTextureContents::UsesEmulatedTileMode( // |Contents| bool TiledTextureContents::IsOpaque() const { - if (GetOpacity() < 1) { + if (GetOpacity() < 1 || x_tile_mode_ == Entity::TileMode::kDecal || + y_tile_mode_ == Entity::TileMode::kDecal) { return false; } if (color_filter_.has_value()) { diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 0493d55c5d753..88a3861d0c702 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2556,6 +2556,9 @@ TEST_P(EntityTest, LinearGradientContentsIsOpaque) { ASSERT_TRUE(contents.IsOpaque()); contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)}); ASSERT_FALSE(contents.IsOpaque()); + contents.SetColors({Color::CornflowerBlue()}); + contents.SetTileMode(Entity::TileMode::kDecal); + ASSERT_FALSE(contents.IsOpaque()); } TEST_P(EntityTest, RadialGradientContentsIsOpaque) { @@ -2564,6 +2567,9 @@ TEST_P(EntityTest, RadialGradientContentsIsOpaque) { ASSERT_TRUE(contents.IsOpaque()); contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)}); ASSERT_FALSE(contents.IsOpaque()); + contents.SetColors({Color::CornflowerBlue()}); + contents.SetTileMode(Entity::TileMode::kDecal); + ASSERT_FALSE(contents.IsOpaque()); } TEST_P(EntityTest, SweepGradientContentsIsOpaque) { @@ -2572,6 +2578,9 @@ TEST_P(EntityTest, SweepGradientContentsIsOpaque) { ASSERT_TRUE(contents.IsOpaque()); contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)}); ASSERT_FALSE(contents.IsOpaque()); + contents.SetColors({Color::CornflowerBlue()}); + contents.SetTileMode(Entity::TileMode::kDecal); + ASSERT_FALSE(contents.IsOpaque()); } TEST_P(EntityTest, TiledTextureContentsIsOpaque) {