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

Commit 4445f86

Browse files
author
Chris Yang
committed
draft
draft format format clean
1 parent 5a71874 commit 4445f86

13 files changed

+240
-146
lines changed

flow/embedded_views.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ void MutatorsStack::PushOpacity(const int& alpha) {
100100
};
101101

102102
void MutatorsStack::PushBackdropFilter(
103-
const std::shared_ptr<const DlImageFilter>& filter) {
104-
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(filter);
103+
const std::shared_ptr<const DlImageFilter>& filter,
104+
const SkRect& filter_rect) {
105+
std::shared_ptr<Mutator> element =
106+
std::make_shared<Mutator>(filter, filter_rect);
105107
vector_.push_back(element);
106108
};
107109

flow/embedded_views.h

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,33 @@ enum MutatorType {
3232
kBackdropFilter
3333
};
3434

35+
// Represents an image filter mutation.
36+
//
37+
// Should be used for image_filter_layer and backdrop_filter_layer.
38+
// TODO(cyanglaz): Refactor this into a ImageFilterMutator class.
39+
// https://github.com/flutter/flutter/issues/108470
40+
class ImageFilterMutation {
41+
public:
42+
ImageFilterMutation(std::shared_ptr<const DlImageFilter> filter,
43+
const SkRect& filter_rect)
44+
: filter_(filter), filter_rect_(filter_rect) {}
45+
46+
const DlImageFilter& GetFilter() const { return *filter_; }
47+
const SkRect& GetFilterRect() const { return filter_rect_; }
48+
49+
bool operator==(const ImageFilterMutation& other) const {
50+
return *filter_ == *other.filter_ && filter_rect_ == other.filter_rect_;
51+
}
52+
53+
bool operator!=(const ImageFilterMutation& other) const {
54+
return !operator==(other);
55+
}
56+
57+
private:
58+
std::shared_ptr<const DlImageFilter> filter_;
59+
const SkRect filter_rect_;
60+
};
61+
3562
// Stores mutation information like clipping or kTransform.
3663
//
3764
// The `type` indicates the type of the mutation: kClipRect, kTransform and etc.
@@ -73,15 +100,17 @@ class Mutator {
73100
explicit Mutator(const SkMatrix& matrix)
74101
: type_(kTransform), matrix_(matrix) {}
75102
explicit Mutator(const int& alpha) : type_(kOpacity), alpha_(alpha) {}
76-
explicit Mutator(std::shared_ptr<const DlImageFilter> filter)
77-
: type_(kBackdropFilter), filter_(filter) {}
103+
explicit Mutator(std::shared_ptr<const DlImageFilter> filter,
104+
const SkRect& filter_rect)
105+
: type_(kBackdropFilter),
106+
filter_(std::make_shared<ImageFilterMutation>(filter, filter_rect)) {}
78107

79108
const MutatorType& GetType() const { return type_; }
80109
const SkRect& GetRect() const { return rect_; }
81110
const SkRRect& GetRRect() const { return rrect_; }
82111
const SkPath& GetPath() const { return *path_; }
83112
const SkMatrix& GetMatrix() const { return matrix_; }
84-
const DlImageFilter& GetFilter() const { return *filter_; }
113+
const ImageFilterMutation& GetFilter() const { return *filter_; }
85114
const int& GetAlpha() const { return alpha_; }
86115
float GetAlphaFloat() const { return (alpha_ / 255.0); }
87116

@@ -132,8 +161,7 @@ class Mutator {
132161
int alpha_;
133162
};
134163

135-
std::shared_ptr<const DlImageFilter> filter_;
136-
164+
std::shared_ptr<ImageFilterMutation> filter_;
137165
}; // Mutator
138166

