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

Fix position of BackdropFilter above PlatformView #39244

Merged
merged 2 commits into from
Feb 9, 2023
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
5 changes: 5 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class MutatorsStack {
void PushClipPath(const SkPath& path);
void PushTransform(const SkMatrix& matrix);
void PushOpacity(const int& alpha);
// `filter_rect` is in global coordinates.
void PushBackdropFilter(const std::shared_ptr<const DlImageFilter>& filter,
const SkRect& filter_rect);

Expand Down Expand Up @@ -284,6 +285,8 @@ class EmbeddedViewParams {
const SkRect& finalBoundingRect() const { return final_bounding_rect_; }

// Pushes the stored DlImageFilter object to the mutators stack.
//
// `filter_rect` is in global coordinates.
void PushImageFilter(std::shared_ptr<const DlImageFilter> filter,
const SkRect& filter_rect) {
mutators_stack_.PushBackdropFilter(filter, filter_rect);
Expand Down Expand Up @@ -487,6 +490,8 @@ class ExternalViewEmbedder {
// Pushes a DlImageFilter object to each platform view within a list of
// visited platform views.
//
// `filter_rect` is in global coordinates.
//
// See also: |PushVisitedPlatformView| for pushing platform view ids to the
// visited platform views list.
virtual void PushFilterToVisitedPlatformViews(
Expand Down
2 changes: 1 addition & 1 deletion flow/layers/backdrop_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void BackdropFilterLayer::Preroll(PrerollContext* context) {
Layer::AutoPrerollSaveLayerState::Create(context, true, bool(filter_));
if (context->view_embedder != nullptr) {
context->view_embedder->PushFilterToVisitedPlatformViews(
filter_, context->state_stack.local_cull_rect());
filter_, context->state_stack.device_cull_rect());
}
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, &child_paint_bounds);
Expand Down
13 changes: 12 additions & 1 deletion shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "assets/directory_asset_bundle.h"
#include "common/graphics/persistent_cache.h"
#include "flutter/flow/layers/backdrop_filter_layer.h"
#include "flutter/flow/layers/clip_rect_layer.h"
#include "flutter/flow/layers/display_list_layer.h"
#include "flutter/flow/layers/layer_raster_cache_item.h"
#include "flutter/flow/layers/platform_view_layer.h"
Expand Down Expand Up @@ -827,10 +828,16 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) {
auto platform_view_layer = std::make_shared<PlatformViewLayer>(
SkPoint::Make(10, 10), SkSize::Make(10, 10), 50);
root->Add(platform_view_layer);
auto transform_layer =
std::make_shared<TransformLayer>(SkMatrix::Translate(1, 1));
root->Add(transform_layer);
auto clip_rect_layer = std::make_shared<ClipRectLayer>(
SkRect::MakeLTRB(0, 0, 30, 30), Clip::hardEdge);
transform_layer->Add(clip_rect_layer);
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
auto backdrop_filter_layer =
std::make_shared<BackdropFilterLayer>(filter, DlBlendMode::kSrcOver);
root->Add(backdrop_filter_layer);
clip_rect_layer->Add(backdrop_filter_layer);
auto platform_view_layer2 = std::make_shared<PlatformViewLayer>(
SkPoint::Make(10, 10), SkSize::Make(10, 10), 75);
backdrop_filter_layer->Add(platform_view_layer2);
Expand All @@ -846,6 +853,10 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) {
auto mutator = *external_view_embedder->GetStack(50).Begin();
ASSERT_EQ(mutator->GetType(), MutatorType::kBackdropFilter);
ASSERT_EQ(mutator->GetFilterMutation().GetFilter(), filter);
// Make sure the filterRect is in global coordinates (contains the (1,1)
// translation).
ASSERT_EQ(mutator->GetFilterMutation().GetFilterRect(),
SkRect::MakeLTRB(1, 1, 31, 31));

DestroyShell(std::move(shell));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
}
[mask_view_pool_.get() recycleMaskViews];
clipView.maskView = nil;
CGFloat screenScale = [UIScreen mainScreen].scale;
auto iter = mutators_stack.Begin();
while (iter != mutators_stack.End()) {
switch ((*iter)->GetType()) {
Expand Down Expand Up @@ -530,6 +531,9 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
}
CGRect filterRect =
flutter::GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect());
// `filterRect` is in global coordinates. We need to convert to local space.
filterRect = CGRectApplyAffineTransform(
filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale));
// `filterRect` reprents the rect that should be filtered inside the `flutter_view_`.
// The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be
// filtered.
Expand Down Expand Up @@ -564,7 +568,6 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
[clipView applyBlurBackdropFilters:blurFilters];
}

CGFloat screenScale = [UIScreen mainScreen].scale;
// The UIKit frame is set based on the logical resolution (points) instead of physical.
// (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html).
// However, flow is based on the physical resolution. For example, 1000 pixels in flow equals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,12 @@ - (void)testApplyBackdropFilter {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push a backdrop filter
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));

auto embeddedViewParams =
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
Expand Down Expand Up @@ -348,12 +348,12 @@ - (void)testApplyBackdropFilterWithCorrectFrame {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push a backdrop filter
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 8, 8));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));

