Skip to content

No shrinking for BackdropFilter's cull rect #29070

@liyuqian

Description

@liyuqian

Currently, it's easy to misunderstand how BackdropFilter works because its area of effect depends on Skia's cull rect. Skia views that cull rect only as a performance optimization hint so it can freely modify it to any rect that encloses the child. Therefore it's hard to predict the cull rect's exact size.

One example of such confusion is

BackdropFilter(
  child: Container(width: 200, height: 200, child: Text('Hello')),
  ...
);

Many expect the filter to be applied to the full container of size 200x200. Instead, Skia only sees a drawText call which has an small area of 'Hello', so it reduces the filter area to just around that 'Hello' text.

By fixing this this issue, Flutter will always set BackdropFilter's area of effect to fill its parent/ancestor clip (full screen if unclipped). This is more in line with our clip behaviors (no clip by default), but it doesn't directly achieve a 200x200 filtered area using the code above.

In order to get the filtered area of 200x200 when this issue is fixed, one has to write the following code

ClipRect(
  child: BackdropFilter(
    child: Container(width: 200, height: 200, child: Text('Hello')),
  )
);

If this breaks your app, wrap the BackdropFilter with a ClipRect (or some other clip of your choice).

Related issues: #10148 (BackdropFilter only shrinks when there's a child text widget), #16148 (BackdropFilter doesn't match the size of of its child).

To fully fix this issue, we have a 3-step plan to accommodate our golden tests infrastructure.

  1. Land No shrinking for BackdropFilter's cull rect #28174 with the transparent paint hack to change the behavior with pure framework (flutter/flutter) changes.
  2. Modify BackdropFilterLayer in flutter/engine to send a nullptr bounds (instead of paint_bounds) to SaveLayerRec in https://github.com/flutter/engine/blob/master/flow/layers/backdrop_filter_layer.cc#L19
  3. Wait for the engine change to roll into the framework; then remove the transparent paint hack.

Such plan ensures that our engine roll won't be blocked by a golden image mismatch.

Metadata

Metadata

Assignees

Labels

c: API breakBackwards-incompatible API changes

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions