Closed Bug 1685263 Opened 4 years ago Closed 4 years ago

[wayland] Firefox flickers in KDE Plasma

Categories

(Core :: Widget: Gtk, defect, P2)

Firefox 86
defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: zzag, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(8 files)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0

Steps to reproduce:

Firefox with the Basic renderer flickers a lot when it's running in KDE Plasma Wayland session. The main reason why it seems to do so is because committed shared memory client buffers are incomplete, which is a strict violation of the protocol.

Actual results:

Shared memory client buffers are incomplete.

Expected results:

Shared memory client buffers are complete.

Summary: Firefox commits incomplete shared memory client buffers → [wayland] Firefox commits incomplete shared memory client buffers

What do you mean by "incomplete"? AFAK dirty rectangles are used to mark areas which should be repainted.

Blocks: wayland
Priority: -- → P2
Flags: needinfo?(vlad.zahorodnii)

Is that a recent regression or can you reproduce that with all Firefox versions?

At the moment, it looks like some of the attached buffers are only partially drawn. This is what I mean by "incomplete". The first and the third screenshot should look same as the second one. The damage region only acts as a hint, the compositor may choose to ignore it altogether.

Flags: needinfo?(vlad.zahorodnii)

I can reproduce it with older version of Firefox as well. It's an old bug.

Note that this bug can't be reproduced if hardware acceleration is enabled.

