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

Commit ad9e4fe

Browse files
author
Jonah Williams
authored
[Impeller] add mechanism for sharing bdf inputs. (#55701)
Introduces a mechanism to allow backdrop filters to 1) share backdrop inputs and 2) fuse filter applications for faster blurs. This is a proposed solution to flutter/flutter#131568 Implemented: * Developer can specify a "backdrop id" which indicates that a backdrop layer should share the input texture and potentially cached filter for a layer. * Removes second save layer for each backdrop filter * Removes save layer trace event for backdrop filter * Can fuse backdrop filters if there is more than one identical filter TBD: * Adjust heruristic to avoid applying bdf filter to entire screen Suggestions: applying a bdf should be a distinct operation from a save layer in the DL builder/dispatcher. The saveLayer implmenentation in the impeller dispatcher is super convoluted because it needs to handle both. ### Video Video starts with normal bdf then I hot reload to specify that the bdfs share inputs/filters. This is running on a pixel 8 pro Change to the macrobenchmark app is just: ```dart Widget build(BuildContext context) { Widget addBlur(Widget child, bool shouldBlur) { if (shouldBlur) { return ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), backdropId: 1, // Added ID child: child, ), ); } else { return child; } } ``` https://github.com/user-attachments/assets/22707f97-5825-43f1-91b4-1a02a43437f5 Requires framework changes in https://github.com/jonahwilliams/flutter/pull/new/backdrop_id
1 parent 76d310e commit ad9e4fe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+612
-255
lines changed

