backdrop-filter doesn't blur remote <browser> element
Categories
(Core :: Graphics: WebRender, defect, P2)
Tracking
()
People
(Reporter: userChrome.css, Assigned: cheff)
References
(Blocks 2 open bugs)
Details
Attachments
(4 files)
-
Using userChrome.css custom file before backdrop-filter was disabled, fixed and re-enabled (around ver. 95.0), you could set this CSS property for firefox UI elements, like:
-- absolute position bookmarks bar;
-- search breakout megabar;
-- tabs, etc. -
Attached pictures - shows you could use backdrop-filter for UI elements before.
Is that a bug or is there a reason it was disabled for UI elements after re-enabling it?
Comment 1•3 years ago
|
||
Checked with Glenn, and this definitely appears to be a regression.
| Reporter | ||
Comment 2•3 years ago
|
||
Just wanted to let you know that it still broken on Firefox v115/v117nightly.
One thing I noticed that blur rendering works in settings menu.
| Reporter | ||
Comment 3•3 years ago
|
||
Forgot to mention that flag "layout.css.backdrop-filter.enabled" is used.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 4•2 years ago
|
||
I was poking at some of these effects and found this issue.
Here's a patch that reproduces the issue:
diff --git a/browser/themes/shared/urlbar-searchbar.css b/browser/themes/shared/urlbar-searchbar.css
index b5684c5f6f4b9..a3ff1a8c2b3e4 100644
--- a/browser/themes/shared/urlbar-searchbar.css
+++ b/browser/themes/shared/urlbar-searchbar.css
@@ -242,6 +242,8 @@
}
#urlbar[breakout][breakout-extend] > #urlbar-background {
+ background-color: rgba(0, 0, 0, .3);
+ backdrop-filter: blur(10px);
animation-name: urlbar-grow;
animation-duration: 0s;
animation-timing-function: var(--animation-easing-function);
What is going on is that blurring remote tabs (like the new tab page) doesn't work. However blurring same-process tabs like about:config does work.
I thought this could be more general but http://crisal.io/tmp/backdrop-filter-iframe.html indicates this works for content... Glenn, do you know the difference here off-hand? Are top level tabs treated specially by webrender vs. cross-origin iframes? I would've expected them to be somewhat similar from WR's side.
Comment 5•2 years ago
|
||
They will look quite different from WR side (remote tabs get an iframe display item, local tabs get embedded in parent display list). Having said that, I'm not sure why that would make any difference to whether backdrop-filter works on it, so it will need investigation.
Comment 6•2 years ago
|
||
Right, but my point is that in the test-case above (http://crisal.io/tmp/backdrop-filter-iframe.html), I have a local iframe and a remote iframe, and those both work, right?
Comment 7•2 years ago
|
||
But yeah maybe there's something weird going on there on the top level display list or something.
| Reporter | ||
Comment 8•1 year ago
|
||
I found on reddit that adding clip-path to :root element makes backdrop-filter blur work again on #urlbar-background element.
:root { clip-path: inset(0 round 8px); }
| Assignee | ||
Comment 9•5 months ago
|
||
Any updates on this?
Comment 10•5 months ago
|
||
hey, so I looked into this because of Zen.
the backdrop-filter breaks when the content underneath it is in an OOP iframe. so the blur sees only the parent chrome background, ignoring the iframe's pixels.
cause:
in gfx/wr/webrender/src/scene_building.rs, the WebRender inserts a tile-cache barrier both before and after traversing a root (OOP) iframe. the post-iframe barrier splits chrome content into a separate tile-cache surface, and any subsequent backdrop-filter can't sample the iframe's pixels, since they're on a different surface.
fix:
remove the post-iframe barrier only (the pre-iframe barrier stays). this keeps chrome content in the same tile-cache slice as the iframe so backdrop-filter can reach across the boundary.
verified locally. [screenshot] (https://postimg.cc/xq82GbjJ) test with backdrop-filter:invert(1) inverts the OOP iframe's pixel colors. the clip-path workaround from Comment 8 (:root { clip-path: inset(0 round 8px) }) works because it forces a new tile cache slice that happens to include the iframe.
patch:
diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs
--- a/gfx/wr/webrender/src/scene_building.rs
+++ b/gfx/wr/webrender/src/scene_building.rs
@@ -1083,7 +1083,6 @@
if self.iframe_size.is_empty() {
assert!(self.root_iframe_clip.is_some());
self.root_iframe_clip = None;
- self.add_tile_cache_barrier_if_needed(SliceFlags::empty());
}
self.id_to_index_mapper_stack.pop().unwrap();
@@ -1335,8 +1334,10 @@
SpatialNodeUid::root_scroll_frame(iframe_pipeline_id, instance_id),
);
- // If this is a root iframe, force a new tile cache both before and after
- // adding primitives for this iframe.
+ // If this is a root iframe, force a new tile cache before adding
+ // primitives for this iframe. Keep the post-iframe content in the same
+ // tile cache so backdrop-filters in chrome/parent content can read back
+ // pixels from the visually preceding remote iframe surface.
if self.iframe_size.is_empty() {
assert!(self.root_iframe_clip.is_none());
self.root_iframe_clip = Some(ClipId::root(iframe_pipeline_id));
diff --git a/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe.yaml b/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe.yaml
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe.yaml
@@ -0,0 +1,19 @@
+# Verify that a backdrop-filter following a root iframe can sample the iframe's
+# rendered pixels.
+---
+root:
+ items:
+ - type: iframe
+ id: [1, 2]
+ bounds: [0, 0, 100, 100]
+ clip-rect: [0, 0, 100, 100]
+ - type: backdrop-filter
+ bounds: [0, 0, 100, 100]
+ filters: invert(1)
+
+pipelines:
+ - id: [1, 2]
+ items:
+ - type: rect
+ bounds: [0, 0, 100, 100]
+ color: red
diff --git a/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe-ref.yaml b/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe-ref.yaml
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/filters/backdrop-filter-root-iframe-ref.yaml
@@ -0,0 +1,6 @@
+---
+root:
+ items:
+ - type: rect
+ bounds: [0, 0, 100, 100]
+ color: cyan
diff --git a/gfx/wr/wrench/reftests/filters/reftest.list b/gfx/wr/wrench/reftests/filters/reftest.list
--- a/gfx/wr/wrench/reftests/filters/reftest.list
+++ b/gfx/wr/wrench/reftests/filters/reftest.list
@@ -64,6 +64,7 @@
skip_on(android,device) skip_on(win) fuzzy(1,104) fuzzy-if(platform(swgl),4,18484) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Pixel2
== svg-filter-flood.yaml svg-filter-flood-ref.yaml
== backdrop-filter-basic.yaml backdrop-filter-basic-ref.yaml
+== backdrop-filter-root-iframe.yaml backdrop-filter-root-iframe-ref.yaml
platform(linux,mac) == backdrop-filter-perspective.yaml backdrop-filter-perspective.png
== backdrop-filter-on-child-surface.yaml backdrop-filter-on-child-surface-ref.yaml
== backdrop-filter-clip-mask.yaml backdrop-filter-clip-mask-ref.yaml
Comment 11•5 months ago
|
||
But it is important for web content to be on its own cache slice for all sorts of things like scrolling performance, so doing that unconditionally is not a viable fix.
| Assignee | ||
Comment 12•5 months ago
|
||
What's not very clear to me is how it does work across iframes but not for browser elements
| Assignee | ||
Comment 13•16 days ago
|
||
| Assignee | ||
Comment 14•16 days ago
|
||
Updated•16 days ago
|
Updated•16 days ago
|
Updated•11 days ago
|
Description
•