Announcing the XFree KWin project

Over the last weeks I concentrated my work on KWin on what I call the XFree KWin project. The idea is to be able to start KWin/Wayland without XWayland support. While most of the changes required for it are already in Plasma 5.11, not everything got ready in time, but now everything is under review on phabricator, so it’s a good point in time to talk about this project.

Why an XFree KWin?

You might wonder why we spend time on getting KWin to run without X11 support. After all we need to provide support for XWayland anyway to be able to support legacy applications which are not yet on Wayland. So what’s the advantage if in a normal session one needs XWayland anyway?

One aspect is that it shows that our porting efforts to Wayland are finished. Over the last years I tried to start KWin without XWayland support for a few times just to find areas which are not yet ported. By being able to run KWin without X11 support we know that everything is ported or at least does not hard depend on X11 any more.

Another aspect is obviously Plasma Mobile which does not really require XWayland and also XWayland not making much sense on e.g. the libhybris enabled systems as Xwayland doesn’t have OpenGL there. By not requiring XWayland we can reduce our runtime and memory costs.

Speaking of runtime costs: not requiring X11 means that we don’t have to wait for XWayland during KWin startup. Instead XWayland can be started in parallel. This means KWin and the complete Plasma session starts a little bit faster.

And most important this is an important prerequisite to be able to handle a crashing XWayland. So far when XWayland crashed KWin terminated gracefully as KWin depends on X11. The hope is that when XWayland crashes we can just restart it and keep the session running.

How it was done

The general idea behind getting KWin X11 free is “code that isn’t loaded, cannot interfere”. KWin uses platform plugins (not Qt QPA plugins) for the various platforms KWin can run on. There is also a platform plugin for KWin/X11, so code which is only required in the KWin/X11 case can be moved into the platform plugin. As KWin/Wayland does not load this plugin we are certain that the code will not be loaded and thus cannot interfere.

But how to find code which is only required on KWin/X11? After all KWin’s code base is about 150 kSloc (according to cloc) and that makes it rather difficult. A good help here was our CI system which performs code coverage. KWin’s tests mostly are mostly based on KWin/Wayland so an area which does not have any test coverage is a good candidate for being X11 specific. By looking at these areas it was possible to find patterns which also helped to find more usages. A good help is KWin’s internal X11 API such as displayWidth, displayHeight, rootWindow and connection. The usage of these functions is partially so few that one could just evaluate each usage. As a result of this work the functions displayWidth and displayHeight are not used at all any more.

Plugin based compositors

Another idea was to get our compositors into plugins. Especially the XRender based compositor is not of much use in a Wayland world and thus should not be loaded into the binary. Unfortunately various parts of KWin called directly into the concrete compositor implementations, so to solve this we had to extend the internal API. In Plasma 5.11 the XRender and QPainter compositor are now loaded as plugins, so on Wayland the not-compatible XRender compositor is no longer loaded into memory and on X11 the not-compatible QPainter compositor is no longer loaded into memory. But also on Wayland the QPainter compositor is only loaded into memory if it is going to be used.

The OpenGL compositor is still always loaded in Plasma 5.11, but the change to have it as a plugin is already prepared and will be merged into master soonish. This will bring great advantages to the stability of the system: currently we are not able to define which platform supports which compositor as the initialization code just didn’t support being more flexible. But now with the plugin based approach I’m very confident that we can make this work in a better way.

Outlook

Being able to start and run KWin/Wayland without X11 support is of course only the start. More changes will be required. For example to delay loading XWayland until an application tries to connect to it (c.f. Weston). This would not make much sense in the start of Plasma yet as we still have applications in our startup which require X11 (e.g. ksmserver).

Another area is to try to get KWin compile without X11 support and to move everything required for Xwayland into a plugin. This will be a larger project as it will require to move much code around and to add further abstractions in some areas of KWin. Hint: this could be a nice Google Summer of Code project. As a fast step for especially Plasma Mobile and the Purism Librem phone an ifdef around every X11 code area could be a solution.

But my personal main goal is to be able to handle a crashing XWayland. This will also be an interesting task as the X11 code in KWin also depends on other libraries (e.g. KWindowSystem) which do not expect to outlive the X server. So that will be a challenging task to find all areas where KWin holds X11 data structures and to clean them up properly without crashing due to some cleanup code calling into xcb.

Rootless Xwayland server integration into KWin

Over the last weeks I concentrated my KWin related work on trying to integrate the Xwayland server properly. Xwayland is an interesting step on the way to Wayland as it maps X11 windows to Wayland surfaces. But it also needs an X11 window manager to manage the X11 windows. Overall it allows us to start integrating Wayland into the compositor without too much breakage. It’s still X11 after all, so our existing code base continues to work. And gruadually functionality can be replaced with the Wayland equivalent, so that we can afterwards start integrating proper Wayland clients.

Integrating Xwayland showed interesting challenges. KWin as an X11 window manager requires a running X server prior to start. It also can only communicate with one X server, the code base has many hard constraints on being only one X server. This means if we want to use Xwayland the Xwayland server must be the one KWin uses. Which means Xwayland must be started prior to KWin’s X11 usage. So far KWin also enforced the usage of the “xcb” QPA plugin, the windowing system abstraction plugin for the X world in Qt. This plugin gets loaded directly at application startup and aborts if there is no X server it can connect to.