139167
// A stack of mutators that can be applied to an embedded platform view.
@@ -154,7 +182,8 @@ class MutatorsStack {
154182
void PushClipPath(const SkPath& path);
155183
void PushTransform(const SkMatrix& matrix);
156184
void PushOpacity(const int& alpha);
157-
void PushBackdropFilter(const std::shared_ptr<const DlImageFilter>& filter);
185+
void PushBackdropFilter(const std::shared_ptr<const DlImageFilter>& filter,
186+
const SkRect& filter_rect);
158187

159188
// Removes the `Mutator` on the top of the stack
160189
// and destroys it.
@@ -249,8 +278,9 @@ class EmbeddedViewParams {
249278
const SkRect& finalBoundingRect() const { return final_bounding_rect_; }
250279

251280
// Pushes the stored DlImageFilter object to the mutators stack.
252-
void PushImageFilter(std::shared_ptr<const DlImageFilter> filter) {
253-
mutators_stack_.PushBackdropFilter(filter);
281+
void PushImageFilter(std::shared_ptr<const DlImageFilter> filter,
282+
const SkRect& filter_rect) {
283+
mutators_stack_.PushBackdropFilter(filter, filter_rect);
254284
}
255285

256286
// Whether the embedder should construct DisplayList objects to hold the
@@ -454,7 +484,8 @@ class ExternalViewEmbedder {
454484
// See also: |PushVisitedPlatformView| for pushing platform view ids to the
455485
// visited platform views list.
456486
virtual void PushFilterToVisitedPlatformViews(
457-
std::shared_ptr<const DlImageFilter> filter) {}
487+
std::shared_ptr<const DlImageFilter> filter,
488+
const SkRect& filter_rect) {}
458489

459490
private:
460491
bool used_this_frame_ = false;

flow/layers/backdrop_filter_layer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ void BackdropFilterLayer::Preroll(PrerollContext* context,
4444
Layer::AutoPrerollSaveLayerState save =
4545
Layer::AutoPrerollSaveLayerState::Create(context, true, bool(filter_));
4646
if (context->view_embedder != nullptr) {
47-
context->view_embedder->PushFilterToVisitedPlatformViews(filter_);
47+
context->view_embedder->PushFilterToVisitedPlatformViews(
48+
filter_, context->cull_rect);
4849
}
4950
SkRect child_paint_bounds = SkRect::MakeEmpty();
5051
PrerollChildren(context, matrix, &child_paint_bounds);

flow/mutators_stack_unittests.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,14 @@ TEST(MutatorsStack, PushBackdropFilter) {
9494
const int num_of_mutators = 10;
9595
for (int i = 0; i < num_of_mutators; i++) {
9696
auto filter = std::make_shared<DlBlurImageFilter>(i, 5, DlTileMode::kClamp);
97-
stack.PushBackdropFilter(filter);
97+
stack.PushBackdropFilter(filter, SkRect::MakeEmpty());
9898
}
9999

100100
auto iter = stack.Begin();
101101
int i = 0;
102102
while (iter != stack.End()) {
103103
ASSERT_EQ(iter->get()->GetType(), MutatorType::kBackdropFilter);
104-
ASSERT_EQ(iter->get()->GetFilter().asBlur()->sigma_x(), i);
104+
ASSERT_EQ(iter->get()->GetFilter().GetFilter().asBlur()->sigma_x(), i);
105105
++iter;
106106
++i;
107107
}
@@ -164,7 +164,7 @@ TEST(MutatorsStack, Equality) {
164164
int alpha = 240;
165165
stack.PushOpacity(alpha);
166166
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
167-
stack.PushBackdropFilter(filter);
167+
stack.PushBackdropFilter(filter, SkRect::MakeEmpty());
168168

169169
MutatorsStack stack_other;
170170
SkMatrix matrix_other = SkMatrix::Scale(1, 1);
@@ -179,7 +179,7 @@ TEST(MutatorsStack, Equality) {
179179
stack_other.PushOpacity(other_alpha);
180180
auto other_filter =
181181
std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
182-
stack_other.PushBackdropFilter(other_filter);
182+
stack_other.PushBackdropFilter(other_filter, SkRect::MakeEmpty());
183183

184184
ASSERT_TRUE(stack == stack_other);
185185
}
@@ -211,9 +211,9 @@ TEST(Mutator, Initialization) {
211211
ASSERT_TRUE(mutator5.GetType() == MutatorType::kOpacity);
212212

213213
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
214-
Mutator mutator6 = Mutator(filter);
214+
Mutator mutator6 = Mutator(filter, SkRect::MakeEmpty());
215215
ASSERT_TRUE(mutator6.GetType() == MutatorType::kBackdropFilter);
216-
ASSERT_TRUE(mutator6.GetFilter() == *filter);
216+
ASSERT_TRUE(mutator6.GetFilter().GetFilter() == *filter);
217217
}
218218

219219
TEST(Mutator, CopyConstructor) {
@@ -244,7 +244,7 @@ TEST(Mutator, CopyConstructor) {
244244
ASSERT_TRUE(mutator5 == copy5);
245245

246246
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
247-
Mutator mutator6 = Mutator(filter);
247+
Mutator mutator6 = Mutator(filter, SkRect::MakeEmpty());
248248
Mutator copy6 = Mutator(mutator6);
249249
ASSERT_TRUE(mutator6 == copy6);
250250
}
@@ -277,8 +277,8 @@ TEST(Mutator, Equality) {
277277
ASSERT_TRUE(mutator5 == other_mutator5);
278278

279279
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
280-
Mutator mutator6 = Mutator(filter);
281-
Mutator other_mutator6 = Mutator(filter);
280+
Mutator mutator6 = Mutator(filter, SkRect::MakeEmpty());
281+
Mutator other_mutator6 = Mutator(filter, SkRect::MakeEmpty());
282282
ASSERT_TRUE(mutator6 == other_mutator6);
283283
}
284284

@@ -299,8 +299,8 @@ TEST(Mutator, UnEquality) {
299299
auto filter = std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
300300
auto filter2 =
301301
std::make_shared<DlBlurImageFilter>(10, 10, DlTileMode::kClamp);
302-
Mutator mutator3 = Mutator(filter);
303-
Mutator other_mutator3 = Mutator(filter2);
302+
Mutator mutator3 = Mutator(filter, SkRect::MakeEmpty());
303+
Mutator other_mutator3 = Mutator(filter2, SkRect::MakeEmpty());
304304
ASSERT_TRUE(mutator3 != other_mutator3);
305305
}
306306

shell/common/shell_test_external_view_embedder.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,11 @@ void ShellTestExternalViewEmbedder::PushVisitedPlatformView(int64_t view_id) {
8989

9090
// |ExternalViewEmbedder|
9191
void ShellTestExternalViewEmbedder::PushFilterToVisitedPlatformViews(
92-
std::shared_ptr<const DlImageFilter> filter) {
92+
std::shared_ptr<const DlImageFilter> filter,
93+
const SkRect& filter_rect) {
9394
for (int64_t id : visited_platform_views_) {
9495
EmbeddedViewParams params = current_composition_params_[id];
95-
params.PushImageFilter(filter);
96+
params.PushImageFilter(filter, filter_rect);
9697
current_composition_params_[id] = params;
9798
mutators_stacks_[id] = params.mutatorsStack();
9899
}

shell/common/shell_test_external_view_embedder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
7676

7777
// |ExternalViewEmbedder|
7878
void PushFilterToVisitedPlatformViews(
79-
std::shared_ptr<const DlImageFilter> filter) override;
79+
std::shared_ptr<const DlImageFilter> filter,
80+
const SkRect& filter_rect) override;
8081

8182
// |ExternalViewEmbedder|
8283
void SubmitFrame(GrDirectContext* context,

shell/common/shell_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) {
844844
auto filter = DlBlurImageFilter(5, 5, DlTileMode::kClamp);
845845
auto mutator = *external_view_embedder->GetStack(50).Begin();
846846
ASSERT_EQ(mutator->GetType(), MutatorType::kBackdropFilter);
847-
ASSERT_EQ(mutator->GetFilter(), filter);
847+
ASSERT_EQ(mutator->GetFilter().GetFilter(), filter);
848848

849849
DestroyShell(std::move(shell));
850850
}

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,11 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
321321
}
322322

323323
void FlutterPlatformViewsController::PushFilterToVisitedPlatformViews(
324-
std::shared_ptr<const DlImageFilter> filter) {
324+
std::shared_ptr<const DlImageFilter> filter,
325+
const SkRect& filter_rect) {
325326
for (int64_t id : visited_platform_views_) {
326327
EmbeddedViewParams params = current_composition_params_[id];
327-
params.PushImageFilter(filter);
328+
params.PushImageFilter(filter, filter_rect);
328329
current_composition_params_[id] = params;
329330
}
330331
}
@@ -425,7 +426,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
425426
CGRectGetWidth(flutter_view.bounds),
426427
CGRectGetHeight(flutter_view.bounds))] autorelease];
427428

428-
NSMutableArray* blurRadii = [[[NSMutableArray alloc] init] autorelease];
429+
NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease];
429430

430431
auto iter = mutators_stack.Begin();
431432
while (iter != mutators_stack.End()) {
@@ -448,13 +449,24 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
448449
embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha;
449450
break;
450451
case kBackdropFilter: {
451-
// We only support DlBlurImageFilter for BackdropFilter.
452-
if ((*iter)->GetFilter().asBlur() && canApplyBlurBackdrop) {
452+
// Only support DlBlurImageFilter for BackdropFilter.
453+
if ((*iter)->GetFilter().GetFilter().asBlur() && canApplyBlurBackdrop) {
453454
// sigma_x is arbitrarily chosen as the radius value because Quartz sets
454455
// sigma_x and sigma_y equal to each other. DlBlurImageFilter's Tile Mode
455456
// is not supported in Quartz's gaussianBlur CAFilter, so it is not used
456457
// to blur the PlatformView.
457-
[blurRadii addObject:@((*iter)->GetFilter().asBlur()->sigma_x())];
458+
CGFloat blurRadius = (*iter)->GetFilter().GetFilter().asBlur()->sigma_x();
459+
CGRect filterRect = flutter::GetCGRectFromSkRect((*iter)->GetFilter().GetFilterRect());
460+
// `filterRect` reprents the rect that shouuld be filtered inside the `flutter_view_`.
461+
// The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be
462+
// filtered.
463+
CGRect intersection = CGRectIntersection(filterRect, clipView.frame);
464+
if (CGRectContainsRect(clipView.frame, intersection)) {
465+
CGRect frameInClipView = [flutter_view_.get() convertRect:intersection toView:clipView];
466+
PlatformViewFilter* filter = [[PlatformViewFilter alloc] initWithFrame:frameInClipView
467+
blurRadius:blurRadius];
468+
[blurFilters addObject:filter];
469+
}
458470
}
459471
break;
460472
}
@@ -463,15 +475,16 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
463475
}
464476

465477
if (canApplyBlurBackdrop) {
466-
canApplyBlurBackdrop = [clipView applyBlurBackdropFilters:blurRadii];
478+
canApplyBlurBackdrop = [clipView applyBlurBackdropFilters:blurFilters];
467479
}
468480

469481
// Reverse the offset of the clipView.
470482
// The clipView's frame includes the final translate of the final transform matrix.
471-
// So we need to revese this translate so the platform view can layout at the correct offset.
483+
// Thus, this translate needs to be reversed so the platform view can layout at the correct
484+
// offset.
472485
//
473-
// Note that we don't apply this transform matrix the clippings because clippings happen on the
474-
// mask view, whose origin is always (0,0) to the flutter_view.
486+
// Note that the transforms are not applied to the clipping paths because clipping paths happen on
487+
// the mask view, whose origin is always (0,0) to the flutter_view.
475488
CATransform3D reverseTranslate =
476489
CATransform3DMakeTranslation(-clipView.frame.origin.x, -clipView.frame.origin.y, 0);
477490
embedded_view.layer.transform = CATransform3DConcat(finalTransform, reverseTranslate);

0 commit comments

Comments
 (0)