[impeller] convert src over to src for solid color (flutter/engine#41351)

Related to https://github.com/flutter/flutter/issues/114402

At least in the flutter gallery test app, with https://github.com/flutter/gallery/pull/909 reverted - this significantly improves the performance in the Xcode frame debugger. If we wanted to do this for more color sources or filter effects, we need to do much more work to track texture opacity, but this seems like a reasonable and low cost first step.

### Before

![image](https://user-images.githubusercontent.com/8975114/233222371-f33d29ad-c556-4db0-b949-84777bb09307.png)

### After

![image](https://user-images.githubusercontent.com/8975114/233222350-0517d109-cabd-45af-a0af-06b95da2d026.png)
This commit is contained in:
Jonah Williams
2023-04-19 18:07:33 -07:00
committed by GitHub
parent e0d1b1a6a9
commit f73ae51144
3 changed files with 32 additions and 0 deletions

View File

@@ -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;

View File

@@ -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_;

View File

@@ -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