Revert "Revert "[impeller] convert src over to src for solid color" (#41466)"
This reverts commit 8fe8e94c02fc70861cc9bb2e51035e39552de015.
diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc
index 9c14169..80f7c4c 100644
--- a/impeller/entity/contents/solid_color_contents.cc
+++ b/impeller/entity/contents/solid_color_contents.cc
@@ -46,6 +46,11 @@
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 @@
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 5348b90..9486fc8 100644
--- a/impeller/entity/contents/solid_color_contents.h
+++ b/impeller/entity/contents/solid_color_contents.h
@@ -46,6 +46,10 @@
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 f1285c3..b34055b 100644
--- a/impeller/entity/entity_unittests.cc
+++ b/impeller/entity/entity_unittests.cc
@@ -2547,5 +2547,25 @@
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