GNOME Bugzilla – Bug 772075
GTK+ uses a lot more CPU under Wayland than under X11
Last modified: 2016-11-16 16:30:25 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.
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.
Forgot to say that I also tried hidpi in X11, and it worked good too, so it seems to be wayland + hidpi.
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).
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.
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.
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.
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.
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 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!
\o/ indeed it is a leftover from the test above. Thanks!
Attachment 339535 [details] pushed as 942e904 - cssshadowvalue: scale the blur surface by the same factor as the target
*** Bug 774378 has been marked as a duplicate of this bug. ***