Skip to content

Commit

Permalink
Fix source blend (flutter#34066)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero authored Jun 15, 2022
1 parent ae357ca commit 1c22a58
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
2 changes: 1 addition & 1 deletion impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
case Entity::BlendMode::kSource:
color0.dst_alpha_blend_factor = BlendFactor::kZero;
color0.dst_color_blend_factor = BlendFactor::kZero;
color0.src_alpha_blend_factor = BlendFactor::kSourceAlpha;
color0.src_alpha_blend_factor = BlendFactor::kOne;
color0.src_color_blend_factor = BlendFactor::kOne;
break;
case Entity::BlendMode::kDestination:
Expand Down
52 changes: 40 additions & 12 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/contents/solid_color_contents.h"
#include "impeller/entity/contents/solid_stroke_contents.h"
#include "impeller/entity/contents/texture_contents.h"
#include "impeller/entity/contents/vertices_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass.h"
Expand Down Expand Up @@ -772,38 +773,47 @@ TEST_P(EntityTest, Filters) {
}

TEST_P(EntityTest, GaussianBlurFilter) {
auto bridge = CreateTextureForFixture("bay_bridge.jpg");
auto boston = CreateTextureForFixture("boston.jpg");
auto kalimba = CreateTextureForFixture("kalimba.jpg");
ASSERT_TRUE(bridge && boston && kalimba);
ASSERT_TRUE(boston);

bool first_frame = true;
auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({500, 250});
ImGui::SetNextWindowPos({300, 500});
ImGui::SetNextWindowSize({500, 290});
ImGui::SetNextWindowPos({300, 480});
}

const char* input_type_names[] = {"Texture", "Solid Color"};
const char* blur_type_names[] = {"Image blur", "Mask blur"};
const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
const FilterContents::BlurStyle blur_styles[] = {
FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};

// UI state.
static int selected_input_type = 0;
static Color input_color = Color::Black();
static int selected_blur_type = 0;
static float blur_amount[2] = {20, 20};
static int selected_blur_style = 0;
static Color cover_color(1, 0, 0, 0.2);
static Color bounds_color(0, 1, 0, 0.1);
static float offset[2] = {500, 400};
static float rotation = 0;
static float scale[2] = {0.5, 0.5};
static float scale[2] = {0.75, 0.75};
static float skew[2] = {0, 0};

ImGui::Begin("Controls");
{
ImGui::Combo("Input type", &selected_input_type, input_type_names,
sizeof(input_type_names) / sizeof(char*));
if (selected_input_type == 0) {
ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
} else {
ImGui::ColorEdit4("Input color",
reinterpret_cast<float*>(&input_color));
}
ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
sizeof(blur_type_names) / sizeof(char*));
ImGui::SliderFloat2("Blur", &blur_amount[0], 0, 200);
Expand All @@ -820,21 +830,39 @@ TEST_P(EntityTest, GaussianBlurFilter) {
}
ImGui::End();

auto blend =
FilterContents::MakeBlend(Entity::BlendMode::kScreen,
FilterInput::Make({boston, bridge, kalimba}));
std::shared_ptr<Contents> input;
Size input_size;

if (selected_input_type == 0) {
auto texture = std::make_shared<TextureContents>();
auto input_rect = Rect::MakeSize(Size(boston->GetSize()));
texture->SetSourceRect(input_rect);
texture->SetPath(PathBuilder{}.AddRect(input_rect).TakePath());
texture->SetTexture(boston);
texture->SetOpacity(input_color.alpha);

input = texture;
input_size = input_rect.size;
} else {
auto fill = std::make_shared<SolidColorContents>();
auto input_rect = Rect::MakeSize(Size(boston->GetSize()));
fill->SetColor(input_color);
fill->SetPath(PathBuilder{}.AddRect(input_rect).TakePath());

input = fill;
input_size = input_rect.size;
}

auto blur = FilterContents::MakeGaussianBlur(
FilterInput::Make(blend), FilterContents::Sigma{blur_amount[0]},
FilterInput::Make(input), FilterContents::Sigma{blur_amount[0]},
FilterContents::Sigma{blur_amount[1]},
blur_styles[selected_blur_style]);

auto mask_blur = FilterContents::MakeBorderMaskBlur(
FilterInput::Make(bridge), FilterContents::Sigma{blur_amount[0]},
FilterInput::Make(input), FilterContents::Sigma{blur_amount[0]},
FilterContents::Sigma{blur_amount[1]},
blur_styles[selected_blur_style]);

auto input_size = bridge->GetSize();
auto ctm = Matrix::MakeScale(GetContentScale()) *
Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
Matrix::MakeRotationZ(Radians(rotation)) *
Expand Down

0 comments on commit 1c22a58

Please sign in to comment.