As you can see KWin needs to ensure that Xwayland is running prior to the application startup. But Xwayland requires a running Wayland server, which is supposed to be provided by KWin and for processing Wayland events we need a running event loop, which is only present after the application started. Looks like we are caught in a dependency loop:
circular-dependencies

After some hacking and experimenting I found a solution which can start the Wayland server and Xwayland prior to the application startup, but it’s considerable fragile and it can only be a temporary solution. In the long run it would of course be better if KWin could use the Wayland QPA plugin provided by QtWayland to connect to it’s own Wayland server and start Xwayland later-on.

Nevertheless I succeeded in getting KWin connect to the Xwayland server and to start transitioning X clients to be rendered using Wayland buffers instead of performing texture from X11 pixmap:

Aus 2015-02-11

But it just hit another problem: it didn’t support accelerated OpenGL rendering on the X server. That’s quite a problem if no X11 client connected to the Xwayland server can use proper OpenGL and it’s even a problem for KWin as KWin uses QtQuick scenes which use the X server. So KWin itself fails to render accelerated UI. Compositing is not affected as we don’t use Qt for that.

The reason for the problem is that Xwayland expects the Wayland “wl_drm” interface to be present. This interface gets created when binding an EGLDisplay to a Wayland display. In case of KWin the EGLDisplay exists after the Compositor is fully initialized. And again we are in a dependency chain: the Compositor gets created and uses the Workspace class. This class controls the complete startup of the X11 window manager which means it’s highly X11 dependent and requires Xwayland to be present. Again we are in a dependency loop.

Breaking up this dependency loop is quite tricky. The Compositor is too deeply nested into the application to be considered started before creating the QApplication. This means we must be able to create the QApplication before we have an X Server running. This means no usage of xcb QPA plugin. As KWin is going to start a Wayland server anyway, it would be good to get KWin to use the wayland QPA plugin.

This was again quite a challenge. The QtWayland QPA plugin performs blocking roundtrips to the Wayland server in the main thread during startup. But the Wayland server is running in the same thread. So a blocking call to the Wayland server dead locks the server. It’s not possible to move the Wayland server at that point into a thread as one cannot start a QThread prior to having the QCoreApplication created.

The solution I developed for this problem involves creating an own event dispatcher prior to creating the QApplication. So we have the event dispatching for the Wayland server ready to use. Just the event loop is not yet running. This allowed to provide a small patch for QtWayland to run any event dispatcher set before creating the QApplication. A test application in the kwayland repository is also adjusted to make use of it (the test application is also able to start an Xwayland server prior to creating the QApplication).

Unfortunately there is still another issue: QtWayland might call eglInitialize in the main thread which again performs a blocking wayland call. This is a problem I haven’t solved yet and currently just hacked around by disabling OpenGL in Qt (which breaks the QtQuick views).

Being able to use the Wayland QPA just creates a new bunch of problems for KWin. KWin still needs to use X11 and thus needs to create an xcb connection. Just that this wouldn’t help much. KWin on X11 doesn’t init the xcb connection, it’s the xcb plugin in Qt which does it and we only access it via QX11Info. Thus KWin needs to be moved away from the usage. Luckily in many cases we already wrapped the functionality as going through the QPA interface (which QX11Info does internally) is too expensive for our use cases. So the changes are not that invasive. But KWin also uses frameworks like KF5WindowSystem which use QX11Info. Even more those frameworks were properly fixed to perform platform checks and don’t do the X11 specific code if it’s not on platform xcb. But it’s providing important X11 window manager functionality for KWin. For some classes like KWindowInfo and KWindowSystem the fix was trivial: don’t use in KWin. There’s also the more low-level NETRootInfo and NETWinInfo and that’s what KWin should use – usage of the KWindowInfo or KWindowSystem inside KWin can be considered a bug. For some other classes it was already partially possible to be used without the xcb plugin on X11. The classes are only used if we compile with xcb present, so it was possible to add more xcb specific methods which can then be used by KWin even if we do not use platform xcb. The required changes will be part of frameworks 5.8 release.

To summary where we are now: we can start kwin_wayland on platform wayland connecting to a Wayland server started by kwin_wayland, we do not require QX11Info in (most of) KF5WindowSystem and KWin. We are a good step closer to the aim, but still not there. The dependency loop is still in place: Workspace starts the Compositor, the Compositor creates the EGLDisplay which is needed to start Xwayland, which provides X11 which is needed for starting the Workspace.

This means: reorder the startup. We need to be able to start the Compositor prior to the Workspace (which could be interesting for kwin_x11, too, as it could improve persumed startup time). This task was easier than expected. Workspace got split into many modules over the last years and most modules which need to be created prior to creating the Compositor do not depend on Workspace and do not depend on X11. In the few cases where it actually does depend on X11 it was not difficult to delay the X11 specific code till after the X11 connection is created.

With all that in place I was able to delay starting Xwayland to after the Compositor is created and Xwayland can provide OpenGL to the connected clients:

This screenshot shows kwin_wayland running on top of Weston connected to an Xwayland server supporting proper OpenGL as can be seen by the output of glxinfo (in the konsole) and glxgears. Also plasmoidviewer just works on top of this X stack.

Of course there is still some work to be done till this is production ready code, but it looks really promising and I hope to have this ready for the KWin 5.3 release. The aim is also to get more and more features changed to use the Wayland functionality instead of the X11 functionality. E.g. for damage event handling it already uses the damage event of a wl_surface instead of creating an X11 damage handle. This makes supporting Wayland clients easier afterwards.