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

Conversation

ferhatb
Copy link
Contributor

@ferhatb ferhatb commented Apr 15, 2020

  • Fixed physicalSize missing devicePixelRatio when sizing backdrop element.
  • Instead of covering physical size, backdrop filter now checks for ancestor clip if available.
  • Added golden test.

Fixes: flutter/flutter#54871
Fixes: flutter/flutter#55193

@ferhatb ferhatb requested a review from yjbanov April 15, 2020 20:41
@auto-assign auto-assign bot requested a review from jason-simmons April 15, 2020 20:43
String width = '${rect.width}px';
String height = '${rect.height}px';
while (parentSurface != null) {
html.HtmlElement parentElement = parentSurface.rootElement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The surface is placed in the DOM after it is updated. When the surface is moved to another parent, this will get a wrong DOM element.

To fix this you can schedule the update after the update, similar to how canvas painting is scheduled into the _paintQueue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think I know the proper place for the logic that figures out the nearest clip: recomputeTransformAndClip. It is invoked as part of the preroll to figure out clip changes even for addRetained. This way, the backdrop filter doesn't need to walk up the parent chain at all. Instead, it will be given nearest clip, so it can react appropriately when the clip changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Reading localClipRect from PersistedContainerSurface instead.

String height = '${rect.height}px';
while (parentSurface != null) {
html.HtmlElement parentElement = parentSurface.rootElement;
if (parentElement.tagName == 'flt-clip' || parentElement.tagName == 'FLT-CLIP') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on element tag name seems error-prone as we can have other clipping elements with different tag names. In fact, I think this already missed <flt-clippath>.

Instead, let's add a bool isClipping getter to PersistedContainerSurface that returns false by default. Clips can override it and return true instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -65,14 +65,41 @@ class PersistedBackdropFilter extends PersistedContainerSurface
_invertedTransform = Matrix4.inverted(_transform);
_previousTransform = _transform;
}
final ui.Rect rect = transformLTRB(_invertedTransform, 0, 0,
ui.window.physicalSize.width, ui.window.physicalSize.height);
// https://api.flutter.dev/flutter/widgets/BackdropFilter-class.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For performance reasons the apply() is not called when the surface is added using addRetained. You also need to override retain() to schedule this logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified update.

@@ -0,0 +1,106 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation is sensitive to the surface lifecycle. We should have tests that move the surface around (both as retained and as updated) and check that the style is applied correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test that moves clipRect.

Copy link
Contributor

@yjbanov yjbanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo the grandparent bug.

void _checkForUpdatedAncestorClipElement() {
// If parent clip element has moved, adjust bounds.
PersistedContainerSurface parentSurface = parent;
html.HtmlElement parentElement = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// If parent clip element has moved, adjust bounds.
PersistedContainerSurface parentSurface = parent;
html.HtmlElement parentElement = null;
while (parentSurface != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it will be an infinite loop unless the immediate parent is a clip. I think there should be parentSurface = parentSurface.parent somewhere inside the loop. Would also be good to add a test that checks that we can climb up the parent chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@ferhatb ferhatb merged commit 753514c into flutter:master Apr 21, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cupertino widgets blurred on https://flutter.github.io/gallery/#/ [web] BackdropFilter doesn't render correctly after Chrome 81 update.
3 participants