The wayland project II

The last post I laid out the story of me with wayland. Technology is fascinating isn't it? Every once a while, there are plenty of new projects that aim to start an revolution, getting people excited. Projects like systemd, Wayland, Vulkan make us think how come we did not think of those before, they seemed perfect at the moment. Technologies always work like a rush of hot wave, our sights are limited at the moment we are in, maybe 5 years from now, even vulkan is not sexy anymore. For ten years, community has been urging everyone to jump on the boat of wayland. Some major platform adopted it, just there is no money in it. Major platforms like GNOME and KDE are not even mature yet, KDE developers also worries about the future of the wayland, will it last 30 years like X window?

One of the truth that almost nobody talks about is that we all try to advertize the vague new technology as easy-to-learn, benifits and ignore all the learning curves. Is it really so? How many simple ideas out there that can rock the world? I cannot judge, in the context of wayland project. I cannot really use the word facile. The knowledge required for a wayland compositor is far more than what presented in DWM. Wayland is merely a IPC protocol library, all the work such as mapping hardware to logic devices, rendering and compositing has to done by a compositor writer. Even with the library libweston, programmers are still exposed by all those concepts. If you step on the path to do it all yourself, you will need quite a massive knowledge under the belt, I'd say. But let's not discourage everyone. Let's talk about all the goodies of wayland tech, especially the libweston could offer.

The input

The first thing that I started with the libweston is actually learning xkbcommon(xkbcommon itself has the concepts like keymap, modifier, keysym and so on). I was trying to implement a complex keyboard mapping, supporting sequence keybindings. It works a bit like what is available in emacs, only I have to hack around the libweston's flat keyboard handler. After registering the keybinding callbacks, compositor will route the key events to the clients when they are in focus.

Another idea exposed is the seat, it is presented in the wayland core protocol as well. Unix system has this concept called seat. A seat is a set of input device like keyboard, mice or controller, it means adding a seat for a user to user, how to discouver and group input devices into seats is transparent in the libweston, what programmer has is a signal handler. once a new seat discovered, compositor can setup the keymap and other things.

The view and surface

The view and the surface are the core concept in the weston composition. Basically weston_surface contains the buffer, but weston_view determines where you will show the surface on the screen. In the current weston architecture, at every frame, weston will build up a list of views and render them on top of each other. You can play all kinds of tricks with view, like rotations and scaling.

weston_output and weston_layer

The next concepts is the layer, this is idea when you want to futher seperate compositing into layers of cake. For example, on the top of your layers, you would have your cursor, then you may have some ui elements. futher downwards, you may have your regular windows section, then at the bottom, there is the wallpaper. If your GPU supports multiple planes, you can take the advantage of it to composite only certain layers and leaves the rest unchange, your wouldn't want to redraw everything just for the small motion of cursor, right :p?

What about weston_output? Output is the monitor, but technically it is a view of your entire framebuffer. If you have two monitors side-by-side, one output (monitor) occupies a chunk of that framebuffer. In this design, we only need to composite one framebuffer, and you can move the windows from one monitor to another at ease.

Other wayland concepts

Wayland object is not easy to work with, first challenge is double buffer state. Manage the state is quite lines of code actually. Many other objects like registry and wl_global or wl_seat are easier and usually done with a common routine (I guess that is why you would want Qt/GTK instead of barebone wayland client).

But The most confusing concept I've had is the wl_surface_frame. By reading the wayland docs. Firstly I thought it was compulsory to do a buffer swap, once you have your frame callback, you can do a rendering and commit. But if you really do that, you would not be able to draw anything since frame only issues after the commit. So you need to do a wl_surface_frame, then commit, then why do you need the wl_callback later? Just to delete it? This was how I drive my wayland client for a long period. In turned out wl_frame is only useful for the animations, but even though, you still need to have a first commit to drive the next frame. If you are work with typical GUI element where you only need to redraw at input events. The frame callback is totally unecessary. I only realized it after reading through the libweston rendering pipeline.

So if you need to work on a wayland client, there are some traps like this. Designing UIs under wayland is really far from easy, I would maybe write another article about that part of the story.

So after all, is it all good

In the end, I have to say this. With help of libweston, the implemention of a compositor is indeed much easier, it setup the drm and gbm, and implements most of the core protocols like wl_surface wl_buffer on the sever side. What it offers the compositor designer is a feature-rich apis to manipulate wayland object, you can do almost everything you want. Only if you have a strong grasp of all the concepts, so you can avoid all the traps that I as in. And libweston has absolutely no documentation at all.

READ THE CODE! and go through a hell of debugging, you will get there in a year or two.