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
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,8 @@ FILE: ../../../flutter/impeller/entity/contents/filters/blend_filter_contents.cc
FILE: ../../../flutter/impeller/entity/contents/filters/blend_filter_contents.h
FILE: ../../../flutter/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc
FILE: ../../../flutter/impeller/entity/contents/filters/border_mask_blur_filter_contents.h
FILE: ../../../flutter/impeller/entity/contents/filters/color_filter_contents.cc
FILE: ../../../flutter/impeller/entity/contents/filters/color_filter_contents.h
FILE: ../../../flutter/impeller/entity/contents/filters/color_matrix_filter_contents.cc
FILE: ../../../flutter/impeller/entity/contents/filters/color_matrix_filter_contents.h
FILE: ../../../flutter/impeller/entity/contents/filters/filter_contents.cc
Expand Down
37 changes: 34 additions & 3 deletions impeller/aiks/paint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,53 @@ std::shared_ptr<Contents> Paint::WithFilters(
std::optional<bool> is_solid_color,
const Matrix& effect_transform) const {
bool is_solid_color_val = is_solid_color.value_or(!color_source);
input = WithMaskBlur(input, is_solid_color_val, effect_transform);
input = WithImageFilter(input, effect_transform);
input = WithColorFilter(input);
return input;
}

std::shared_ptr<Contents> Paint::WithFiltersForSubpassTarget(
std::shared_ptr<Contents> input,
const Matrix& effect_transform) const {
input = WithMaskBlur(input, false, effect_transform);
input = WithImageFilter(input, effect_transform);
input = WithColorFilter(input, /**absorb_opacity=*/true);
return input;
}

std::shared_ptr<Contents> Paint::WithMaskBlur(
std::shared_ptr<Contents> input,
bool is_solid_color,
const Matrix& effect_transform) const {
if (mask_blur_descriptor.has_value()) {
input = mask_blur_descriptor->CreateMaskBlur(
FilterInput::Make(input), is_solid_color_val, effect_transform);
FilterInput::Make(input), is_solid_color, effect_transform);
}
return input;
}

std::shared_ptr<Contents> Paint::WithImageFilter(
std::shared_ptr<Contents> input,
const Matrix& effect_transform) const {
if (image_filter.has_value()) {
const ImageFilterProc& filter = image_filter.value();
input = filter(FilterInput::Make(input), effect_transform);
}
return input;
}

std::shared_ptr<Contents> Paint::WithColorFilter(
std::shared_ptr<Contents> input,
bool absorb_opacity) const {
if (color_filter.has_value()) {
const ColorFilterProc& filter = color_filter.value();
input = filter(FilterInput::Make(input));
auto color_filter_contents = filter(FilterInput::Make(input));
if (color_filter_contents) {
color_filter_contents->SetAbsorbOpacity(absorb_opacity);
}
input = color_filter_contents;
}

return input;
}

