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

Commit 969e79d

Browse files
committed
Add Analyze()
1 parent d630d3b commit 969e79d

38 files changed

+592
-338
lines changed

flow/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ executable("flow_unittests") {
136136
"layers/color_filter_layer_unittests.cc",
137137
"layers/container_layer_unittests.cc",
138138
"layers/layer_tree_unittests.cc",
139-
"layers/layer_unittests.cc",
140139
"layers/opacity_layer_unittests.cc",
141140
"layers/performance_overlay_layer_unittests.cc",
142141
"layers/physical_shape_layer_unittests.cc",

flow/layers/backdrop_filter_layer.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77
namespace flutter {
88

99
BackdropFilterLayer::BackdropFilterLayer(sk_sp<SkImageFilter> filter)
10-
: filter_(std::move(filter)) {
11-
set_layer_reads_surface(filter_.get() != nullptr);
10+
: filter_(std::move(filter)) {}
11+
12+
Layer::AnalysisResult BackdropFilterLayer::Analyze() const {
13+
Layer::AnalysisResult result = ContainerLayer::Analyze();
14+
result.renders_to_save_layer = true;
15+
result.layer_reads_surface = (filter_.get() != nullptr);
16+
17+
return result;
1218
}
1319

1420
void BackdropFilterLayer::Paint(PaintContext& context) const {

flow/layers/backdrop_filter_layer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class BackdropFilterLayer : public ContainerLayer {
1515
public:
1616
BackdropFilterLayer(sk_sp<SkImageFilter> filter);
1717

18+
AnalysisResult Analyze() const override;
1819
void Paint(PaintContext& context) const override;
1920

2021
private:

flow/layers/backdrop_filter_layer_unittests.cc

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ TEST_F(BackdropFilterLayerTest, EmptyFilter) {
4949
auto layer = std::make_shared<BackdropFilterLayer>(nullptr);
5050
layer->Add(mock_layer);
5151

52+
auto analysis_result = layer->Analyze();
53+
EXPECT_FALSE(analysis_result.layer_reads_surface);
54+
EXPECT_TRUE(analysis_result.renders_to_save_layer);
55+
EXPECT_FALSE(analysis_result.child_reads_surface);
56+
EXPECT_FALSE(analysis_result.needs_screen_readback());
57+
5258
layer->Preroll(preroll_context(), initial_transform);
5359
EXPECT_EQ(layer->paint_bounds(), child_bounds);
5460
EXPECT_TRUE(layer->needs_painting());
@@ -75,6 +81,12 @@ TEST_F(BackdropFilterLayerTest, SimpleFilter) {
7581
auto layer = std::make_shared<BackdropFilterLayer>(layer_filter);
7682
layer->Add(mock_layer);
7783

84+
auto analysis_result = layer->Analyze();
85+
EXPECT_TRUE(analysis_result.layer_reads_surface);
86+
EXPECT_TRUE(analysis_result.renders_to_save_layer);
87+
EXPECT_FALSE(analysis_result.child_reads_surface);
88+
EXPECT_TRUE(analysis_result.needs_screen_readback());
89+
7890
layer->Preroll(preroll_context(), initial_transform);
7991
EXPECT_EQ(layer->paint_bounds(), child_bounds);
8092
EXPECT_TRUE(layer->needs_painting());
@@ -91,6 +103,33 @@ TEST_F(BackdropFilterLayerTest, SimpleFilter) {
91103
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
92104
}
93105

106+
TEST_F(BackdropFilterLayerTest, EmptyFilterButChildReadback) {
107+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
108+
const SkPath child_path = SkPath().addRect(child_bounds);
109+
const SkPaint child_paint = SkPaint(SkColors::kYellow);
110+
auto mock_layer = std::make_shared<MockLayer>(
111+
child_path, child_paint, true /* fake_layer_reads_surface */);
112+
auto layer = std::make_shared<BackdropFilterLayer>(nullptr);
113+
layer->Add(mock_layer);
114+
115+
auto analysis_result = layer->Analyze();
116+
EXPECT_FALSE(analysis_result.layer_reads_surface);
117+
EXPECT_TRUE(analysis_result.renders_to_save_layer);
118+
EXPECT_TRUE(analysis_result.child_reads_surface);
119+
EXPECT_FALSE(analysis_result.needs_screen_readback());
120+
121+
layer->Preroll(preroll_context(), SkMatrix());
122+
layer->Paint(paint_context());
123+
EXPECT_EQ(
124+
mock_canvas().draw_calls(),
125+
std::vector({MockCanvas::DrawCall{
126+
0, MockCanvas::SaveLayerData{child_bounds, SkPaint(),
127+
nullptr, 1}},
128+
MockCanvas::DrawCall{
129+
1, MockCanvas::DrawPathData{child_path, child_paint}},
130+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
131+
}
132+
94133
TEST_F(BackdropFilterLayerTest, MultipleChildren) {
95134
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 1.0f);
96135
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 2.5f, 3.5f);
@@ -100,12 +139,19 @@ TEST_F(BackdropFilterLayerTest, MultipleChildren) {
100139
const SkPaint child_paint1 = SkPaint(SkColors::kYellow);
101140
const SkPaint child_paint2 = SkPaint(SkColors::kCyan);
102141
auto layer_filter = SkImageFilters::Paint(SkPaint(SkColors::kMagenta));
103-
auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
142+
auto mock_layer1 = std::make_shared<MockLayer>(
143+
child_path1, child_paint1, true /* fake_layer_reads_surface */);
104144
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
105145
auto layer = std::make_shared<BackdropFilterLayer>(layer_filter);
106146
layer->Add(mock_layer1);
107147
layer->Add(mock_layer2);
108148

149+
auto analysis_result = layer->Analyze();
150+
EXPECT_TRUE(analysis_result.layer_reads_surface);
151+
EXPECT_TRUE(analysis_result.renders_to_save_layer);
152+
EXPECT_TRUE(analysis_result.child_reads_surface);
153+
EXPECT_TRUE(analysis_result.needs_screen_readback());
154+
109155
SkRect children_bounds = child_path1.getBounds();
110156
children_bounds.join(child_path2.getBounds());
111157
layer->Preroll(preroll_context(), initial_transform);
@@ -142,13 +188,25 @@ TEST_F(BackdropFilterLayerTest, Nested) {
142188
auto layer_filter1 = SkImageFilters::Paint(SkPaint(SkColors::kMagenta));
143189
auto layer_filter2 = SkImageFilters::Paint(SkPaint(SkColors::kDkGray));
144190
auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
145-
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
191+
auto mock_layer2 = std::make_shared<MockLayer>(
192+
child_path2, child_paint2, true /* fake_layer_reads_surface */);
146193
auto layer1 = std::make_shared<BackdropFilterLayer>(layer_filter1);
147194
auto layer2 = std::make_shared<BackdropFilterLayer>(layer_filter2);
148195
layer2->Add(mock_layer2);
149196
layer1->Add(mock_layer1);
150197
layer1->Add(layer2);
151198

199+
auto analysis_result1 = layer1->Analyze();
200+
EXPECT_TRUE(analysis_result1.layer_reads_surface);
201+
EXPECT_TRUE(analysis_result1.renders_to_save_layer);
202+
EXPECT_TRUE(analysis_result1.child_reads_surface);
203+
EXPECT_TRUE(analysis_result1.needs_screen_readback());
204+
auto analysis_result2 = layer2->Analyze();
205+
EXPECT_TRUE(analysis_result2.layer_reads_surface);
206+
EXPECT_TRUE(analysis_result2.renders_to_save_layer);
207+
EXPECT_TRUE(analysis_result2.child_reads_surface);
208+
EXPECT_TRUE(analysis_result2.needs_screen_readback());
209+
152210
SkRect children_bounds = child_path1.getBounds();
153211
children_bounds.join(child_path2.getBounds());
154212
layer1->Preroll(preroll_context(), initial_transform);

flow/layers/clip_path_layer.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ namespace flutter {
1515
ClipPathLayer::ClipPathLayer(const SkPath& clip_path, Clip clip_behavior)
1616
: clip_path_(clip_path), clip_behavior_(clip_behavior) {
1717
FML_DCHECK(clip_behavior != Clip::none);
18-
set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer);
18+
}
19+
20+
Layer::AnalysisResult ClipPathLayer::Analyze() const {
21+
Layer::AnalysisResult result = ContainerLayer::Analyze();
22+
result.renders_to_save_layer =
23+
(clip_behavior_ == Clip::antiAliasWithSaveLayer);
24+
25+
return result;
1926
}
2027

2128
void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {

flow/layers/clip_path_layer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class ClipPathLayer : public ContainerLayer {
1313
public:
1414
ClipPathLayer(const SkPath& clip_path, Clip clip_behavior = Clip::antiAlias);
1515

16+
AnalysisResult Analyze() const override;
1617
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
1718

1819
void Paint(PaintContext& context) const override;

flow/layers/clip_path_layer_unittests.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,47 @@ TEST_F(ClipPathLayerTest, PaintBeforePreroll) {
4444
"needs_painting\\(\\)");
4545
}
4646

47+
TEST_F(ClipPathLayerTest, ReadbackChild) {
48+
const SkPath path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f));
49+
auto readback_layer = std::make_shared<MockLayer>(
50+
SkPath(), SkPaint(), true /* fake_layer_reads_surface */);
51+
52+
{
53+
auto hardedge_layer = std::make_shared<ClipPathLayer>(path, Clip::hardEdge);
54+
hardedge_layer->Add(readback_layer);
55+
56+
auto hardedge_result = hardedge_layer->Analyze();
57+
EXPECT_FALSE(hardedge_result.layer_reads_surface);
58+
EXPECT_FALSE(hardedge_result.renders_to_save_layer);
59+
EXPECT_TRUE(hardedge_result.child_reads_surface);
60+
EXPECT_TRUE(hardedge_result.needs_screen_readback());
61+
}
62+
63+
{
64+
auto antialias_layer =
65+
std::make_shared<ClipPathLayer>(path, Clip::antiAlias);
66+
antialias_layer->Add(readback_layer);
67+
68+
auto antialias_result = antialias_layer->Analyze();
69+
EXPECT_FALSE(antialias_result.layer_reads_surface);
70+
EXPECT_FALSE(antialias_result.renders_to_save_layer);
71+
EXPECT_TRUE(antialias_result.child_reads_surface);
72+
EXPECT_TRUE(antialias_result.needs_screen_readback());
73+
}
74+
75+
{
76+
auto antialias_save_layer =
77+
std::make_shared<ClipPathLayer>(path, Clip::antiAliasWithSaveLayer);
78+
antialias_save_layer->Add(readback_layer);
79+
80+
auto antialias_save_result = antialias_save_layer->Analyze();
81+
EXPECT_FALSE(antialias_save_result.layer_reads_surface);
82+
EXPECT_TRUE(antialias_save_result.renders_to_save_layer);
83+
EXPECT_TRUE(antialias_save_result.child_reads_surface);
84+
EXPECT_FALSE(antialias_save_result.needs_screen_readback());
85+
}
86+
}
87+
4788
TEST_F(ClipPathLayerTest, CulledLayer) {
4889
const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f);
4990
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);

flow/layers/clip_rect_layer.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ namespace flutter {
99
ClipRectLayer::ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior)
1010
: clip_rect_(clip_rect), clip_behavior_(clip_behavior) {
1111
FML_DCHECK(clip_behavior != Clip::none);
12-
set_renders_to_save_layer(clip_behavior == Clip::antiAliasWithSaveLayer);
12+
}
13+
14+
Layer::AnalysisResult ClipRectLayer::Analyze() const {
15+
Layer::AnalysisResult result = ContainerLayer::Analyze();
16+
result.renders_to_save_layer =
17+
(clip_behavior_ == Clip::antiAliasWithSaveLayer);
18+
19+
return result;
1320
}
1421

1522
void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {

flow/layers/clip_rect_layer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class ClipRectLayer : public ContainerLayer {
1313
public:
1414
ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior);
1515

16+
AnalysisResult Analyze() const override;
1617
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
1718
void Paint(PaintContext& context) const override;
1819

flow/layers/clip_rect_layer_unittests.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,47 @@ TEST_F(ClipRectLayerTest, PaintBeforePreroll) {
4343
"needs_painting\\(\\)");
4444
}
4545

46+
TEST_F(ClipRectLayerTest, ReadbackChild) {
47+
const SkRect rect = SkRect::MakeWH(5.0f, 5.0f);
48+
auto readback_layer = std::make_shared<MockLayer>(
49+
SkPath(), SkPaint(), true /* fake_layer_reads_surface */);
50+
51+
{
52+
auto hardedge_layer = std::make_shared<ClipRectLayer>(rect, Clip::hardEdge);
53+
hardedge_layer->Add(readback_layer);
54+
55+
auto hardedge_result = hardedge_layer->Analyze();
56+
EXPECT_FALSE(hardedge_result.layer_reads_surface);
57+
EXPECT_FALSE(hardedge_result.renders_to_save_layer);
58+
EXPECT_TRUE(hardedge_result.child_reads_surface);
59+
EXPECT_TRUE(hardedge_result.needs_screen_readback());
60+
}
61+
62+
{
63+
auto antialias_layer =
64+
std::make_shared<ClipRectLayer>(rect, Clip::antiAlias);
65+
antialias_layer->Add(readback_layer);
66+
67+
auto antialias_result = antialias_layer->Analyze();
68+
EXPECT_FALSE(antialias_result.layer_reads_surface);
69+
EXPECT_FALSE(antialias_result.renders_to_save_layer);
70+
EXPECT_TRUE(antialias_result.child_reads_surface);
71+
EXPECT_TRUE(antialias_result.needs_screen_readback());
72+
}
73+
74+
{
75+
auto antialias_save_layer =
76+
std::make_shared<ClipRectLayer>(rect, Clip::antiAliasWithSaveLayer);
77+
antialias_save_layer->Add(readback_layer);
78+
79+
auto antialias_save_result = antialias_save_layer->Analyze();
80+
EXPECT_FALSE(antialias_save_result.layer_reads_surface);
81+
EXPECT_TRUE(antialias_save_result.renders_to_save_layer);
82+
EXPECT_TRUE(antialias_save_result.child_reads_surface);
83+
EXPECT_FALSE(antialias_save_result.needs_screen_readback());
84+
}
85+
}
86+
4687
TEST_F(ClipRectLayerTest, CulledLayer) {
4788
const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f);
4889
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);

0 commit comments

Comments
 (0)