Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3581,5 +3581,37 @@ TEST_P(AiksTest, VerticesGeometryUVPositionData) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, ClearBlendWithBlur) {
Canvas canvas;
Paint white;
white.color = Color::Blue();
canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);

Paint clear;
clear.blend_mode = BlendMode::kClear;
clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
.style = FilterContents::BlurStyle::kNormal,
.sigma = Sigma(20),
};

canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);

ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, ClearBlend) {
Canvas canvas;
Paint white;
white.color = Color::Blue();
canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);

Paint clear;
clear.blend_mode = BlendMode::kClear;

canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);

ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

} // namespace testing
} // namespace impeller
17 changes: 13 additions & 4 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,19 @@ void ContentContextOptions::ApplyToPipelineDescriptor(

switch (pipeline_blend) {
case BlendMode::kClear:
color0.dst_alpha_blend_factor = BlendFactor::kZero;
color0.dst_color_blend_factor = BlendFactor::kZero;
color0.src_alpha_blend_factor = BlendFactor::kZero;
color0.src_color_blend_factor = BlendFactor::kZero;
if (is_for_rrect_blur_clear) {
color0.alpha_blend_op = BlendOperation::kReverseSubtract;
color0.color_blend_op = BlendOperation::kReverseSubtract;
color0.dst_alpha_blend_factor = BlendFactor::kOne;
color0.dst_color_blend_factor = BlendFactor::kOne;
color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
color0.src_color_blend_factor = BlendFactor::kDestinationColor;
Copy link
Member

@bdero bdero Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will cause the clear to weaken as the paint color becomes more transparent. Is that behavior correct?
I wonder if Skia is only employing this trick when the color source is entirely opaque.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, thats how you get the blurred results (that work locally):
Screenshot 2023-09-26 at 8 50 09 AM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried this out with wacky transparent colors in your repro and this seems to work great!

} else {
color0.dst_alpha_blend_factor = BlendFactor::kZero;
color0.dst_color_blend_factor = BlendFactor::kZero;
color0.src_alpha_blend_factor = BlendFactor::kZero;
color0.src_color_blend_factor = BlendFactor::kZero;
}
break;
case BlendMode::kSource:
color0.blending_enabled = false;
Expand Down
12 changes: 7 additions & 5 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,14 @@ struct ContentContextOptions {
PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown;
bool has_stencil_attachment = true;
bool wireframe = false;
bool is_for_rrect_blur_clear = false;

struct Hash {
constexpr std::size_t operator()(const ContentContextOptions& o) const {
return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare,
o.stencil_operation, o.primitive_type,
o.color_attachment_pixel_format,
o.has_stencil_attachment, o.wireframe);
return fml::HashCombine(
o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation,
o.primitive_type, o.color_attachment_pixel_format,
o.has_stencil_attachment, o.wireframe, o.is_for_rrect_blur_clear);
}
};

Expand All @@ -329,7 +330,8 @@ struct ContentContextOptions {
lhs.color_attachment_pixel_format ==
rhs.color_attachment_pixel_format &&
lhs.has_stencil_attachment == rhs.has_stencil_attachment &&
lhs.wireframe == rhs.wireframe;
lhs.wireframe == rhs.wireframe &&
lhs.is_for_rrect_blur_clear == rhs.is_for_rrect_blur_clear;
}
};

Expand Down
9 changes: 7 additions & 2 deletions impeller/entity/contents/solid_rrect_blur_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,

Command cmd;
DEBUG_COMMAND_INFO(cmd, "RRect Shadow");
auto opts = OptionsFromPassAndEntity(pass, entity);
ContentContextOptions opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = PrimitiveType::kTriangle;
Color color = color_;
if (entity.GetBlendMode() == BlendMode::kClear) {
opts.is_for_rrect_blur_clear = true;
color = Color::White();
}
cmd.pipeline = renderer.GetRRectBlurPipeline(opts);
cmd.stencil_reference = entity.GetStencilDepth();

Expand All @@ -102,7 +107,7 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));

FS::FragInfo frag_info;
frag_info.color = color_;
frag_info.color = color;
frag_info.blur_sigma = blur_sigma;
frag_info.rect_size = Point(positive_rect.size);
frag_info.corner_radius =
Expand Down