(In reply to Vlad Zahorodnii [:zzag] from comment #6)

At the moment, it looks like some of the attached buffers are only partially drawn. This is what I mean by "incomplete". The first and the third screenshot should look same as the second one. The damage region only acts as a hint, the compositor may choose to ignore it altogether.

I see, Thanks. And can you check if the damage region is correct, i.e. the damage region matches drawn parts of the buffer?

btw: according the doc the areas outside damage area needs to be ignored by compositor, see:

https://wayland.freedesktop.org/docs/html/apa.html

wl_surface::damage_buffer - mark part of the surface damaged using buffer coordinates

This request is used to describe the regions where the pending buffer is different from the current surface contents, and where the surface therefore needs to be repainted. The compositor ignores the parts of the damage that fall outside of the surface.

AFAIK KDE/Plasma is the only compositor I know that has this issue.

Ahh, sorry, looks like I misread the statement :D So you're right, it looks optional.

And can you check if the damage region is correct, i.e. the damage region matches drawn parts of the buffer? And can you check if the damage region is correct, i.e. the damage region matches drawn parts of the buffer?

The damaged region seems okay, but the problem is that if several buffers are committed within a single vblank interval, all but the last buffer will be released and the damaged regions will be accumulated, i.e.

  • commit buffer a, damage a
  • commit buffer b, damage b
  • commit buffer c, damage c
  • composite

When the compositor redraws the screen, "damage a", "damage b", and "damage c" will be combined to determine what area must be re-drawn. Since buffer c is incomplete or contains outdated contents in some areas, Firefox will be flickering.

I see. May that be an issue with frame callback then? Firefox draws content in frame callback handlers only (unless it's a first paint). We also expect to get only one frame callback per vblank interval.

I've just double-checked and Firefox commits only once per vblank interval, except at first paint as you mentioned. This is where Firefox might start flickering (assuming that the last committed buffer is incomplete).

Another odd thing that I've just found is that sometimes one of the surfaces starts oscillating between a size of 1x1 and the expected size. This also contributes to the flickering issue. The oscillation doesn't seem to be caused by kwin as Firefox receives no configure events after xdg_toplevel has been initialized.

I've attached the WAYLAND_DEBUG output of Firefox when this issue occurs. Pay attention to wl_buffer@61 and wl_buffer@76.

Summary: [wayland] Firefox commits incomplete shared memory client buffers → [wayland] Firefox flickers in KDE Plasma

I see. So do you think the flickering is caused by the first paint and then partial update in frame callback? AFAIK wayland compositors tend to fire frame callbacks right after vblank to give client as much time as possible. Does Kwin behave the same? I think the compositor behavior should be:

-> first commit (without frame callback), Firefox registers frame callback
-> vblank
-> compositor fires frame callback, firefox paints
-> vblank

I think client does not have any ability to check if the commit is the last one or not.

(In reply to Vlad Zahorodnii [:zzag] from comment #15)

I've attached the WAYLAND_DEBUG output of Firefox when this issue occurs. Pay attention to wl_buffer@61 and wl_buffer@76.

That's interesting. Can you run Firefox with:

WAYLAND_DEBUG=1 MOZ_LOG="WidgetWayland:5, Widget:5"

env variables?

It should reveal why the surface is created so small and where it belongs, the log contains surface ID too.

KWin is not different from other wayland compositors in this regard. It sends out frame callbacks after re-drawing the screen.

Thanks for the log, I'll look at it. The 2x2 buffer (1x1 actually without the scale) looks incorrect and I don't understand why it's created.

Not sure if it's related to the flickering issue...

In case Firefox doesn't flicker (it happens from times to times), it looks as if the sub-surface with tabs and the web page is clipped. I checked it and buffers that are attached to the sub-surface are not large enough to match the outlines of the client-side drop shadow. The main surface is resized as expected though. This can be seen only with the Basic renderer.

The 1x1 window is Bug 1685537 but should not be related as the window is not painted.

(In reply to Vlad Zahorodnii [:zzag] from comment #21)

Created attachment 9195728 [details]
Screenshot_20210106_220439.png

Not sure if it's related to the flickering issue...

In case Firefox doesn't flicker (it happens from times to times), it looks as if the sub-surface with tabs and the web page is clipped. I checked it and buffers that are attached to the sub-surface are not large enough to match the outlines of the client-side drop shadow. The main surface is resized as expected though. This can be seen only with the Basic renderer.

It looks like Bug 1454156 (and Bug 1489463) when we fail to resize Firefox window after start. It's caused by async nature of Gtk events and Firefox sync window API.

Vlad, is there any updated KWin version with Wayland fixes? I have kwin-5.20.5-1.fc33.x86_64.

I tested simple scenario when Firefox is launched in normal size and then maximized and there are massive rendering artifacts after resize although wayland log looks sane.

Flags: needinfo?(vlad.zahorodnii)

When I have the updated KWin compositor I can implement wl_buffer dump to basic compositor for better debugging (I used that before).

Hi Vlad, I added wl_buffer dumps to Wayland SW backend so you can see buffer contents and compare that with log. It's implemented by Bug 1686341. To get wl_buffer content and related logging run Firefox (when Bug 1686341 lands) as:

MOZ_ENABLE_WAYLAND=1 WAYLAND_DEBUG=1 MOZ_LOG="WidgetWayland:5" MOZ_WAYLAND_DUMP_WL_BUFFERS=1 ./firefox

the buffers are stored as .png images in current working dir and you may be interested to see buffer content when it's comited. See the wayland log if you want to match buffer content (a png file) with a wayland state.

Usually, git master contains the latest Wayland fixes. This means however that you would need to build kwin from source code https://community.kde.org/Get_Involved/development

Regarding the artifacts during resize, we are aware of this issue. If a sub-surface sticks outside the main subsurface, it won't be clipped. At the moment, kwin handles that case poorly, we hope to change that with the scene redesign. On the other hand, it might be also a Firefox issue as well. If a window is being resized, its contents shouldn't bounce. For what it's worth, Qt applications suffer from a similar issue. Either way, it sounds like an unrelated issue and I should probably file another bug report. :D

I will definitely use the shared memory client buffer dumper for the debugging purposes. :-)

Flags: needinfo?(vlad.zahorodnii)

Okay, Thanks. If you have a clear&small reproducer where Firefox is flickering on KDE/Plasma let me please know, I'll look at it.
For instance when worked on Gnome I used a scenario when video clip is played in a tab and a popup (hamburger menu or urlbar) is displayed over it to see if the buffers are painted correctly by Firefox.

With Firefox 84, it's enough to set gfx.webrender.all to false to get flickering going on. With firefox built from source code, it seems like you need to resize it a couple of times to get flickering going on.

There's another set of fixes which can fix the flickering (Bug 1686703).

Vlad, right now we use the damage region to mark updated areas while parts outside the damaged region can be invalid. If KWin does not support that and always needs fully up-to-date wl_buffer submitted I can do that hack for Kwin only.

At the moment, kwin only updates parts of the texture that have been marked as dirty/damaged by the client. However, there are cases when kwin may decide to fully reload the texture.

I can do that hack for Kwin only.

Do you know if it is going to incur noticeable performance penalties?

(In reply to Vlad Zahorodnii [:zzag] from comment #31)

Do you know if it is going to incur noticeable performance penalties?

I'm not sure if noticeable, when small part of the screen is updated and a wl_buffer from last drawing is not available, Firefox would need to create a new wl_buffer and copy all data from the last one and then do the new painting. So it depends on screen size and how fast the compositor releases used buffers.

Vlad,

I just inspected Wayland basic renderer code and we use direct wl_buffer rendering for large screen updates only (i.e. more than half of the screen is updated), see:

https://searchfox.org/mozilla-central/rev/4dac9993b609fccc87e82682614faf2a44cda306/widget/gtk/WindowSurfaceWayland.cpp#807

But if you go to about:config and set 'widget.wayland-smooth-rendering' to true the intermediate buffer will be always used unless whole screen is repainted.

Blocks: wayland-kde
No longer blocks: wayland

I'm running Fedora Rawhide right now, and I was receiving issues with flickering. I run integrated Intel Graphics if that's related.
Installing: libglvnd-gles has at least for now made what looked like a rave of the screen turn to a stable usable Firefox.

My test case which I used:

  1. Open Firefox
  2. Go to youtube and play a video
  3. Maximize and minimize the window

Before: Flickering as mentioned everywhere, switching tabs.
After: No Flicker.

I think Vlad is right that the current Firefox behaviour is violating the Wayland protocol - and that we should change that eventually, even though that comes with a serious performance penalty.

The good news is that there's a alternative coming up that maybe allows us to essentially mirror internal Mutter behaviour - gfx.webrender.software.opengl combines software rendering with GL buffer management (bug 1673342). As we can pretty much assume GL to be available on Wayland, we'll hopefully need shm-buffers only as a last resort.

Guys, do you still see this issue with latest Nightly?
Thanks.

Flags: needinfo?(vlad.zahorodnii)

(In reply to Martin Stránský [:stransky] (ni? me) from comment #37)

Guys, do you still see this issue with latest Nightly?

How can one force the Basic renderer? At the moment, Firefox falls back to WebRender (Software), or is it intentional?

(In reply to Vlad Zahorodnii [:zzag] from comment #38)

(In reply to Martin Stránský [:stransky] (ni? me) from comment #37)

Guys, do you still see this issue with latest Nightly?

How can one force the Basic renderer? At the moment, Firefox falls back to WebRender (Software), or is it intentional?

gfx.webrender.force-disabled at about:config should do it for you. SW-WR default in Nightly only AFAIK.

Firefox doesn't seem to flicker when it's running with gfx.webrender.force-disabled.

Flags: needinfo?(vlad.zahorodnii)

(In reply to Martin Stránský [:stransky] (ni? me) from comment #39)

gfx.webrender.force-disabled at about:config should do it for you. SW-WR default in Nightly only AFAIK.

FYI in bug 1709038 I reported that when running under Fedora 34's kwin_wayland, Thunderbird 78.8.1's [Join Chat] dialog sometimes flickers, showing the window underneath. clokep pointed me to your suggestion and after I set gfx.webrender.force-disabled to true (with all other webrender settings at their default) and restarted Thunderbird, I couldn't reproduce the flickering.

(In reply to skierpage from comment #41)

(In reply to Martin Stránský [:stransky] (ni? me) from comment #39)

gfx.webrender.force-disabled at about:config should do it for you. SW-WR default in Nightly only AFAIK.

FYI in bug 1709038 I reported that when running under Fedora 34's kwin_wayland, Thunderbird 78.8.1's [Join Chat] dialog sometimes flickers, showing the window underneath. clokep pointed me to your suggestion and after I set gfx.webrender.force-disabled to true (with all other webrender settings at their default) and restarted Thunderbird, I couldn't reproduce the flickering.

Thunderbird 78 is not supposed to run under wayland. First "wayland ready" version may be 91.

Okay, let's close it now.

Btw. I tested KDE/Wayland on Fedora 34 and the Wayland compositor and overall UI responsibility is MUCH better than Gnome/Mutter - it's very fast. Good work!

Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: