Why don’t you just…

Relatively regularly I’m asked why I don’t “just” integrate QtCompositor or libweston and call it a day. Well it should be obvious, if it were as simple as “just” we would do that 😉 So instead of replying again and again I thought to give a full blog post explaining the options and why they don’t really suit our needs.

How KWin’s compositor works

Let’s start with a look at the Compositors in KWin:

  • No Compositing (X11 only)
  • XRender (X11 only)
  • QPainter (Wayland only)
  • OpenGL (ES) (X11 and Wayland)

The task of the compositors is to render the windows into a global scene. The information about the windows is taken from the window manager (e.g. the stacking order defines which window is rendered on top) and get transformed by the effect system.

The compositors use platform specific API to get the content of the window and to render it to the screen. E.g. OpenGL can use GLX and use texture from pixmap to map the content of an X11 window to an OpenGL texture and use an XWindow to create the OpenGL context on. The actual compositor which renders doesn’t care whether it’s an X11 Window or a Wayland window or whatever, all it cares about it’s a texture (OpenGL), a pixmap (XRender) or a QImage (QPainter). The platform specific API is abstracted allowing to make the actual compositors completely windowing system agnostic. Designed as a class diagram it looks (simplified) like this:

Now with that much abstraction one could think that there a huge differences between the code and that there is not much sharing going on. But the opposite is the case. The majority of the code is shared. To give an overview I provide the line count of all the files relevant to the OpenGL compositor.

  • Shared code: 3733 (cloc scene_opengl.* abstract_egl_backend.* scene.*)
  • Platforms specific: 1424 (cloc egl* glxbackend.*)

From the platform specific code the glxbackend is about 50 %. The sharing between the egl backends is larger, for the new X11 mode for kwin_wayland the difference is just 20 lines. For QPainter the differences are also rather small – in fact the differences are so small that all is in one source file making something like 200 lines of code for the three backends. Last week I worked on integrating a framebuffer backend into QPainter – although I prior had no idea about it, it was integrated into KWin in less than two hours fully functional with no change to the SceneQPainter at all except writing 50 lines of the backend code.

Now the backends are only part of the whole story. By using our own existing compositor we ensure a similar feature set between X11 and Wayland and can reuse all our effects directly without any adjustments. According to CLOC we have 22000 lines of effect code.

What about QtCompositor

QtCompositor seems to be the natural choice for bringing Wayland support to KWin. After all it’s part of Qt which is what we use in KWin. Except it doesn’t. For a starter it’s not yet a released component which makes it difficult to use for us to develop against, for our packagers to distribute and for our users to test. “But Martin”, you say, “you could develop on it and get it into a release state!”

Yes I could, but would it help KWin? What is the strength of QtCompositor? Providing a QtQuick API to write a Wayland compositor. But KWin doesn’t use QtQuick in the compositor. “But Martin”, you say, “QtQuick is the new cool thing, everybody ports to it, so should you!”. Yes, of course, but it means:

  • Throwing away all our effects
  • Writing new integration code between QtCompositor and the window manager
  • having no code sharing between the Wayland and the X11 compositor
  • No longer being able to provide non-OpenGL compositors as QtQuick requires OpenGL

If I look at this I rather doubt that this would be a “just integrate it”. That looks like a lot of work and duplication to have the same basic window manager for X11 and Wayland. Code sharing would be kind of impossible as the technologies involved are too different.

“But Martin”, you say, “you could at least use QtCompositor for wrapping the Wayland API and use it to map a Wayland buffer to OpenGL!” Yes, that is true and I did consider it and even planned to do so. In the end I decided against it for multiple reasons. First of all this still shows the problem of the unreleased component (yes, I could work on it), but then I wanted to integrate Wayland in KWin with a Facade. Using a facade is something I consider here as rather important. After all we want to use Wayland for quite some time and not run into the situation that we need to port away from a library in a few years. Using a facade makes such a situation much easier. Now if we write a facade anyway what is the benefit of being a facade to QtWayland compared to being a facade to Wayland directly? It just adds another layer of abstraction which might hinder us (and compared we ported lots away from Qt to XCB during the Qt 5 porting removing the abstraction added by Qt). Oh and of course we will have to use Wayland directly, because we will have to use our own protocols for e.g. interfacing with Plasma. Which would mean that we have to interact with two technologies instead of one. Overall I didn’t see an advantage and that’s why KWayland is a facade over Wayland and not over QtCompositor.

