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 _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
