Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] implement blur style solid #50892

Merged
merged 5 commits into from
Mar 5, 2024
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
28 changes: 28 additions & 0 deletions impeller/aiks/aiks_blur_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -644,5 +644,33 @@ TEST_P(AiksTest, GaussianBlurStyleOuter) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, GaussianBlurStyleSolid) {
Canvas canvas;
canvas.Scale(GetContentScale());

canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});

Paint paint;
paint.color = Color::Green();
paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
.style = FilterContents::BlurStyle::kSolid,
.sigma = Sigma(30),
};
canvas.DrawPath(PathBuilder()
.MoveTo({200, 200})
.LineTo({300, 400})
.LineTo({100, 400})
.Close()
.TakePath(),
paint);

// Draw another thing to make sure the clip area is reset.
Paint red;
red.color = Color::Red();
canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);

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

} // namespace testing
} // namespace impeller
6 changes: 3 additions & 3 deletions impeller/entity/contents/filters/blend_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ static std::optional<Entity> AdvancedBlend(
if (!dst_snapshot.has_value()) {
return std::nullopt;
}
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(),
entity.GetClipDepth());
}
auto maybe_src_uvs = src_snapshot->GetCoverageUVs(coverage);
if (!maybe_src_uvs.has_value()) {
if (!dst_snapshot.has_value()) {
return std::nullopt;
}
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(),
entity.GetClipDepth());
}
src_uvs = maybe_src_uvs.value();
Expand Down Expand Up @@ -426,7 +426,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
}

if (blend_mode == BlendMode::kDestination) {
return Entity::FromSnapshot(dst_snapshot, entity.GetBlendMode(),
return Entity::FromSnapshot(dst_snapshot.value(), entity.GetBlendMode(),
entity.GetClipDepth());
}

Expand Down
83 changes: 51 additions & 32 deletions impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,31 +204,12 @@ int ScaleBlurRadius(Scalar radius, Scalar scalar) {
return static_cast<int>(std::round(radius * scalar));
}

Entity ApplyBlurStyle(FilterContents::BlurStyle blur_style,
const Entity& entity,
const std::shared_ptr<FilterInput>& input,
const Snapshot& input_snapshot,
Entity blur_entity,
const std::shared_ptr<Geometry>& geometry) {
if (blur_style == FilterContents::BlurStyle::kNormal) {
return blur_entity;
}
Entity::ClipOperation clip_operation;
switch (blur_style) {
case FilterContents::BlurStyle::kNormal:
FML_UNREACHABLE();
break;
case FilterContents::BlurStyle::kInner:
clip_operation = Entity::ClipOperation::kIntersect;
break;
case FilterContents::BlurStyle::kOuter:
clip_operation = Entity::ClipOperation::kDifference;
break;
case FilterContents::BlurStyle::kSolid:
FML_DLOG(ERROR) << "Unimplemented blur style";
return blur_entity;
}

Entity ApplyClippedBlurStyle(Entity::ClipOperation clip_operation,
const Entity& entity,
const std::shared_ptr<FilterInput>& input,
const Snapshot& input_snapshot,
Entity blur_entity,
const std::shared_ptr<Geometry>& geometry) {
auto shared_blur_entity = std::make_shared<Entity>(std::move(blur_entity));
shared_blur_entity->SetNewClipDepth(entity.GetNewClipDepth());
auto clipper = std::make_unique<ClipContents>();
Expand All @@ -255,6 +236,48 @@ Entity ApplyBlurStyle(FilterContents::BlurStyle blur_style,
}));
return result;
}

Entity ApplyBlurStyle(FilterContents::BlurStyle blur_style,
const Entity& entity,
const std::shared_ptr<FilterInput>& input,
const Snapshot& input_snapshot,
Entity blur_entity,
const std::shared_ptr<Geometry>& geometry) {
switch (blur_style) {
case FilterContents::BlurStyle::kNormal:
return blur_entity;
case FilterContents::BlurStyle::kInner:
return ApplyClippedBlurStyle(Entity::ClipOperation::kIntersect, entity,
input, input_snapshot,
std::move(blur_entity), geometry);
break;
case FilterContents::BlurStyle::kOuter:
return ApplyClippedBlurStyle(Entity::ClipOperation::kDifference, entity,
input, input_snapshot,
std::move(blur_entity), geometry);
case FilterContents::BlurStyle::kSolid: {
Entity blurred = ApplyClippedBlurStyle(Entity::ClipOperation::kIntersect,
entity, input, input_snapshot,
std::move(blur_entity), geometry);
Entity snapshot_entity = Entity::FromSnapshot(
input_snapshot, entity.GetBlendMode(), entity.GetClipDepth());
Entity result;
std::optional<Rect> coverage = blurred.GetCoverage();
result.SetContents(Contents::MakeAnonymous(
fml::MakeCopyable([blurred = std::move(blurred),
snapshot_entity = std::move(snapshot_entity)](
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) mutable {
return blurred.Render(renderer, pass) &&
snapshot_entity.Render(renderer, pass);
}),
fml::MakeCopyable(
[coverage](const Entity& entity) { return coverage; })));
return result;
}
}
}
} // namespace

