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

Commit 8b6119e

Browse files
authored
Fix bounds of image_filter_layer (#16960)
1 parent 19c11f2 commit 8b6119e

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

flow/layers/image_filter_layer.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,21 @@ ImageFilterLayer::ImageFilterLayer(sk_sp<SkImageFilter> filter)
1111

1212
void ImageFilterLayer::Preroll(PrerollContext* context,
1313
const SkMatrix& matrix) {
14+
TRACE_EVENT0("flutter", "ImageFilterLayer::Preroll");
15+
1416
Layer::AutoPrerollSaveLayerState save =
1517
Layer::AutoPrerollSaveLayerState::Create(context);
16-
ContainerLayer::Preroll(context, matrix);
18+
19+
SkRect child_paint_bounds = SkRect::MakeEmpty();
20+
PrerollChildren(context, matrix, &child_paint_bounds);
21+
if (filter_) {
22+
const SkIRect filter_input_bounds = child_paint_bounds.roundOut();
23+
SkIRect filter_output_bounds =
24+
filter_->filterBounds(filter_input_bounds, SkMatrix::I(),
25+
SkImageFilter::kForward_MapDirection);
26+
child_paint_bounds = SkRect::Make(filter_output_bounds);
27+
}
28+
set_paint_bounds(child_paint_bounds);
1729

1830
if (!context->has_platform_view && context->raster_cache &&
1931
SkRect::Intersects(context->cull_rect, paint_bounds())) {

flow/layers/image_filter_layer_unittests.cc

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
8383
auto layer = std::make_shared<ImageFilterLayer>(layer_filter);
8484
layer->Add(mock_layer);
8585

86+
const SkRect child_rounded_bounds =
87+
SkRect::MakeLTRB(5.0f, 6.0f, 21.0f, 22.0f);
88+
8689
layer->Preroll(preroll_context(), initial_transform);
87-
EXPECT_EQ(layer->paint_bounds(), child_bounds);
90+
EXPECT_EQ(layer->paint_bounds(), child_rounded_bounds);
8891
EXPECT_TRUE(layer->needs_painting());
8992
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
9093

@@ -96,15 +99,35 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
9699
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
97100
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
98101
MockCanvas::DrawCall{
99-
1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
100-
nullptr, 2}},
102+
1, MockCanvas::SaveLayerData{child_rounded_bounds,
103+
filter_paint, nullptr, 2}},
101104
MockCanvas::DrawCall{
102105
2, MockCanvas::DrawPathData{child_path, child_paint}},
103106
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
104107
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
105108
}));
106109
}
107110

111+
TEST_F(ImageFilterLayerTest, SimpleFilterBounds) {
112+
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f);
113+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
114+
const SkPath child_path = SkPath().addRect(child_bounds);
115+
const SkPaint child_paint = SkPaint(SkColors::kYellow);
116+
const SkMatrix filter_transform = SkMatrix::MakeScale(2.0, 2.0);
117+
auto layer_filter = SkImageFilter::MakeMatrixFilter(
118+
filter_transform, SkFilterQuality::kMedium_SkFilterQuality, nullptr);
119+
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
120+
auto layer = std::make_shared<ImageFilterLayer>(layer_filter);
121+
layer->Add(mock_layer);
122+
123+
const SkRect filter_bounds = SkRect::MakeLTRB(10.0f, 12.0f, 42.0f, 44.0f);
124+
125+
layer->Preroll(preroll_context(), initial_transform);
126+
EXPECT_EQ(layer->paint_bounds(), filter_bounds);
127+
EXPECT_TRUE(layer->needs_painting());
128+
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
129+
}
130+
108131
TEST_F(ImageFilterLayerTest, MultipleChildren) {
109132
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f);
110133
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f);
@@ -123,10 +146,12 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) {
123146

124147
SkRect children_bounds = child_path1.getBounds();
125148
children_bounds.join(child_path2.getBounds());
149+
SkRect children_rounded_bounds = SkRect::Make(children_bounds.roundOut());
150+
126151
layer->Preroll(preroll_context(), initial_transform);
127152
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
128153
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
129-
EXPECT_EQ(layer->paint_bounds(), children_bounds);
154+
EXPECT_EQ(layer->paint_bounds(), children_rounded_bounds);
130155
EXPECT_TRUE(mock_layer1->needs_painting());
131156
EXPECT_TRUE(mock_layer2->needs_painting());
132157
EXPECT_TRUE(layer->needs_painting());
@@ -141,8 +166,8 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) {
141166
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
142167
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
143168
MockCanvas::DrawCall{
144-
1, MockCanvas::SaveLayerData{children_bounds, filter_paint,
145-
nullptr, 2}},
169+
1, MockCanvas::SaveLayerData{children_rounded_bounds,
170+
filter_paint, nullptr, 2}},
146171
MockCanvas::DrawCall{
147172
2, MockCanvas::DrawPathData{child_path1, child_paint1}},
148173
MockCanvas::DrawCall{
@@ -173,11 +198,16 @@ TEST_F(ImageFilterLayerTest, Nested) {
173198

174199
SkRect children_bounds = child_path1.getBounds();
175200
children_bounds.join(child_path2.getBounds());
201+
const SkRect children_rounded_bounds =
202+
SkRect::Make(children_bounds.roundOut());
203+
const SkRect mock_layer2_rounded_bounds =
204+
SkRect::Make(child_path2.getBounds().roundOut());
205+
176206
layer1->Preroll(preroll_context(), initial_transform);
177207
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
178208
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
179-
EXPECT_EQ(layer1->paint_bounds(), children_bounds);
180-
EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds());
209+
EXPECT_EQ(layer1->paint_bounds(), children_rounded_bounds);
210+
EXPECT_EQ(layer2->paint_bounds(), mock_layer2_rounded_bounds);
181211
EXPECT_TRUE(mock_layer1->needs_painting());
182212
EXPECT_TRUE(mock_layer2->needs_painting());
183213
EXPECT_TRUE(layer1->needs_painting());
@@ -194,14 +224,14 @@ TEST_F(ImageFilterLayerTest, Nested) {
194224
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
195225
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
196226
MockCanvas::DrawCall{
197-
1, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
198-
nullptr, 2}},
227+
1, MockCanvas::SaveLayerData{children_rounded_bounds,
228+
filter_paint1, nullptr, 2}},
199229
MockCanvas::DrawCall{
200230
2, MockCanvas::DrawPathData{child_path1, child_paint1}},
201231
MockCanvas::DrawCall{2, MockCanvas::SaveData{3}},
202232
MockCanvas::DrawCall{3, MockCanvas::SetMatrixData{SkMatrix()}},
203233
MockCanvas::DrawCall{
204-
3, MockCanvas::SaveLayerData{child_path2.getBounds(),
234+
3, MockCanvas::SaveLayerData{mock_layer2_rounded_bounds,
205235
filter_paint2, nullptr, 4}},
206236
MockCanvas::DrawCall{
207237
4, MockCanvas::DrawPathData{child_path2, child_paint2}},

0 commit comments

Comments
 (0)