Leak Hunting and Mutter Hacking

Greetings GNOMErs!

Last week, when I upgraded to GNOME 3.28, I was sad to notice an extremely annoying bug in Mutter/GNOME Shell: every once in a while, a micro-stuttering happened. This was in additions to another bug that was disappointing me for quite a while: the tiling/maximize/unmaximize animations were not working on Wayland too.

About the former, it may not look like the end of the world, but trust me when I say that a split-second delay every ~10s is the perceived difference of a butter smooth and a trashy experience.

Of course, this is free software, we are free people, and I have this habit of fixing up whatever is bothering me. Naturally, I decided to fix them. I decided to document my journey for people that want to try Mutter/GNOME Shell development be less scared.

Animations

I decided to start working on the animations, since there was a comment written by Jonas Ådahl to bug 780292 that was a leading clue to whatever the issue was. Time to open GNOME Builder, and clone Mutter.

Mutter + Wayland + (Mutter + Wayland + (App))

While testing these changes, I obviously needed to run Mutter and see what was happening. Since we’re talking about Wayland, I was specifically interested in seeing which messages were being sent by the application and which message Mutter was receiving.

To dump the Wayland calls made by an application, we can just use the WAYLAND_DEBUG env var, like this:

$ WAYLAND_DEBUG=1 <application>

This should dump a lot of information into the terminal. This might or might not be useful to you.

One obvious way to test changes in Mutter is to build and install Mutter system-wide, then reboot. Rebooting takes almost 5 minutes to me. Clearly not a good approach. But Mutter has a nested mode where it can run inside another Mutter session.

To run a nested Mutter Wayland session:

$ mutter –nested –wayland

If your changes are making Mutter crash, you might want to run it with GDB. But Mutter is built with Autotools, which of course makes every single thing more complicated than it should be. You’ll notice that src/mutter is not an executable, but a wrapper script. To run Mutter under GDB, do that:

$ libtool –mode=execute gdb mutter

(gdb opens)

> r –nested –wayland

This will open a window with your new raw Mutter session. To run any graphical application against this new nested Mutter, as long as the toolkit supports Wayland, run:

$ WAYLAND_DISPLAY=wayland-1 <application>

Inspecting Mutter and Wayland

This was the trickiest part to me. Mutter has some env vars to control debugging, but I could not use them properly. Either it would dump too much info, or nothing useful at all.

I then decided to go the dumb way and just add dozens of prints around the code.

If you’re aware of any better way to do that, please leave a comment!

The Issue

The root of the issue was in this function:

static void
zxdg_surface_v6_set_window_geometry (struct wl_client   *client,
                                     struct wl_resource *resource,
                                     int32_t             x,
                                     int32_t             y,
                                     int32_t             width,
                                     int32_t             height)
{
  MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);

  surface->pending->has_new_geometry = TRUE;
  surface->pending->new_geometry.x = x;
  surface->pending->new_geometry.y = y;
  surface->pending->new_geometry.width = width;
  surface->pending->new_geometry.height = height;
}

Can you spot the issue here?

Look again.

Notice that Mutter is accepting whatever the new geometry is. It doesn’t check if the new geometry differs from the current. When the geometry doesn’t change, we should not report anything to the compositor. If the compositor is GNOME Shell, things get even worse: we go through the JS trampoline, which is slow, when could have avoided it.

Apparently, GTK reports geometry changes even when they don’t happen, e.g. when hovering whatever area of the window. Every single one of these hundreds of geometry changes that didn’t actually change per second would go though IPC to Mutter, which will mindlessly jump into the compositor’s JS trampoline just to do… nothing. Because the geometry didn’t actually changed.

This was fixed by this commit.

Stuttering

The second point that was actually freaking me out was that Mutter was waking up my discrete GPU quite often. On a PRIME system, this means the GPU is put to sleep after a few seconds without being used. Every wakeup would produce an incredibly annoying stutter.

This was only happening on Wayland.

After further investigation, I came up with this temporary fix until Mutter becomes smarter about how it should handle GPUs. This one is already merged, and will be available on the next GNOME 3.28 release!

Memory Leak

Oh, dear, the infamous memory leak… I’ll just leave this link to the GitLab comment. Go figure.

Advertisements

Improved half tiling available in Mutter 3.26.1

A late night announcement: the improved tiling patches (shown in a previous blog post) were merged in Mutter and and GTK+3, and will be available in GNOME 3.26.1 / GTK 3.22.23 (not yet released; should be available this week).

I’d like to thank Florian Muellner, Matthias Clasen, Jonas Adahl and AlexGS for all their support, time, code reviews and testing.

Have a wonderful night!

Smarter half tiling in GNOME Shell/Mutter

Hello GNOMErs,

I think that, at this point, at least a good part of the community is aware of the many new features that are planned to arrive with GNOME 3.26.

I’m particularly looking forward a better tiling story in GNOME Shell and Mutter.

And, y’know, I’m not exactly a referrence in being passive about my own personal technological wishes. Heck, I love hacking stuff so much that it naturally happens even when I’m sleepless and under headache. Perhaps we can call that organic hacking? 🙂

Anyway, I can’t just sit down and keep waiting for something I could work on, right?

And that’s why this happened:

This is obviously a work in progress. You can track the progress of this smarter half tiling in bug 645153. But, sssshhh don’t tell anyone, this is actually part of the future quarter tiling feature!

Have a wonderful night! o/