diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 9c14169833330..80f7c4cb07bde 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -46,6 +46,11 @@ bool SolidColorContents::ShouldRender( return Contents::ShouldRender(entity, stencil_coverage); } +bool SolidColorContents::ConvertToSrc(const Entity& entity) const { + return entity.GetBlendMode() == BlendMode::kSourceOver && + GetColor().alpha >= 1.0; +} + bool SolidColorContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { @@ -60,6 +65,9 @@ bool SolidColorContents::Render(const ContentContext& renderer, GetGeometry()->GetPositionBuffer(renderer, entity, pass); auto options = OptionsFromPassAndEntity(pass, entity); + if (ConvertToSrc(entity)) { + options.blend_mode = BlendMode::kSource; + } if (geometry_result.prevent_overdraw) { options.stencil_compare = CompareFunction::kEqual; options.stencil_operation = StencilOperation::kIncrementClamp; diff --git a/impeller/entity/contents/solid_color_contents.h b/impeller/entity/contents/solid_color_contents.h index 5348b906afa15..9486fc8f0db2d 100644 --- a/impeller/entity/contents/solid_color_contents.h +++ b/impeller/entity/contents/solid_color_contents.h @@ -46,6 +46,10 @@ class SolidColorContents final : public ColorSourceContents { const Entity& entity, RenderPass& pass) const override; + /// @brief Convert SrcOver blend modes into Src blend modes if the color has + /// no opacity. + bool ConvertToSrc(const Entity& entity) const; + private: Color color_; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index f1285c3393ef7..b34055ba5f61b 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2547,5 +2547,25 @@ TEST_P(EntityTest, CoverageForStrokePathWithNegativeValuesInTransform) { ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155)); } +TEST_P(EntityTest, ConvertToSrcBlend) { + Entity entity; + entity.SetBlendMode(BlendMode::kSourceOver); + + auto contents = SolidColorContents::Make( + PathBuilder{}.AddRect(Rect::MakeSize(Size(100, 100))).TakePath(), + Color::Red()); + + ASSERT_TRUE(contents->ConvertToSrc(entity)); + + // Color with alpha, should return false. + contents->SetInheritedOpacity(0.5); + ASSERT_FALSE(contents->ConvertToSrc(entity)); + + // Non source over blend mode, should return false. + contents->SetInheritedOpacity(1.0); + entity.SetBlendMode(BlendMode::kDestination); + ASSERT_FALSE(contents->ConvertToSrc(entity)); +} + } // namespace testing } // namespace impeller