Wayland Support
Google Summer of Code 2017 Work Product Submission
Student: Philipp Kerling
Motivation
The Wayland protocol is slowly but steadily gaining traction in the Linux world as successor to the X11 display server and is generally seen to replace it in the long term, which is why it is essential for Kodi to support it if it wants to continue to deliver a good user experience on Linux. Kodi did already have a Wayland windowing implementation originally written by Sam Spilsbury during GSoC 2013, but it got removed from master for unsolved infrastructure reasons some time ago and was never on-par with the X11 implementation feature-wise.
Goals
My main goal was quite simply to get Kodi to natively support Wayland again, if possible as well as it currently supports X11. This was refined into a number of sub-goals/features in my initial proposal categorized as "basic" (i.e. necessary so you can reasonably use it at all), "additional," and "possible extension." These goals can be found in full in the
original proposal. They are not revisited goal-for-goal here, but in summary all basic and additional features were completed. One possible extension feature (namely full touch support) was implemented. The remaining ones are listed further down in this document as future work.
Implemented features
The following major features were implemented (links go to GitHub issues, in approximate implementation order):
- Basic Wayland windowing support: Got Kodi running on Wayland again with basic features (only full screen, only full GL, mouse/keyboard input)
- xdg_shell: Wayland has the core wl_shell protocol for communicating details about toplevel windows, but it is deprecated for all practical purposes. To get better integration, support for the still unstable designated successor xdg_shell (version 6 only) was added.
- VAAPI support
- GLES support
- Screensaver inhibition: Support for both the generic org.freedesktop.ScreenSaver DBus interface as well as the Wayland-specific idle inhibit protocol was added.
- Touch input: Kodi/X11 does not have the ability to navigate using multi-touch gestures since touch is only supported via the default X pointer emulation. Kodi/Wayland has full native touch input support.
- Paste from clipboard
- wp_presentation support: The stable wp_presentation protocol provides detailed timing information about displayed frames and is now used for determining display latency and for syncing to video clock on Kodi/Wayland.
- Windowed mode: Most Wayland compositors require applications to draw and handle window decorations themselves (called client-side decorations) if they want to have any. I discussed with my mentor how to go about this and we decided to once again keep things local to the Wayland implementation and draw the decorations there as none of the other windowing systems currently requires this. The other option would have been to somehow integrate the decorations into the Kodi skinning system. This is of course nicer, but far more complicated and probably not worth the trouble. As media center, most users will use Kodi in full screen mode which is also the default, so window decorations that don't look that nice will not be a big problem.
- tools/depends integration for CI: Dependencies for the Wayland build (mostly waylandpp) needed to be added to tools/depends in order to have it build on Jenkins, which the Kodi project uses for continuous integration.
Code
During development I commited all work to my
Kodi fork at GitHub. Further improvements might be made there before they get integrated into mainline.
In preparation of the GSoC work product submission, all Wayland-related changes were submitted as
one pull request against the master branch of the Kodi mainline repository. It was fully merged in the last week of the coding period. Kodi can be built as usual. To select the Wayland platform, the additional CMake arguments
Code:
-DCORE_PLATFORM_NAME=wayland -DWAYLAND_RENDER_SYSTEM=gl
must be used. Also, some extra libraries such as waylandpp are required. For details, see the updated
Linux build instructions.
The main pull request against master had 124 changed files with 9,832 added and 292 removed lines.
Development process
I had planned to salvage as much of the previous code as possible, but different design choices I made ultimately meant that I ended up writing most of it from scratch. Still, I was frequently checking the prior implementation to see which parts of Kodi I have to touch and how I can go about solving some specific aspects.
To get a bit more concrete here, where the approach differs most is how the Wayland protocol objects are used in object-oriented C++. Previously a home-grown approach was used, probably because there were no C++ bindings for libwayland-client at the time. The resulting wrapper code is quite tedious to write and maintain, which is why I decided to use the C++ waylandpp library as base. Even though it is not quite mature yet, I figured that my time would be better spent improving waylandpp than trying to come up with something new on my own. It is of course possible to use the C API of libwayland-client directly without any wrappers, but this is not a very nice solution since the Wayland protocol is really made out to be used in an object-oriented fashion if the language allows for it. Much to my delight, the author of waylandpp was very responsive and supporting, which means that all improvements and feature additions I made to waylandpp at this point are already merged upstream.
Unfortunately, it soon became clear that the novel approaches that Wayland took compared to X11, Windows, and most other windowing systems were not a good match for the Kodi windowing infrastructure: Wayland is designed such that clients have minimal control over the desktop for security reasons. This for example means that applications cannot just set arbitrary video modes. They can only tell what their preference would be to the compositor, which then decides and in turn tells the applications what size they get. On the one hand, I do think that this is a good design decision since it solves a lot of problems that XRandR has like leaving the desktop in a bad resolution when a program crashes. On the other hand, it does mean that a lot of things have to be done differently and that Kodi cannot provide a perfect experience on Wayland for the time being. The reason is that there currently is no practically useful way to tell the compositor e.g. what refresh rate the output should use, so switching to the correct modeline for playback at original speed without occasional micro-stutters is not possible.
As far as the actual implementation is concernced, the Kodi code assumes the traditional procedure of fetching a list of valid resolutions and then being able to switch to any resolution immediately and basically without failure. Changing this in a satisfying way would require quite a lot of refactoring that would have to touch all of the current windowing implementations, too. This is a lot of work, requires coordination with all platform maintainers, and is not realistic to be completed within the GSoC timeframe, so I instead tried to make minimal adjustments to the Kodi resolution switching code that allow the Wayland implementation to work without impacting any other windowing system. The downside to this is that the Wayland code is not as clean as it could or should be and that there is an increased risk of weird stuff happening.
During the past three months I also had to learn that Wayland is still quite new to the scene and that a lot of bugs still lurk in the various components. I had to report and sometimes fix bugs in compositors and other third-party components such as mutter, weston, and libva. Finding these bugs and determining whose fault it is that something did not work as expected took more time than I had initially anticipated.
Future work- Refactor Kodi resolution setting
- Kodi skin cursor image could be placed into the Wayland cursor surface to reduce input latency (at the moment the Wayland cursor surface is empty/unused and Kodi paints the cursor directly into its surface with GL)
- Allow X11 and Wayland in one Kodi build (at the moment Kodi can only be built with one windowing implementation set at compile time): While this would be desirable to facilitate quick adoption of a Wayland, it was ultimately decided that the Kodi core changes if done right would be too extensive to finish in time. Possible work-arounds include shipping two builds plus a wrapper script that starts the version corresponding to the active display server. See here for more details.
- Add facilities to switch resolution and/or frame rate: Wayland currently has no satisfying protocol support for clients that need specific output parameters (except for fullscreen-shell, see below). Therefore, solving this and enabling the resolution adaption in Kodi would require designing and upstreaming a Wayland protocol extension that enables applications to communicate their requirements to the compositor as well as implementing it at least in weston.
- Support for unstable fullscreen-shell protocol to provide modesetting: fullscreen-shell is an alternative shell protocol for a single application to run on a compositor in full screen mode. It has modesetting capabilities. Unclear if needed since Kodi now has a native gbm backend that will result in approximately the same thing (minus the Wayland compositor in between). The gbm backend currently only supports GLES, but it could easily be expanded to full GL.
- Support for zero-copy video rendering of video to YUV surfaces: Still questionable if benefits justify the necessary work
Acknowledgements
I am very grateful to the Kodi team and community for accepting me as student this year and my mentor FernetMenta for always being quick to respond, giving valuable advice, and investing a lot of his private time to review my work. This also goes for a lot of other team members (namely fritsch, lrusak, martijn, paxxi, rechi, and wsnipex) that followed my journey and supported me at specific tasks.
Furthermore, I would like to thank the #wayland IRC community and specifically pq and SardemFF7 for their time and advice that helped me move forward several times.
Contributions to Kodi apart from Wayland PR
Contributions to third-party projects
waylandpp
libva
intel-vaapi-driver
cpython
weston
Bugs reported to third-party projects
mutter/gnome-shell
weston