Skip to content

Commit

Permalink
[Impeller] Add backdrop filter support; refactor EntityPass (flutter#…
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero authored and houhuayong committed Jun 21, 2022
1 parent c014a54 commit d43d756
Show file tree
Hide file tree
Showing 10 changed files with 498 additions and 204 deletions.
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ FILE: ../../../flutter/impeller/entity/entity_pass_delegate.h
FILE: ../../../flutter/impeller/entity/entity_playground.cc
FILE: ../../../flutter/impeller/entity/entity_playground.h
FILE: ../../../flutter/impeller/entity/entity_unittests.cc
FILE: ../../../flutter/impeller/entity/inline_pass_context.cc
FILE: ../../../flutter/impeller/entity/inline_pass_context.h
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag
Expand Down
7 changes: 5 additions & 2 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,17 @@ size_t Canvas::GetStencilDepth() const {
return xformation_stack_.back().stencil_depth;
}

void Canvas::SaveLayer(Paint paint, std::optional<Rect> bounds) {
void Canvas::SaveLayer(Paint paint,
std::optional<Rect> bounds,
std::optional<Paint::ImageFilterProc> backdrop_filter) {
Save(true, paint.blend_mode);

auto& new_layer_pass = GetCurrentPass();
new_layer_pass.SetDelegate(
std::make_unique<PaintPassDelegate>(paint, bounds));
new_layer_pass.SetBackdropFilter(backdrop_filter);

if (bounds.has_value()) {
if (bounds.has_value() && !backdrop_filter.has_value()) {
// Render target switches due to a save layer can be elided. In such cases
// where passes are collapsed into their parent, the clipping effect to
// the size of the render target that would have been allocated will be
Expand Down
5 changes: 4 additions & 1 deletion impeller/aiks/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ class Canvas {

void Save();

void SaveLayer(Paint paint, std::optional<Rect> bounds = std::nullopt);
void SaveLayer(
Paint paint,
std::optional<Rect> bounds = std::nullopt,
std::optional<Paint::ImageFilterProc> backdrop_filter = std::nullopt);

bool Restore();

Expand Down
25 changes: 15 additions & 10 deletions impeller/display_list/display_list_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,12 @@ void DisplayListDispatcher::setMaskFilter(const flutter::DlMaskFilter* filter) {
}
}

// |flutter::Dispatcher|
void DisplayListDispatcher::setImageFilter(
static std::optional<Paint::ImageFilterProc> ToImageFilterProc(
const flutter::DlImageFilter* filter) {
if (filter == nullptr) {
return std::nullopt;
}

switch (filter->type()) {
case flutter::DlImageFilterType::kBlur: {
auto blur = filter->asBlur();
Expand All @@ -338,7 +341,7 @@ void DisplayListDispatcher::setImageFilter(
UNIMPLEMENTED;
}

paint_.image_filter = [sigma_x, sigma_y](FilterInput::Ref input) {
return [sigma_x, sigma_y](FilterInput::Ref input) {
return FilterContents::MakeGaussianBlur(input, sigma_x, sigma_y);
};

Expand All @@ -350,11 +353,16 @@ void DisplayListDispatcher::setImageFilter(
case flutter::DlImageFilterType::kComposeFilter:
case flutter::DlImageFilterType::kColorFilter:
case flutter::DlImageFilterType::kUnknown:
UNIMPLEMENTED;
break;
return std::nullopt;
}
}

// |flutter::Dispatcher|
void DisplayListDispatcher::setImageFilter(
const flutter::DlImageFilter* filter) {
paint_.image_filter = ToImageFilterProc(filter);
}

// |flutter::Dispatcher|
void DisplayListDispatcher::save() {
canvas_.Save();
Expand All @@ -371,11 +379,8 @@ static std::optional<Rect> ToRect(const SkRect* rect) {
void DisplayListDispatcher::saveLayer(const SkRect* bounds,
const flutter::SaveLayerOptions options,
const flutter::DlImageFilter* backdrop) {
if (backdrop) {
UNIMPLEMENTED;
}
canvas_.SaveLayer(options.renders_with_attributes() ? paint_ : Paint{},
ToRect(bounds));
auto paint = options.renders_with_attributes() ? paint_ : Paint{};
canvas_.SaveLayer(paint, ToRect(bounds), ToImageFilterProc(backdrop));
}

// |flutter::Dispatcher|
Expand Down
61 changes: 61 additions & 0 deletions impeller/display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// found in the LICENSE file.

#include "display_list/display_list_blend_mode.h"
#include "display_list/display_list_color.h"
#include "display_list/display_list_color_filter.h"
#include "display_list/display_list_image_filter.h"
#include "display_list/display_list_paint.h"
#include "display_list/display_list_tile_mode.h"
#include "gtest/gtest.h"
#include "third_party/imgui/imgui.h"
Expand Down Expand Up @@ -285,5 +287,64 @@ TEST_P(DisplayListTest, CanDrawWithImageBlurFilter) {
ASSERT_TRUE(OpenPlaygroundHere(callback));
}

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

bool first_frame = true;
auto callback = [&]() {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({400, 100});
ImGui::SetNextWindowPos({300, 650});
}

static float sigma[] = {10, 10};
static bool use_bounds = true;
static bool draw_circle = true;

ImGui::Begin("Controls");
ImGui::SliderFloat2("Sigma", sigma, 0, 100);
ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
ImGui::Checkbox("Draw child element", &draw_circle);
ImGui::End();

flutter::DisplayListBuilder builder;

Vector2 scale = GetContentScale();
builder.scale(scale.x, scale.y);

auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
flutter::DlTileMode::kClamp);

std::optional<SkRect> bounds;
if (use_bounds) {
auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
Point(250, 150), Point(800, 600), 20, Color::White(), Color::White());
bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
}

builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
SkSamplingOptions{}, true);
builder.saveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
&filter);

if (draw_circle) {
auto circle_center =
IMPELLER_PLAYGROUND_POINT(Point(500, 400), 20, Color::Red());

builder.setStyle(flutter::DlDrawStyle::kStroke);
builder.setStrokeCap(flutter::DlStrokeCap::kButt);
builder.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
builder.setStrokeWidth(10);
builder.setColor(flutter::DlColor::kRed().withAlpha(100));
builder.drawCircle({circle_center.x, circle_center.y}, 100);
}

return builder.Build();
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

} // namespace testing
} // namespace impeller
2 changes: 2 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ impeller_component("entity") {
"entity_pass.h",
"entity_pass_delegate.cc",
"entity_pass_delegate.h",
"inline_pass_context.cc",
"inline_pass_context.h",
]

public_deps = [
Expand Down
Loading

0 comments on commit d43d756

Please sign in to comment.