auto embeddedViewParams =
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(5, 10), stack);
Expand Down Expand Up @@ -418,17 +418,17 @@ - (void)testApplyMultipleBackdropFilters {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push backdrop filters
for (int i = 0; i < 50; i++) {
auto filter = std::make_shared<flutter::DlBlurImageFilter>(i, 2, flutter::DlTileMode::kClamp);
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

auto embeddedViewParams =
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(20, 20), stack);

flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
flutterPlatformViewsController->CompositeEmbeddedView(2);
Expand Down Expand Up @@ -489,12 +489,12 @@ - (void)testAddBackdropFilters {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push a backdrop filter
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));

auto embeddedViewParams =
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
Expand Down Expand Up @@ -530,7 +530,7 @@ - (void)testAddBackdropFilters {
stack2.PushTransform(screenScaleMatrix);
// Push backdrop filters
for (int i = 0; i < 2; i++) {
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -600,13 +600,13 @@ - (void)testRemoveBackdropFilters {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push backdrop filters
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
for (int i = 0; i < 5; i++) {
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

auto embeddedViewParams =
Expand Down Expand Up @@ -641,7 +641,7 @@ - (void)testRemoveBackdropFilters {
stack2.PushTransform(screenScaleMatrix);
// Push backdrop filters
for (int i = 0; i < 4; i++) {
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -735,13 +735,13 @@ - (void)testEditBackdropFilters {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push backdrop filters
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
for (int i = 0; i < 5; i++) {
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

auto embeddedViewParams =
Expand Down Expand Up @@ -780,11 +780,12 @@ - (void)testEditBackdropFilters {
auto filter2 =
std::make_shared<flutter::DlBlurImageFilter>(2, 5, flutter::DlTileMode::kClamp);

stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter2,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -833,11 +834,12 @@ - (void)testEditBackdropFilters {
if (i == 0) {
auto filter2 =
std::make_shared<flutter::DlBlurImageFilter>(2, 5, flutter::DlTileMode::kClamp);
stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter2,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -884,11 +886,12 @@ - (void)testEditBackdropFilters {
if (i == 4) {
auto filter2 =
std::make_shared<flutter::DlBlurImageFilter>(2, 5, flutter::DlTileMode::kClamp);
stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter2,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -936,7 +939,7 @@ - (void)testEditBackdropFilters {
for (int i = 0; i < 5; i++) {
auto filter2 = std::make_shared<flutter::DlBlurImageFilter>(i, 2, flutter::DlTileMode::kClamp);

stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -1007,8 +1010,8 @@ - (void)testApplyBackdropFilterNotDlBlurImageFilter {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);
// Push a dilate backdrop filter
auto dilateFilter = std::make_shared<flutter::DlDilateImageFilter>(5, 2);
Expand Down Expand Up @@ -1045,11 +1048,13 @@ - (void)testApplyBackdropFilterNotDlBlurImageFilter {

for (int i = 0; i < 5; i++) {
if (i == 2) {
stack2.PushBackdropFilter(dilateFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(dilateFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(blurFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(blurFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -1082,11 +1087,13 @@ - (void)testApplyBackdropFilterNotDlBlurImageFilter {
// Push backdrop filters and dilate filter
for (int i = 0; i < 5; i++) {
if (i == 0) {
stack2.PushBackdropFilter(dilateFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(dilateFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(blurFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(blurFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -1119,11 +1126,13 @@ - (void)testApplyBackdropFilterNotDlBlurImageFilter {
// Push backdrop filters and dilate filter
for (int i = 0; i < 5; i++) {
if (i == 4) {
stack2.PushBackdropFilter(dilateFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(dilateFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
continue;
}

stack2.PushBackdropFilter(blurFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(blurFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -1155,7 +1164,8 @@ - (void)testApplyBackdropFilterNotDlBlurImageFilter {
}
// Push dilate filters
for (int i = 0; i < 5; i++) {
stack2.PushBackdropFilter(dilateFilter, SkRect::MakeXYWH(0, 0, 10, 10));
stack2.PushBackdropFilter(dilateFilter,
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
}

embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
Expand Down Expand Up @@ -1352,8 +1362,8 @@ - (void)testBackdropFilterCorrectlyPushedAndReset {
// Create embedded view params
flutter::MutatorsStack stack;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
CGFloat screenScale = [UIScreen mainScreen].scale;
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
stack.PushTransform(screenScaleMatrix);

auto embeddedViewParams =
Expand All @@ -1363,8 +1373,8 @@ - (void)testBackdropFilterCorrectlyPushedAndReset {
flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
flutterPlatformViewsController->PushVisitedPlatformView(2);
auto filter = std::make_shared<flutter::DlBlurImageFilter>(5, 2, flutter::DlTileMode::kClamp);
flutterPlatformViewsController->PushFilterToVisitedPlatformViews(filter,
SkRect::MakeXYWH(0, 0, 10, 10));
flutterPlatformViewsController->PushFilterToVisitedPlatformViews(
filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
flutterPlatformViewsController->CompositeEmbeddedView(2);
XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:[ChildClippingView class]]);
ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
Expand Down