std::string_view GaussianBlurFilterContents::kNoMipsError =
Expand Down Expand Up @@ -499,7 +522,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
SamplerDescriptor sampler_desc = MakeSamplerDescriptor(
MinMagFilter::kLinear, SamplerAddressMode::kClampToEdge);

auto blur_output_entity = Entity::FromSnapshot(
Entity blur_output_entity = Entity::FromSnapshot(
Snapshot{.texture = pass3_out.value().GetRenderTargetTexture(),
.transform = input_snapshot->transform *
padding_snapshot_adjustment *
Expand All @@ -508,13 +531,9 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
.opacity = input_snapshot->opacity},
entity.GetBlendMode(), entity.GetClipDepth());

if (!blur_output_entity.has_value()) {
return std::nullopt;
}

return ApplyBlurStyle(mask_blur_style_, entity, inputs[0],
input_snapshot.value(),
std::move(blur_output_entity.value()), mask_geometry_);
input_snapshot.value(), std::move(blur_output_entity),
mask_geometry_);
}

Scalar GaussianBlurFilterContents::CalculateBlurRadius(Scalar sigma) {
Expand Down
10 changes: 7 additions & 3 deletions impeller/entity/contents/filters/local_matrix_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ std::optional<Entity> LocalMatrixFilterContents::RenderFilter(
const Matrix& effect_transform,
const Rect& coverage,
const std::optional<Rect>& coverage_hint) const {
return Entity::FromSnapshot(
inputs[0]->GetSnapshot("LocalMatrix", renderer, entity),
entity.GetBlendMode(), entity.GetClipDepth());
std::optional<Snapshot> snapshot =
inputs[0]->GetSnapshot("LocalMatrix", renderer, entity);
if (!snapshot.has_value()) {
return std::nullopt;
}
return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode(),
entity.GetClipDepth());
}

} // namespace impeller
5 changes: 4 additions & 1 deletion impeller/entity/contents/filters/matrix_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ std::optional<Entity> MatrixFilterContents::RenderFilter(
snapshot->transform;

snapshot->sampler_descriptor = sampler_descriptor_;
return Entity::FromSnapshot(snapshot, entity.GetBlendMode(),
if (!snapshot.has_value()) {
return std::nullopt;
}
return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode(),
entity.GetClipDepth());
}

Expand Down
21 changes: 8 additions & 13 deletions impeller/entity/entity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,21 @@

namespace impeller {

std::optional<Entity> Entity::FromSnapshot(
const std::optional<Snapshot>& snapshot,
BlendMode blend_mode,
uint32_t clip_depth) {
if (!snapshot.has_value()) {
return std::nullopt;
}

auto texture_rect = Rect::MakeSize(snapshot->texture->GetSize());
Entity Entity::FromSnapshot(const Snapshot& snapshot,
BlendMode blend_mode,
uint32_t clip_depth) {
auto texture_rect = Rect::MakeSize(snapshot.texture->GetSize());

auto contents = TextureContents::MakeRect(texture_rect);
contents->SetTexture(snapshot->texture);
contents->SetSamplerDescriptor(snapshot->sampler_descriptor);
contents->SetTexture(snapshot.texture);
contents->SetSamplerDescriptor(snapshot.sampler_descriptor);
contents->SetSourceRect(texture_rect);
contents->SetOpacity(snapshot->opacity);
contents->SetOpacity(snapshot.opacity);

Entity entity;
entity.SetBlendMode(blend_mode);
entity.SetClipDepth(clip_depth);
entity.SetTransform(snapshot->transform);
entity.SetTransform(snapshot.transform);
entity.SetContents(contents);
return entity;
}
Expand Down
7 changes: 3 additions & 4 deletions impeller/entity/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ class Entity {
};

/// @brief Create an entity that can be used to render a given snapshot.
static std::optional<Entity> FromSnapshot(
const std::optional<Snapshot>& snapshot,
BlendMode blend_mode = BlendMode::kSourceOver,
uint32_t clip_depth = 0);
static Entity FromSnapshot(const Snapshot& snapshot,
BlendMode blend_mode = BlendMode::kSourceOver,
uint32_t clip_depth = 0);

Entity();

Expand Down
3 changes: 3 additions & 0 deletions testing/impeller_golden_tests_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ impeller_Play_AiksTest_GaussianBlurStyleInner_Vulkan.png
impeller_Play_AiksTest_GaussianBlurStyleOuter_Metal.png
impeller_Play_AiksTest_GaussianBlurStyleOuter_OpenGLES.png
impeller_Play_AiksTest_GaussianBlurStyleOuter_Vulkan.png
impeller_Play_AiksTest_GaussianBlurStyleSolid_Metal.png
impeller_Play_AiksTest_GaussianBlurStyleSolid_OpenGLES.png
impeller_Play_AiksTest_GaussianBlurStyleSolid_Vulkan.png
impeller_Play_AiksTest_GaussianBlurWithoutDecalSupport_Metal.png
impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal.png
impeller_Play_AiksTest_GradientStrokesRenderCorrectly_OpenGLES.png
Expand Down