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

Commit ca329dd

Browse files
authored
[Impeller] Turn off Aiks bounds tracking for filtered SaveLayers. (#49076)
We use this bounds rect for querying the DisplayList rtree when culling. But when sub-DisplayLists are being dispatched, the DisplayList's rtree is local and doesn't incorporate parent layer filters. So sub-DisplayLists are getting culled as if no filters are being applied. Technically our local bounds tracking in Aiks is actually correct here, but this is a quick fix to alleviate the problem. I don't know what the best longterm solution for this is.
1 parent 3223485 commit ca329dd

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

impeller/aiks/canvas.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,14 @@ void Canvas::SaveLayer(const Paint& paint,
681681
TRACE_EVENT0("flutter", "Canvas::saveLayer");
682682
Save(true, paint.blend_mode, backdrop_filter);
683683

684+
// The DisplayList bounds/rtree doesn't account for filters applied to parent
685+
// layers, and so sub-DisplayLists are getting culled as if no filters are
686+
// applied.
687+
// See also: https://github.com/flutter/flutter/issues/139294
688+
if (paint.image_filter) {
689+
transform_stack_.back().cull_rect = std::nullopt;
690+
}
691+
684692
auto& new_layer_pass = GetCurrentPass();
685693
new_layer_pass.SetBoundsLimit(bounds);
686694

impeller/aiks/canvas_unittests.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "flutter/testing/testing.h"
66
#include "impeller/aiks/canvas.h"
7+
#include "impeller/aiks/image_filter.h"
78
#include "impeller/geometry/path_builder.h"
89

910
// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
@@ -336,6 +337,23 @@ TEST(AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect) {
336337
ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
337338
}
338339

340+
TEST(AiksCanvasTest, DisableLocalBoundsRectForFilteredSaveLayers) {
341+
Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
342+
343+
Canvas canvas(initial_cull);
344+
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
345+
346+
canvas.Save();
347+
canvas.SaveLayer(
348+
Paint{.image_filter = ImageFilter::MakeBlur(
349+
Sigma(10), Sigma(10), FilterContents::BlurStyle::kNormal,
350+
Entity::TileMode::kDecal)});
351+
ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
352+
353+
canvas.Restore();
354+
ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
355+
}
356+
339357
} // namespace testing
340358
} // namespace impeller
341359

0 commit comments

Comments
 (0)