[PATCH weston 0/7] Grouped output repaint
Daniel Stone
daniels at collabora.com
Tue Feb 14 13:18:00 UTC 2017
Hi,
One of the nice features of atomic modesetting is, well, atomicity of
modesetting. Specifically that you can perform one call across every
output to set every mode in one go.
The previous atomic series implemented the nuclear pageflip side of
atomic modesetting (for one output, every plane reconfigured together),
which allows us to use planes. But not the atomic modesetting part.
The atomic API not only encourages us to do grouped output modesetting,
but actually _enforces_ it in some cases. For instance, when calling
drmModeSetCrtc() as the legacy hook, it orphans the old configuration
if necessary.
If we have CRTC A powering connector B at entry and CRTC C powering
connector D at entry, and Weston decides it would like to have CRTC C
powering connector B, setting the latter configuration through
drmModeSetCrtc results in CRTC A being disabled (as all its connectors
have been stolen), as well as connector D being disabled (as it is
no longer connected to a CRTC).
The atomic API instead demands that we explicitly set the entire state,
and errors out if we simply try to put in a C -> B link, as it will not
implicitly orphan objects.
This all happens at output->repaint() time, since in order to enable
our outputs, we need some content to display. In order to implement
this, I've rearranged target frame times to be calculated in absolute
space, driven by a unified idle_repaint timer. A backend's
repaint_begin() hook, if present, is called and allowed to return
private data which is constant for the length of the repaint. When all
outputs have been repainted, repaint_flush() is called to allow it to
submit all repaint data as a whole.
Doing this enables proper use of the atomic API, as well as a
performance improvement: rather than going through multiple serialised
output disable/wait/re-enable cycles, we can perform everything in one
go. Doing this enables some esoteric usecases, e.g. on Intel hardware
which only has two clocks for three CRTCs. Without atomic, some
reconfigurations will fail due to transient intermediate state: we would
need to disable all outputs first, then bring them back one by one.
Doing it all in one go means that the kernel can validate the final
state.
It's also a bit nicer for backends, as they no longer need to stash data
away between assign_planes() and repaint().
In order to make this bulletproof, I've special-cased the scenario where
we legitimately have no idea when our repaint window is (when we haven't
set a mode, we don't know anything of vblank timings), in which case we
schedule a repaint immediately rather than adding a few milliseconds.
This is good for an imperceptibly small startup time improvement.
Whilst in the area, I added some timespec helpers rather than
open-coding things, and tests for same.
Cheers,
Daniel
More information about the wayland-devel
mailing list