display_list/benchmarking/dl_complexity_gl.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ unsigned int DisplayListGLComplexityCalculator::GLHelper::BatchedComplexity() {
5151
void DisplayListGLComplexityCalculator::GLHelper::saveLayer(
5252
const DlRect& bounds,
5353
const SaveLayerOptions options,
54-
const DlImageFilter* backdrop) {
54+
const DlImageFilter* backdrop,
55+
std::optional<int64_t> backdrop_id) {
5556
if (IsComplex()) {
5657
return;
5758
}
@@ -627,7 +628,8 @@ void DisplayListGLComplexityCalculator::GLHelper::drawDisplayList(
627628
GLHelper helper(Ceiling() - CurrentComplexityScore());
628629
if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
629630
auto bounds = display_list->GetBounds();
630-
helper.saveLayer(bounds, SaveLayerOptions::kWithAttributes, nullptr);
631+
helper.saveLayer(bounds, SaveLayerOptions::kWithAttributes, nullptr,
632+
/*backdrop_id=*/-1);
631633
}
632634
display_list->Dispatch(helper);
633635
AccumulateComplexity(helper.ComplexityScore());

display_list/benchmarking/dl_complexity_gl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class DisplayListGLComplexityCalculator
3737

3838
void saveLayer(const DlRect& bounds,
3939
const SaveLayerOptions options,
40-
const DlImageFilter* backdrop) override;
40+
const DlImageFilter* backdrop,
41+
std::optional<int64_t> backdrop_id) override;
4142

4243
void drawLine(const DlPoint& p0, const DlPoint& p1) override;
4344
void drawDashedLine(const DlPoint& p0,

display_list/benchmarking/dl_complexity_metal.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ DisplayListMetalComplexityCalculator::MetalHelper::BatchedComplexity() {
6565
void DisplayListMetalComplexityCalculator::MetalHelper::saveLayer(
6666
const DlRect& bounds,
6767
const SaveLayerOptions options,
68-
const DlImageFilter* backdrop) {
68+
const DlImageFilter* backdrop,
69+
std::optional<int64_t> backdrop_id) {
6970
if (IsComplex()) {
7071
return;
7172
}
@@ -571,7 +572,8 @@ void DisplayListMetalComplexityCalculator::MetalHelper::drawDisplayList(
571572
MetalHelper helper(Ceiling() - CurrentComplexityScore());
572573
if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
573574
auto bounds = display_list->GetBounds();
574-
helper.saveLayer(bounds, SaveLayerOptions::kWithAttributes, nullptr);
575+
helper.saveLayer(bounds, SaveLayerOptions::kWithAttributes, nullptr,
576+
/*backdrop_id=*/-1);
575577
}
576578
display_list->Dispatch(helper);
577579
AccumulateComplexity(helper.ComplexityScore());

display_list/benchmarking/dl_complexity_metal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class DisplayListMetalComplexityCalculator
3737

3838
void saveLayer(const DlRect& bounds,
3939
const SaveLayerOptions options,
40-
const DlImageFilter* backdrop) override;
40+
const DlImageFilter* backdrop,
41+
std::optional<int64_t> backdrop_id) override;
4142

4243
void drawLine(const DlPoint& p0, const DlPoint& p1) override;
4344
void drawDashedLine(const DlPoint& p0,

display_list/display_list_unittests.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,15 +1483,17 @@ class SaveLayerExpector : public virtual DlOpReceiver,
14831483

14841484
void saveLayer(const DlRect& bounds,
14851485
const SaveLayerOptions options,
1486-
const DlImageFilter* backdrop) override {
1486+
const DlImageFilter* backdrop,
1487+
std::optional<int64_t> backdrop_id) override {
14871488
FML_UNREACHABLE();
14881489
}
14891490

14901491
virtual void saveLayer(const DlRect& bounds,
14911492
const SaveLayerOptions& options,
14921493
uint32_t total_content_depth,
14931494
DlBlendMode max_content_blend_mode,
1494-
const DlImageFilter* backdrop = nullptr) {
1495+
const DlImageFilter* backdrop = nullptr,
1496+
std::optional<int64_t> backdrop_id = std::nullopt) {
14951497
ASSERT_LT(save_layer_count_, expected_.size()) << label();
14961498
auto expect = expected_[save_layer_count_];
14971499
if (expect.options.has_value()) {
@@ -3666,7 +3668,8 @@ class SaveLayerBoundsExpector : public virtual DlOpReceiver,
36663668

36673669
void saveLayer(const DlRect& bounds,
36683670
const SaveLayerOptions options,
3669-
const DlImageFilter* backdrop) override {
3671+
const DlImageFilter* backdrop,
3672+
std::optional<int64_t> backdrop_id) override {
36703673
ASSERT_LT(save_layer_count_, expected_.size());
36713674
auto expected = expected_[save_layer_count_];
36723675
EXPECT_EQ(options.bounds_from_caller(),
@@ -4131,7 +4134,8 @@ class DepthExpector : public virtual DlOpReceiver,
41314134

41324135
void saveLayer(const DlRect& bounds,
41334136
SaveLayerOptions options,
4134-
const DlImageFilter* backdrop) override {
4137+
const DlImageFilter* backdrop,
4138+
std::optional<int64_t> backdrop_id) override {
41354139
// This method should not be called since we override the variant with
41364140
// the total_content_depth parameter.
41374141
FAIL() << "saveLayer(no depth parameter) method should not be called";
@@ -4141,7 +4145,8 @@ class DepthExpector : public virtual DlOpReceiver,
41414145
const SaveLayerOptions& options,
41424146
uint32_t total_content_depth,
41434147
DlBlendMode max_content_mode,
4144-
const DlImageFilter* backdrop) override {
4148+
const DlImageFilter* backdrop,
4149+
std::optional<int64_t> backdrop_id) override {
41454150
ASSERT_LT(index_, depth_expectations_.size());
41464151
EXPECT_EQ(depth_expectations_[index_], total_content_depth)
41474152
<< "at index " << index_;

display_list/dl_builder.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ void DisplayListBuilder::Save() {
409409

410410
void DisplayListBuilder::saveLayer(const DlRect& bounds,
411411
const SaveLayerOptions in_options,
412-
const DlImageFilter* backdrop) {
412+
const DlImageFilter* backdrop,
413+
std::optional<int64_t> backdrop_id) {
413414
SaveLayerOptions options = in_options.without_optimizations();
414415
DisplayListAttributeFlags flags = options.renders_with_attributes()
415416
? kSaveLayerWithPaintFlags
@@ -524,7 +525,8 @@ void DisplayListBuilder::saveLayer(const DlRect& bounds,
524525
}
525526

526527
if (backdrop) {
527-
Push<SaveLayerBackdropOp>(0, options, record_bounds, backdrop);
528+
Push<SaveLayerBackdropOp>(0, options, record_bounds, backdrop,
529+
backdrop_id);
528530
} else {
529531
Push<SaveLayerOp>(0, options, record_bounds);
530532
}
@@ -542,7 +544,8 @@ void DisplayListBuilder::saveLayer(const DlRect& bounds,
542544
}
543545
void DisplayListBuilder::SaveLayer(std::optional<const DlRect>& bounds,
544546
const DlPaint* paint,
545-
const DlImageFilter* backdrop) {
547+
const DlImageFilter* backdrop,
548+
std::optional<int64_t> backdrop_id) {
546549
SaveLayerOptions options;
547550
DlRect temp_bounds;
548551
if (bounds.has_value()) {
@@ -556,7 +559,7 @@ void DisplayListBuilder::SaveLayer(std::optional<const DlRect>& bounds,
556559
SetAttributesFromPaint(*paint,
557560
DisplayListOpFlags::kSaveLayerWithPaintFlags);
558561
}
559-
saveLayer(temp_bounds, options, backdrop);
562+
saveLayer(temp_bounds, options, backdrop, backdrop_id);
560563
}
561564

562565
void DisplayListBuilder::Restore() {

display_list/dl_builder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
5454
// |DlCanvas|
5555
void SaveLayer(std::optional<const DlRect>& bounds,
5656
const DlPaint* paint = nullptr,
57-
const DlImageFilter* backdrop = nullptr) override;
57+
const DlImageFilter* backdrop = nullptr,
58+
std::optional<int64_t> backdrop_id = std::nullopt) override;
5859
// |DlCanvas|
5960
void Restore() override;
6061
// |DlCanvas|
@@ -354,7 +355,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
354355
// |DlOpReceiver|
355356
void saveLayer(const DlRect& bounds,
356357
const SaveLayerOptions options,
357-
const DlImageFilter* backdrop) override;
358+
const DlImageFilter* backdrop,
359+
std::optional<int64_t> backdrop_id) override;
358360
// |DlOpReceiver|
359361
void restore() override { Restore(); }
360362

display_list/dl_canvas.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class DlCanvas {
6262
virtual void Save() = 0;
6363
virtual void SaveLayer(std::optional<const DlRect>& bounds,
6464
const DlPaint* paint = nullptr,
65-
const DlImageFilter* backdrop = nullptr) = 0;
65+
const DlImageFilter* backdrop = nullptr,
66+
std::optional<int64_t> backdrop_id = std::nullopt) = 0;
6667
virtual void Restore() = 0;
6768
virtual int GetSaveCount() const = 0;
6869
virtual void RestoreToCount(int restore_count) = 0;
@@ -233,9 +234,10 @@ class DlCanvas {
233234

234235
void SaveLayer(const SkRect* bounds,
235236
const DlPaint* paint = nullptr,
236-
const DlImageFilter* backdrop = nullptr) {
237+
const DlImageFilter* backdrop = nullptr,
238+
std::optional<int64_t> backdrop_id = std::nullopt) {
237239
auto optional_bounds = ToOptDlRect(bounds);
238-
SaveLayer(optional_bounds, paint, backdrop);
240+
SaveLayer(optional_bounds, paint, backdrop, backdrop_id);
239241
}
240242

241243
void Transform(const SkMatrix* matrix) {

display_list/dl_op_receiver.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include "flutter/display_list/effects/dl_mask_filter.h"
1818
#include "flutter/display_list/image/dl_image.h"
1919

20-
#include "flutter/impeller/geometry/path.h"
21-
2220
namespace flutter {
2321

2422
class DisplayList;
@@ -143,15 +141,17 @@ class DlOpReceiver {
143141
// layer before further rendering happens.
144142
virtual void saveLayer(const DlRect& bounds,
145143
const SaveLayerOptions options,
146-
const DlImageFilter* backdrop = nullptr) = 0;
144+
const DlImageFilter* backdrop = nullptr,
145+
std::optional<int64_t> backdrop_id = std::nullopt) = 0;
147146
// Optional variant of saveLayer() that passes the total depth count of
148147
// all rendering operations that occur until the next restore() call.
149148
virtual void saveLayer(const DlRect& bounds,
150149
const SaveLayerOptions& options,
151150
uint32_t total_content_depth,
152151
DlBlendMode max_content_blend_mode,
153-
const DlImageFilter* backdrop = nullptr) {
154-
saveLayer(bounds, options, backdrop);
152+
const DlImageFilter* backdrop = nullptr,
153+
std::optional<int64_t> backdrop_id = std::nullopt) {
154+
saveLayer(bounds, options, backdrop, backdrop_id);
155155
}
156156
virtual void restore() = 0;
157157

@@ -170,13 +170,17 @@ class DlOpReceiver {
170170
// public DisplayListBuilder/DlCanvas public interfaces where possible,
171171
// as tracked in:
172172
// https://github.com/flutter/flutter/issues/144070
173-
virtual void saveLayer(const DlRect* bounds,
174-
const SaveLayerOptions options,
175-
const DlImageFilter* backdrop = nullptr) final {
173+
virtual void saveLayer(
174+
const DlRect* bounds,
175+
const SaveLayerOptions options,
176+
const DlImageFilter* backdrop = nullptr,
177+
std::optional<int64_t> backdrop_id = std::nullopt) final {
176178
if (bounds) {
177-
saveLayer(*bounds, options.with_bounds_from_caller(), backdrop);
179+
saveLayer(*bounds, options.with_bounds_from_caller(), backdrop,
180+
backdrop_id);
178181
} else {
179-
saveLayer(DlRect(), options.without_bounds_from_caller(), backdrop);
182+
saveLayer(DlRect(), options.without_bounds_from_caller(), backdrop,
183+
backdrop_id);
180184
}
181185
}
182186
// ---------------------------------------------------------------------

display_list/dl_op_records.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,19 +310,24 @@ struct SaveLayerBackdropOp final : SaveLayerOpBase {
310310

311311
SaveLayerBackdropOp(const SaveLayerOptions& options,
312312
const DlRect& rect,
313-
const DlImageFilter* backdrop)
314-
: SaveLayerOpBase(options, rect), backdrop(backdrop->shared()) {}
313+
const DlImageFilter* backdrop,
314+
std::optional<int64_t> backdrop_id)
315+
: SaveLayerOpBase(options, rect),
316+
backdrop(backdrop->shared()),
317+
backdrop_id_(backdrop_id) {}
315318

316319
const std::shared_ptr<DlImageFilter> backdrop;
320+
std::optional<int64_t> backdrop_id_;
317321

318322
void dispatch(DlOpReceiver& receiver) const {
319323
receiver.saveLayer(rect, options, total_content_depth, max_blend_mode,
320-
backdrop.get());
324+
backdrop.get(), backdrop_id_);
321325
}
322326

323327
DisplayListCompare equals(const SaveLayerBackdropOp* other) const {
324328
return (options == other->options && rect == other->rect &&
325-
Equals(backdrop, other->backdrop))
329+
Equals(backdrop, other->backdrop) &&
330+
backdrop_id_ == other->backdrop_id_)
326331
? DisplayListCompare::kEqual
327332
: DisplayListCompare::kNotEqual;
328333
}

0 commit comments

Comments
 (0)