Power saving with variable refresh rate
In many cases, driving a high resolution and/or high refresh rate display requires the GPU to keep VRAM clocks high, which uses a lot of power. With VRR, we can reduce the refresh rate when appropriate to reduce that power usage.
This is a long term goal, as the kernel API isn't currently well suited for this purpose: We have one property that toggles whether or not the kernel changes the refresh rate to the rate at which KWin commits new frames, and that's it. This is problematic, as in normal desktop operations KWin submits buffers in irregular patterns, causing the refresh rate to change rapidly, and thus causing visible flicker on many displays.
Some possibilities of implementing this would be:
- (obviously) add a kernel API allowing us to set any refresh rate we want, or to otherwise limit the rate at which the refresh rate changes to eliminate flicker. With the rate at which the drm API evolves I'm not optimistic about this, but maybe worth a try
- we could enable VRR whenever we're not updating anything. This has the drawback that we're drastically changing the refresh rate, causing a moment of brightness change, but it's not that noticeable if it doesn't happen often
- recently amdgpu has added VRR modes. These are a few special modes that can be switched to without doing a modeset. Which modes can do this can be figured out by doing atomic tests, so it would be possible to switch to a lower refresh rate mode while KWin is committing fewer frames. As a downside, this is still rapidly changing the refresh rate, so the same caveat as with the option above applies
- with !3828 (merged) and some additional work, it may be possible to use the commit thread to do atomic commits at a very stable rate, allowing us to emulate any refresh rate + limited rate of change thereof we want. It may also require actually triggering page flips though, so we'd need at least two identical buffers to flip between... needs to be tested and evaluated if it's worth the complexity.