After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 772075 - GTK+ uses a lot more CPU under Wayland than under X11
GTK+ uses a lot more CPU under Wayland than under X11
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Wayland
3.21.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
: 774378 (view as bug list)
Depends on:
Blocks: WaylandRelated
 
 
Reported: 2016-09-27 18:00 UTC by Gustavo Noronha (kov)
Modified: 2016-11-16 16:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
css shadows: repeat a painted surface rather than masking (3.27 KB, patch)
2016-10-26 16:23 UTC, Gustavo Noronha (kov)
none Details | Review
cssshadowvalue: scale the blur surface by the same factor as the target (3.70 KB, patch)
2016-11-10 18:16 UTC, Gustavo Noronha (kov)
committed Details | Review

Description Gustavo Noronha (kov) 2016-09-27 18:00:12 UTC
When I run gtk3-demo --run=pixbufs on my Gnome on Wayland session I get around 86% CPU usage. If I run it with GDK_BACKEND=x11 it uses only around 25%.

Perf tells me the biggest offender is bits_image_fetch_bilinear_affine_normal_a8. Setting a breakpoint in gdb I noticed it is almost all due to gtk_window_draw drawing client-side decorations, particularly shadows.

Returning at the top of that function after just chaining up to the parent brings CPU usage down to ~42%. Still higher than under Xwayland, but much lower than the original 86%.

This is the biggest drag on the WebKitGTK+ performance at the moment, I believe. While playing a 4k video the browser spends most of its time painting the window decoration.
Comment 1 Carlos Garcia Campos 2016-09-28 07:26:10 UTC
I've tried the pixbuf demo and it works good enough for me in Wayland too, but only when not on hidpi, so it might be related to the hidpi code path.
Comment 2 Carlos Garcia Campos 2016-09-28 07:30:22 UTC
Forgot to say that I also tried hidpi in X11, and it worked good too, so it seems to be wayland + hidpi.
Comment 3 Gustavo Noronha (kov) 2016-10-26 16:23:45 UTC
Created attachment 338532 [details] [review]
css shadows: repeat a painted surface rather than masking

After further investigating, it seems like doing a repeat masking is much
slower than a repeat paint operation. Using an intermediate surface and
repeating it improves performance a lot - I can now resize terminal and
browser windows without hiccups, and the pixbufs demo runs much better.

I still see a lot of overhead caused by the mixing of GL and 2D cairo in some
test cases (such as https://webkit.org/blog-files/3d-transforms/poster-circle.html), but the overhead caused by painting shadows pretty much disappears from
my profiles (I'm testing mainly with gtk 3.20 on Fedora 24, but tried the patch
on master as well).
Comment 4 atomnuker 2016-11-05 03:07:40 UTC
I've patched my libgtk with that patch and I can confirm that it does significantly reduce CPU and speeds up the entire environment by a noticeable amount. Unfortunately, scrolling in gedit or gnome-terminal is still noticeably slower than under x11, but it's progress nevertheless.
Comment 5 Benjamin Otte (Company) 2016-11-08 16:33:11 UTC
I don't like the patch, because it's a workaround avoiding a slow codepath in pixman (or Cairo).
The current code is the ideal code you would write: correct, short and doesn't do anything stupid.

So I'd be a lot happier if somebody were to fix this upstream.
Comment 6 Gustavo Noronha (kov) 2016-11-08 17:05:28 UTC
By the way, I was discussing with Benjaming and the window shadows should probably not even be repainted unless the window size is changing or something like that. I reported bug 774114 for that one.
Comment 7 Gustavo Noronha (kov) 2016-11-10 11:33:31 UTC
I was talking to Pekka Paalanen about the pixman fast path and he was telling me:

1) good luck getting anything new into pixman
2) affine matrix + scaling, repeat/pad masking all make fast paths harder to find

I believe the problematic bit in question is scaling, since it is not a problem when not in hidpi, so we could take that out of the equation, but I'm not sure how - sounds like it would be a much more intrusive change. Pekka suggested that I try disabling bilinear filtering:

diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 35d3df7..6de2bf1 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -381,6 +381,7 @@ mask_surface_repeat (cairo_t         *cr,
 
     pattern = cairo_pattern_create_for_surface (surface);
     cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+    cairo_pattern_set_filter (pattern, CAIRO_FILTER_FAST);
 
     cairo_mask (cr, pattern);

That improves things quite a bit, but not as much as my patch does - resizing the main gtk3-demo window is still quite jerky, for instance.
Comment 8 Gustavo Noronha (kov) 2016-11-10 18:16:33 UTC
Created attachment 339535 [details] [review]
cssshadowvalue: scale the blur surface by the same factor as the target

Making sure the surfaces are using the same scale factor makes it more
likely a fast path will be used when pixman gets involved, as pointed
out by Benjamin Otte.
Comment 9 Benjamin Otte (Company) 2016-11-10 18:20:28 UTC
Comment on attachment 339535 [details] [review]
cssshadowvalue: scale the blur surface by the same factor as the target

+    cairo_pattern_set_filter (pattern, CAIRO_FILTER_FAST);

I suppose that's a leftover from the last patch?

With that line removed: Push it to master and 3.22!
Comment 10 Gustavo Noronha (kov) 2016-11-10 18:26:18 UTC
\o/ indeed it is a leftover from the test above. Thanks!
Comment 11 Gustavo Noronha (kov) 2016-11-10 18:58:21 UTC
Attachment 339535 [details] pushed as 942e904 - cssshadowvalue: scale the blur surface by the same factor as the target
Comment 12 Emmanuele Bassi (:ebassi) 2016-11-16 16:30:25 UTC
*** Bug 774378 has been marked as a duplicate of this bug. ***