Window transparency doesn't work with gpu process disabled (which causes issues when mica is enabled and the gpu process dies repeatedly)
Categories
(Core :: Graphics, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox-esr128 | --- | unaffected |
firefox134 | --- | wontfix |
firefox135 | --- | fix-optional |
firefox136 | --- | verified |
People
(Reporter: mayankleoboy1, Assigned: emilio)
References
(Blocks 1 open bug, Regression)
Details
(Keywords: regression)
Attachments
(6 files)
48.82 KB,
text/plain
|
Details | |
5.87 MB,
video/mp4
|
Details | |
6.03 KB,
patch
|
Details | Diff | Splinter Review | |
1.70 KB,
patch
|
Details | Diff | Splinter Review | |
834 bytes,
patch
|
Details | Diff | Splinter Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
- Create new firefox profile
- set widget.windows.mica = true
- restart firefox and go to https://en.wikipedia.org/wiki/Barack_Obama
- in a new window, open about:support
- Make both the windows as foreground
- Click on "terminate gpu process" once. The obama page will go black. Click inside the page to restore it.
- Now repeatedly and rapidly start clicking on "terminate gpu process"
- If you dont repro, restart from step 3 and repeat step6 2-3 times.
AR: After maybe 30 clicks, the browser UI will stop responding to mouse clicks.
ER: not so.
Reporter | ||
Comment 1•19 days ago
|
||
Reporter | ||
Comment 2•19 days ago
|
||
Reporter | ||
Updated•19 days ago
|
Reporter | ||
Updated•19 days ago
|
Reporter | ||
Comment 3•19 days ago
|
||
I cant get a log as all UI elements in the the about:logging tab (including the "capture the profile") get blank during the STR.
Comment 4•19 days ago
|
||
Set release status flags based on info from the regressing bug 1764822
Updated•19 days ago
|
Reporter | ||
Comment 5•19 days ago
|
||
May be easier to repro if you force enable software-wr by setting gfx.webrender.software=TRUE, restarting browser, and then going to town on the "trigger gpu reset" button.
Assignee | ||
Comment 6•19 days ago
|
||
I mean, if I hammer that button I can also get full browser crashes like:
[Parent 25312, Compositor] WARNING: Invalid to register the same layer tree twice: file D:/moz/gecko/gfx/layers/ipc/CompositorBridgeParent.cpp:891
[25312] Hit MOZ_CRASH(Use IPC_FAIL only in an unrecoverable, unexpected state: RecvNotifyChildRecreated
even with Mica disabled... So I'm a bit skeptic this is mica-specific. That said this is a debug assert
Sotaro, do you know how to best debug this?
Assignee | ||
Comment 7•19 days ago
|
||
Another assert, also with mica disabled:
[18680] Assertion failure: state.mApzcTreeManagerParent == parent, at D:/moz/gecko/gfx/layers/ipc/ContentCompositorBridgeParent.cpp:99
I'm pretty sure this is not mica-specific at this point, though it might be easier to hit? Not sure.
Reporter | ||
Comment 8•19 days ago
|
||
FWIW, without being mica-specific, its easy to get errors in gfx-critical notes in about:support by hammering that button. But that doesnt necessarily make the UI unusable. This bug is specific about the UI going blank and/or not responding.
I didnt get any crash with that button though, and i was trying really hard to get it to crash or hang :)
Updated•19 days ago
|
Comment 9•16 days ago
|
||
With the log, it seemed that the problem seemed to happen since Firefox fallbacked to no gpu process with software webrender.
Comment 10•16 days ago
•
|
||
With the following pref, Firefox window did not updated. mica might not work without gpu process
- pref widget.windows.mica = true
- pref layers.gpu-process.enabled = false
Assignee | ||
Comment 11•16 days ago
|
||
Hmm, I see... The only difference mica introduces is window transparency and this bit to add the backdrop.
I'm not on windows right now, but does the same happen with only layers.gpu-process.enabled = false
and something like:
diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css
index f49604e537807..e261339684efe 100644
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -25,6 +25,10 @@
}
}
+:root[customtitlebar] {
+ background-color: transparent;
+}
+
@media (-moz-windows-accent-color-in-titlebar) or (-moz-windows-mica) {
:root[customtitlebar] {
@media (-moz-windows-mica) {
Comment 12•16 days ago
•
|
||
Yeah, confirmed Comment 11 caused the rendering problem.
Updated•16 days ago
|
Assignee | ||
Updated•16 days ago
|
Assignee | ||
Updated•16 days ago
|
Assignee | ||
Comment 13•14 days ago
|
||
So AIUI, this is because we're using the transparency code in InProcessWinCompositorWidget
, which draws to a memory DC, but we're not using the memory DC thing in here, because we're not using the fallback renderer (I think?).
But avoiding the whole memory DC stuff and drawing directly to the window DC seems to work just fine (tried early-returning in InProcessWinCompositorWindow::UpdateTransparency
). Chris, you seem the most familiar with this, do you have the context for what the InProcessWinCompositorWidget
is trying to do with transparency?
Comment 14•14 days ago
|
||
With the following prefs, save window rendering to png files. With the patch, rendering to window seemed to work as expected.
- pref gfx.webrender.software = true
- gfx.webrender.software.d3d11 = false
- layers.gpu-process.enabled = false
Comment 15•14 days ago
|
||
Change Change TransparencyModeIs() as to TransparencyMode::Transparent check return false.
With the change, I see UI rendering.
Comment 16•14 days ago
•
|
||
Even when gpu process is enabled, the following pref change caused the problem.
- pref gfx.webrender.dcomp-win.enabled = false
The change disables DirectComposition usage. And RenderCompositorANGLE does swap chain present to windows. And the problem happened with mica. When RenderCompositorANGLE::ShouldUseAlpha() returned false, ui was rendered as expected.
By the way, with the following pref change, WebRender does swap chain present with DirectComposition. In this case, UI was rendered as expected.
- pref gfx.webrender.compositor = false
Comment 17•13 days ago
•
|
||
Chris, you seem the most familiar with this, do you have the context for what the InProcessWinCompositorWidget is trying to do with transparency?
Hey Emilio,
It's possible that we've completely changed the way this works by now, but it used to be that when we are drawing with the GDI and we need alpha blending we would create the window as a Layered Window by adding the WS_EX_LAYERED
window style to it.
When you do that, you stop receiving WM_PAINT
messages and you're expected to render to an in-memory DC and call UpdateLayeredWindow to actually define the window pixels.
It's possible that it might incidentally work to draw directly to the DC of a layered window, but AFAIK the behavior is unspecified by Microsoft and not guaranteed to work.
I believe that the use-cases for these transparent windows have really decreased over the years -- They may not be used for anything anymore! They used to be used for rendering XUL Panel controls, for example. This was the cause of Bug 1604412 all those years ago, where the Hamburger Menu disappeared when the GPU sandbox was enabled due to it using XULPanel.
If the backend that's being used to draw the window no longer uses the StartRemoteDrawing()
and EndRemoteDrawing()
calls, it's possible that this window doesn't need to be transparent (in the sense of being a layered window). It would be interesting to see if things work if you simply set the window to TransparencyMode::Opaque
.
EDIT: nsMenuPopupFrame seems to be the code we have that still uses window transparency, and it looks like it is only used by the SWGL backend.
Assignee | ||
Comment 18•13 days ago
|
||
Ah, yeah, so... For toplevel transparent windows (e.g. if you enable widget.windows.mica=true, but also if you use something like comment 11) we no longer use WS_EX_LAYERED (see the IsPopup()
here). That seems to work for DCOMP, see bug 1911763 and company.
Assignee | ||
Comment 19•13 days ago
|
||
We do have existing transparent windows that don't rely on these tho, like the nonnative notifications (alerts.useSystemBackend=false
).
Comment 20•13 days ago
|
||
So then... Does that mean that the problem is that you're using the SWGL backend but without the WS_EX_LAYERED
style? If so, that would mean that UpdateLayeredWindow
(which the SWGL backend uses) wouldn't do anything. It would also explain why you're saying that it works fine if you just render directly with the window DC.
Comment 21•13 days ago
•
|
||
We do have existing transparent windows that don't rely on these tho, like the nonnative notifications (alerts.useSystemBackend=false).
I wonder if we accomplish that using Direct2D? IIUC with a lot of the newer GFX apis, there's really no need for this "layered window" stuff anymore, and a window can support transparency directly via its swapchain. TBH I'm not really sure in what circumstances we still fall back to the SWGL path.
Comment 22•13 days ago
•
|
||
So, it looks like overall the issue is that this patch created a mismatch between WinCompositorWidget::mTransparencyMode
and WS_EX_LAYERED
. Previously, all the code in InProcessWinCompositorWidget
assumed that mTransparencyMode == TransparencyMode::Transparent
always implied WS_EX_LAYERED
. But now, that's not true for anything but WindowType::Popup
.
That patch (correctly) fixed the code in RemoteBackbuffer.cpp
to ignore mTransparencyMode
and only consider whether or not the window is layered or not. I think the fix would be to have InProcessWinCompositorWidget
basically do the same thing.
As I'm saying this, I'm actually realizing that there's probably not any point anymore to even passing mTransparencyMode
to the CompositorWidgetDelegate
anymore -- Unless I'm missing something, it serves no purpose other than to act as a proxy for layering (which - as you know - can just be determined using GetWindowLongPtr()
).
If you don't think you'll have time to work on this soon, I can make a patch for it?
Assignee | ||
Comment 23•13 days ago
|
||
Updated•13 days ago
|
Assignee | ||
Comment 24•13 days ago
|
||
(In reply to Chris Martin [:cmartin] from comment #20)
So then... Does that mean that the problem is that you're using the SWGL backend but without the
WS_EX_LAYERED
style? If so, that would mean thatUpdateLayeredWindow
(which the SWGL backend uses) wouldn't do anything. It would also explain why you're saying that it works fine if you just render directly with the window DC.
Yeah that is correct. Indeed, if I go to https://www.bennish.net/web-notifications.html with gfx.webrender.dcomp-win.enabled=false
and alerts.useSystemBackend=false
the window doesn't show at all.
I wonder if we accomplish that using Direct2D? IIUC with a lot of the newer GFX apis, there's really no need for this "layered window" stuff anymore, and a window can support transparency directly via its swapchain. TBH I'm not really sure in what circumstances we still fall back to the SWGL path.
RenderCompositorANGLE
does add an alpha swapchain. I figured out some of the bits here, I think, see above.
Comment 25•12 days ago
|
||
Comment 26•12 days ago
|
||
bugherder |
Updated•7 days ago
|
Comment 27•2 days ago
|
||
I've reproduced this issue by opening and reloading the site https://en.wikipedia.org/wiki/Barack_Obama for a couple of times. The prefs widget.windows.mica
and layers.gpu-process.enabled
were set to false on Win 11 on an affected Nightly build (2025-01-23).
The issue is verified as fixed on the latest Beta 136.0b3 build, under Win 11.
Description
•