I haven’t been blogging about KWin for quite some time, so it’s way time to write what I recently worked on for KWin.
The big topic of the work of the last two weeks is improving the startup experience of KWin. It’s mostly a scratch your own itch as I do restart KWin quite often while working on it and having it start up faster is a nice thing in general.
KWin consists of multiple parts which need to startup:
- Window Manager
- Compositor
- Effects
- Scripts
The current version does everything in one go and starts with the compositor, but the first frame is rendered after everything has been set up. During this process the screen is frozen as the compositor has taken over the rendering from X and the screen has not yet been rendered by the compositor. This is not visible for users as KWin only starts up while the Splash Screen is shown and given the way how our Splash works this short freeze is hardly visible. If you know that it has to happen and if you know which of the shown icons belongs to the window manager you can see it.
My idea to improve this is splitting up the startup into phases and try to get the first frame rendered faster. E.g. the Compositor is fully functional without Effects, the Window Manager does not need the scripts and so on. What we now already have in master is delaying the loading of Scripts into the first event cycle after the Window Manager has set up everything else.
This does not shorten the startup time but reduced the frozen time. Even the overall frozen time is more or less the same, but we get a rendered frame in between.
To get the actual startup time down a possible solution is to identify areas which take long and make them load in parallel. For that areas where KWin actually waits for something else need to be identified and moved into an async running thread.
One of these areas is the loading of the configuration options. KWin re-parses the configuration file at startup. This is I/O and KWin needs to wait for it, but no longer in current master. The I/O operation is now performed in a background thread and only if the loading has not finished before KWin needs to access a configuration value for the first time it will have to wait. On my system loading the file takes only a few milliseconds and with an SSD it should be even faster, but nevertheless it’s a few milliseconds shorter startup time. And we have to consider that during startup there is a lot I/O going on and the file has probably not yet moved into the cache. But the longer it takes the more likely it is that KWin has to wait as we need config options very early in the startup process.
Also the Compositor is currently waiting: it invokes an external program to figure out whether direct rendering is supported or not. After reworking the patches multiple times during review this is now strongly improved. KWin does no longer have to wait for the external program and as a side effect the code got cleaned up, so that no OpenGL call is created outside the compositor. To achieve the we “had to” remove OpenGL detection from the Desktop Effects configuration module. It now queries KWin directly which is of course much better.
Executing the external program took around 100 msec on my system and the code which got removed were another 50 msec. That was about 5 % of the overall KWin startup time on my system.
While doing the profiling I also figured out a few things which can easily improved when creating and destroying windows. So I discovered that the window decorations are actually created twice: once when the window is started for compositing and once when the window is fully managed by the window manager. This had been required to support both compositing and non-compositing and to allow easily turning on and off compositing at runtime (decoration needs to be recreated to e.g. remove shadows). My current patches will now ensure that the decoration is not created twice when a window is opened, though in the special case when kwin restarts it still has to create them twice. But that’s a problem I have to live with and which does not affect our users.
Another interesting thing we discovered due to a crash I recently introduced: while ending the window manager completely we performed quite some heavy operations on the windows, which make sense during the normal operation but not when shutting down. This is now nicely optimized away resulting in a faster and more secure shutdown.
This weekend I continued to move I/O operations into threads and loading KWin scripts from file does no longer block the window manager and compositor. It’s now more or less a pattern which I will try to use for other areas where files are loaded (e.g. some effects).