Expand Down
27 changes: 26 additions & 1 deletion impeller/aiks/paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "flutter/fml/macros.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/contents/filters/color_filter_contents.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/linear_gradient_contents.h"
#include "impeller/entity/contents/radial_gradient_contents.h"
Expand All @@ -23,7 +24,7 @@ struct Paint {
FilterInput::Ref,
const Matrix& effect_transform)>;
using ColorFilterProc =
std::function<std::shared_ptr<FilterContents>(FilterInput::Ref)>;
std::function<std::shared_ptr<ColorFilterContents>(FilterInput::Ref)>;
using MaskFilterProc = std::function<std::shared_ptr<FilterContents>(
FilterInput::Ref,
bool is_solid_color,
Expand Down Expand Up @@ -75,8 +76,32 @@ struct Paint {
std::optional<bool> is_solid_color = std::nullopt,
const Matrix& effect_transform = Matrix()) const;

/// @brief Wrap this paint's configured filters to the given contents of
/// subpass target.
/// @param[in] input The contents of subpass target to wrap with paint's
/// filters.
///
/// @return The filter-wrapped contents. If there are no filters that need
/// to be wrapped for the current paint configuration, the
/// original contents is returned.
std::shared_ptr<Contents> WithFiltersForSubpassTarget(
std::shared_ptr<Contents> input,
const Matrix& effect_transform = Matrix()) const;

std::shared_ptr<Contents> CreateContentsForEntity(Path path = {},
bool cover = false) const;

private:
std::shared_ptr<Contents> WithMaskBlur(std::shared_ptr<Contents> input,
bool is_solid_color,
const Matrix& effect_transform) const;

std::shared_ptr<Contents> WithImageFilter(
std::shared_ptr<Contents> input,
const Matrix& effect_transform) const;

std::shared_ptr<Contents> WithColorFilter(std::shared_ptr<Contents> input,
bool absorb_opacity = false) const;
};

} // namespace impeller
5 changes: 3 additions & 2 deletions impeller/aiks/paint_pass_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ std::shared_ptr<Contents> PaintPassDelegate::CreateContentsForSubpassTarget(
contents->SetTexture(target);
contents->SetSourceRect(Rect::MakeSize(target->GetSize()));
contents->SetOpacity(paint_.color.alpha);

return paint_.WithFilters(std::move(contents), false, effect_transform);
contents->SetDeferApplyingOpacity(true);
return paint_.WithFiltersForSubpassTarget(std::move(contents),
effect_transform);
}

} // namespace impeller
8 changes: 4 additions & 4 deletions impeller/display_list/display_list_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -447,24 +447,24 @@ static std::optional<Paint::ColorFilterProc> ToColorFilterProc(
auto blend_mode = ToBlendMode(dl_blend->mode());
auto color = ToColor(dl_blend->color());
return [blend_mode, color](FilterInput::Ref input) {
return FilterContents::MakeBlend(blend_mode, {input}, color);
return ColorFilterContents::MakeBlend(blend_mode, {input}, color);
};
}
case flutter::DlColorFilterType::kMatrix: {
const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
impeller::FilterContents::ColorMatrix color_matrix;
dl_matrix->get_matrix(color_matrix.array);
return [color_matrix](FilterInput::Ref input) {
return FilterContents::MakeColorMatrix({input}, color_matrix);
return ColorFilterContents::MakeColorMatrix({input}, color_matrix);
};
}
case flutter::DlColorFilterType::kSrgbToLinearGamma:
return [](FilterInput::Ref input) {
return FilterContents::MakeSrgbToLinearFilter({input});
return ColorFilterContents::MakeSrgbToLinearFilter({input});
};
case flutter::DlColorFilterType::kLinearToSrgbGamma:
return [](FilterInput::Ref input) {
return FilterContents::MakeLinearToSrgbFilter({input});
return ColorFilterContents::MakeLinearToSrgbFilter({input});
};
case flutter::DlColorFilterType::kUnknown:
FML_LOG(ERROR) << "requested DlColorFilterType::kUnknown";
Expand Down
117 changes: 117 additions & 0 deletions impeller/display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,123 @@ TEST_P(DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(DisplayListTest, SaveLayerWithColorMatrixFiltersAndAlphaDrawCorrectly) {
auto texture = CreateTextureForFixture("boston.jpg");
bool first_frame = true;
enum class Type { kUseAsImageFilter, kUseAsColorFilter, kDisableFilter };
auto callback = [&]() {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowPos({10, 10});
}

static float alpha = 0.5;
static int selected_type = 0;
const char* names[] = {"Use as image filter", "Use as color filter",
"Disable filter"};

static float color_matrix[20] = {
1, 0, 0, 0, 0, //
0, 1, 0, 0, 0, //
0, 0, 1, 0, 0, //
0, 0, 0, 2, 0, //
};

ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::SliderFloat("Alpha", &alpha, 0, 1);

ImGui::Combo("Type", &selected_type, names, sizeof(names) / sizeof(char*));
std::string label = "##1";
for (int i = 0; i < 20; i += 5) {
ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
&(color_matrix[i]), 5, nullptr, nullptr, "%.2f", 0);
label[2]++;
}
ImGui::End();

flutter::DisplayListBuilder builder;
flutter::DlPaint save_paint;
save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
auto color_filter =
std::make_shared<flutter::DlMatrixColorFilter>(color_matrix);
Type type = static_cast<Type>(selected_type);
switch (type) {
case Type::kUseAsImageFilter: {
auto image_filter =
std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
save_paint.setImageFilter(image_filter);
break;
}
case Type::kUseAsColorFilter: {
save_paint.setColorFilter(color_filter);
break;
}
case Type::kDisableFilter:
break;
}
builder.saveLayer(nullptr, &save_paint);
flutter::DlPaint draw_paint;
builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
flutter::DlImageSampling::kNearestNeighbor, &draw_paint);
builder.restore();
return builder.Build();
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(DisplayListTest, SaveLayerWithBlendFiltersAndAlphaDrawCorrectly) {
auto texture = CreateTextureForFixture("boston.jpg");
bool first_frame = true;
enum class Type { kUseAsImageFilter, kUseAsColorFilter, kDisableFilter };
auto callback = [&]() {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowPos({10, 10});
}

static float alpha = 0.5;
static int selected_type = 0;
const char* names[] = {"Use as image filter", "Use as color filter",
"Disable filter"};

ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::SliderFloat("Alpha", &alpha, 0, 1);

ImGui::Combo("Type", &selected_type, names, sizeof(names) / sizeof(char*));
ImGui::End();

flutter::DisplayListBuilder builder;
flutter::DlPaint save_paint;
save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
auto color_filter = std::make_shared<flutter::DlBlendColorFilter>(
flutter::DlColor::kRed(), flutter::DlBlendMode::kDstOver);
Type type = static_cast<Type>(selected_type);
switch (type) {
case Type::kUseAsImageFilter: {
auto image_filter =
std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
save_paint.setImageFilter(image_filter);
break;
}
case Type::kUseAsColorFilter: {
save_paint.setColorFilter(color_filter);
break;
}
case Type::kDisableFilter:
break;
}
builder.saveLayer(nullptr, &save_paint);
flutter::DlPaint draw_paint;
draw_paint.setColor(flutter::DlColor::kBlue());
builder.drawRect(SkRect::MakeLTRB(100, 100, 400, 400), draw_paint);
builder.restore();
return builder.Build();
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(DisplayListTest, CanDrawBackdropFilter) {
auto texture = CreateTextureForFixture("embarcadero.jpg");

Expand Down
2 changes: 2 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ impeller_component("entity") {
"contents/filters/blend_filter_contents.h",
"contents/filters/border_mask_blur_filter_contents.cc",
"contents/filters/border_mask_blur_filter_contents.h",
"contents/filters/color_filter_contents.cc",
"contents/filters/color_filter_contents.h",
"contents/filters/color_matrix_filter_contents.cc",
"contents/filters/color_matrix_filter_contents.h",
"contents/filters/filter_contents.cc",
Expand Down
Loading