On the Plasma workspaces Display Power Management Signaling (DPMS) is handled by the power management daemon (powerdevil). After a configurable idle time it signals the X-Server through the X11 DPMS Extension. The X-Server handles the timeout, switching to a different DPMS level and restoring to enabled after an input event all by itself.
The X11 extension is a one-way channel. One can tell the X-Server to go to DPMS, but it neither notifies when it has done so nor when it restored. This means powerdevil doesn’t know when the screens are off. Granted, there is a call to query the current state, but we cannot perform active polling to figure out whether the state changed. That would be rather bad from a power management perspective.
So overall it’s kind of a black box. Our power management doesn’t know when the screens turn off, Neither does any other application including KWin. For KWin it would be rather important to know about it, because it’s the compositor and there is no point in running the compositor to render for something which will never be visible. The same is obviously true for any other application: it will happily continue to render updated states although it won’t be visible. For a power management feature this is rather disappointing.
Now let’s switch to Wayland – in this case kwin_wayland. Last week I started to implement support for DPMS in KWin. Given that KWin is responsible for DRM, we need to add support for it in KWin. Of course we want to leverage the existing code in powerdevil, so we don’t add the actual power management functionality, but rather an easy to use interface to tell KWin to enter a DPMS state on a given output.
Of course we tried to not repeat the mistake from X11 and thus the interface is bi-directional: it notifies when a given state is entered. Although in a Wayland world that’s not so important any more: KWin enables DPMS and knows that DPMS is enabled and can make internal use of this. So whenever the outputs are put into standby the compositor loop is stopped and doesn’t try to repaint any more. If the compositor is stopped windows are not being repainted and aren’t signaled that the last frame got painted. So all applications properly supporting frame callbacks stop rendering automatically, too. This means on Wayland we are able to properly put the rendering of all applications into an off state when the connected outputs are in standby mode. A huge improvement for power management.
Very neat and nifty feature!
Great 🙂 I just hope that there aren’t too many apps out there with a buggy event loop that will stop all activity rather than just rendering activity when the screen is off…
In applications using EGL, the frame callback and buffer release events are handled by the EGL platform code, so it will probably block in a eglSwapBuffers or when starting to render a frame, in glClear for example.
In Mesa, this is in platform_wayland.c, it will block in get_back_bo function when starting to render.
If I’m right all applications doing OpenGL on the main thread will have issues (and perhaps even other ones if some code assumes the rendering thread loops in a reasonable amount of time).
yeah if applications are badly prepared it can be bad – but then they should not use the frame callback. One needs to question the choice by mesa here.
If apps do not want EGL to block indefinitely, they have a couple of choices currently:
– ask for their own frame callbacks, and do not call eglSwapBuffers() if they haven’t got their callback signalled,
– set eglSwapInterval to zero,
– or preferably do both, so you are appropriately throttled while you still have the option to draw if you really want to.
Unfortunately, I think the EGL spec kind of requires waiting for frame callbacks when swap interval is one. At least I don’t have any good ideas what else one could do in an EGL implementation.
Of course everything will get even more complicated when people demand for the option to tear on purpose, which perhaps might conflict with the swap interval zero as proposed in Mesa.
I don’t know how Mesa could have done otherwise. They must block somewhere (unless swap interval is 0).
An application could probably listen to frame callback too, and only start rendering a frame when it receives the event. In this case the mesa code shouldn’t block.
Why would it be any different from the current case where an application’s window is offscreen (e.g. on a different desktop?) Or do offscreen windows get notifications that they have been painted? (Why?)
On Wayland it isn’t a difference – you’re right. The compositor is not supposed to send frameRendered to not visible windows. On X11 it’s different, though. Windows don’t get a callback, aren’t blocked and just assume they get rendered.
Does this mean that it will be possible for KWin/Wayland to automatically lock my session when I turn my monitor off? That’s been on my “it would be nice to have, I wonder why no-one’s ever implemented it” list for *years*…
DPMS doesn’t typically provide feedback that your monitor is turned off. Depending on the monitor, it *might* stop showing up as a monitor when turned off, in which case your desktop environment could detect the lack of outputs and lock. But some monitors keep showing up as a monitor even when turned off.
Sorry no: DPMS is here no help. We don’t detect that.
Ah, right. I see I misunderstood “This means powerdevil doesn’t know when the screens are off.” I thought this meant it was possible for the hardware to tell when a screen had been switched off, only powerdevil couldn’t access that, now I realise it just means (I think) that we can tell when a screen has gone into power-saving mode.
This seems weird. We can read an EDID containing all manner of data, whether a screen is powered on or not. And we can tell whether a screen is in power-saving mode or not. But there’s no bit to say whether it’s powered on or not? What an odd omission from the protocol.
It might be that this exists. But I haven’t looked into it yet. Anyway: that would end in not being considered as power management by us, but rather in a screen change. E.g. we would remove the screen from the logical set of enabled screens.
Do things work like this for Android’s compositor? Or elsewhere, e.g. with iOS?