What about (lib)weston

“But Martin”, you say, “you could integrate (lib)weston’s backend!”. Yes, weston uses plugins for it’s backends, so in theory it would be possible to load the plugins and interface with them. There were also patches to make this possible through a libweston, but I actually don’t know whether they got integrated (quick check looks like they didn’t).

I would love to have a library which abstracts e.g. kms or framebuffer for me, but honestly I doubt weston is that. Weston was developed as the reference compositor and not as a library to do that. Weston code is always open in my editor, so I know a little bit about the code and can see that it is – well – Weston-specific. I doubt that the code base could be shared in it’s current state. It would need an effort like what has been done for libinput to move this into a well designed API. As long as that doesn’t happen weston’s backends are not directly useable for us.

And even if we would get back to a different feature set. We use QPainter for non-GL rendering, Weston uses pixman. And that is nested into the compositor implementations of Weston. Again: that needs lots of work to get in a state which would allow integration, so overall it’s not a “just use it”.

And all of that does not consider what is more difficult: integrating the C API or writing the code yourself tailored in a way which makes sense in a C++/Qt world.

KWinception

Last week I merged in a few important changes for the upcoming KWin 5.3 release. The rootless Xwayland support is integrated, which means we are a huge step closer to managing Wayland clients. Rendering, input and cursor is already using the Wayland code paths and will be shared with proper Wayland clients. I have already started working on code for that and have it working quite nicely already but decided to delay the integration for Plasma 5.4.

This means that kwin_wayland starts a Wayland server, but except Xwayland there is no application which can properly connect to it. Nevertheless it’s an important step and allows to also test the code in a better way.

In addition I worked on a better support for nesting compositors. So far one had to start Weston in order to test kwin_wayland. This is of course not optimal as it makes the development setup more difficult than it has to be. So last week I looked into developing a new backend which can use an X11 window to render to. This is comparable to Weston which can be used nested on X11. The backend is relatively straight forward: it can render to the created window using either the OpenGL or QPainter compositor, accepts input events and delegates them and passes the cursor from Wayland windows to the X11 window. The tricky part is that we cannot use any of our X11 specific libraries to create the window: we don’t use the xcb QPA, so no support from Qt and we cannot use KWindowSystem as it only allows one xcb_connection and that’s already needed for the Xwayland window manager. So I had to do things myself and as I consider this just a development feature it’s probably the worst X11 client in existance 😉 (Long term KWindowSystem should be changed to support multiple connections, would be very useful for unit tests).

The new backend triggered a small refactoring which makes it easier to implement further backends like e.g. a plain framebuffer or a drm/kms. As a small reminder: there’s an open GSoC idea for implementing the drm/kms backend and application period is to close soon.

Anyway with the nested KWin it’s now possible to create a kwin_wayland instance on the X Server using kwin_x11 and on the kwin_wayland one can create yet another kwin_wayland so that we have a KWinception:

Aus 2015-03-19

To start such a nested compositor use:

kwin_wayland --windowed --xwayland

Please watch the debug output for:

X-Server started on display :1

This tells the id of the created X Server (normally the next free id) and allows to start an application on the nested KWin:
DISPLAY=:1 kwrite

KWin_Wayland picks the windowing system depending on the environment variables which are defined. For DISPLAY it uses X11, for WAYLAND_DISPLAY it uses Wayland. If both are defined Wayland is preferred. If one wants to specify explicitly one can use the command line arguments –x11-display or –wayland-display. E.g.


kwin_wayland --windowed --xwayland --x11-display=:0

For X11 there are also the options –width and –height to specify an initial size (default is currently 1024×768). On Wayland these options are currently not available, the window always opens fullscreen.

Please remember that this is pretty new code and the support is still incomplete. Feature might be missing or broken. This is at the current state expected and because of that we do not yet accept bug reports. If you find a bug which you think should be fixed, please open an editor 😉