Hi all, Building on the previous series, as well as the global repaint timer series which I've just sent out for more review (thanks Pekka!), here is v9 of atomic. The most interesting feature is that it is now atomic.
As mentioned in the patch changelogs, in order to use the atomic API correctly, we need the global repaint hook, and thus atomicity of modesetting. The reason is that the legacy API (e.g. drmModeSetCrtc) will implicitly pull in other objects: when changing routing between, say, a CRTC and a connector, it will remove the changing object's connection from other objects, and disable them if necessary. Atomic refuses to do this, as it demands (for locking purposes, if nothing else) that all state be explicitly provided by the user. I have thus, on top of the global repaint timer, implemented a fully atomic modeset for at least all points where we need to reset all state and program in something completely new. The steady state remains, of course, entirely on a per-output repaint timer. Doing this required introducing a third level of state: drm_pending_state (bikeshed suggestions welcome, why not). So we have, in descending ownership order: - drm_pending_state lives between repaint_begin to repaint_flush or repaint_cancel, solely to group proposed drm_output_states together - when the repaint is flushed, the drm_output_states are exploded to be treated individually, and are no longer owned by the drm_pending_state, which is discarded - the drm_output_state is primarily a collection of drm_plane_states, which are what own the drm_fbs I've addressed all pending review comments I've got, and thanks to testing from Fabien DESSENNE and Tiago Gomes as well as what I've found in my own travels, fixed some bugs too. Eagle eyes will note that this series introduces dependencies on three unmerged kernel patches. The first is the per-CRTC atomic completion interface, which we need in order to actually do this correctly. It introduces a crtc_id variable into atomic completion events, so we can tell outputs apart (as one event is sent for each CRTC). It can be found here: https://patchwork.kernel.org/patch/7025111/ The second is the drmModeGetPlane2 ioctl, which we use to discover the set of supported format modifiers. This is not critical, as it is purely a new feature, but still getting acks would be nice. It can be found here: http://www.spinics.net/lists/dri-devel/msg127666.html The third is the GBM counterpart to GetPlane2, where we pass GBM a list of supported modiifers, so we can render our composition output into tiled or compressed buffers. It can be found here: https://lists.freedesktop.org/archives/mesa-dev/2016-December/137120.html New kernel uABI must come with a real-world user (that's us!), where the use of the interface is acked, before merge. So it would be very nice to get feedback on our use of these interfaces, and any potential pitfalls, so we can get them merged into the kernel before we depend on them. The series can be pulled from Git at: git://git.collabora.com/git/user/daniels/weston#wip/2017-03/atomic-v9 It can be considered in several groups: The pixel-format helpers are largely standalone, and I would welcome any review on these, as well as anyone who feels like porting gl-renderer to use them ... 03-10 are already largely reviewed by Pekka, adding a refcount to drm_fb so we can reuse them. One benefit of explicit refcounting is that we don't have to re-render every time we hit repaint: if the only changed content is on an overlay, the composited content can just be reused from the last frame. Pekka has already reviewed these, but more eyes are never a bad thing. If nothing horrible comes up in review here, I'm inclined to merge them reasonably soon. 11-19 lay the groundwork for treating all the state we have from repaint as, well, state. This is the core building block of atomic: we build up a full view of the _proposed_ state during atomic, and repeatedly test it, discarding it if it fails. The previous structure assumed a very linear progression through a repaint cycle, which no longer holds true in our brave new world. 20-22 are mostly about how we use DRM properties, and putting in a more robust structure around them to reduce a lot of boilerplate. They may look familiar, but have been substantially changed since the last series. 23-25 introduce the three levels of state object. These changes are mostly mechanical, thanks to the 11-19 prep work. 26-33 include a couple of smaller patches, but are mostly about using the new state objects everywhere, moving the separate users over one by one. By patch 33, our normal paths do not call any of the DRM state modification functions (drmModeSetCrtc, drmModePageFlip, drmModeSetCursor, drmModeSetPlane) other than through applying a state object. 34-37 are surprisingly small: since our only path to changing state is contained in the one place, we just add an alternate route which applies that state through the atomic API. At this point, we are gaining little to no benefit from the atomic API (bar faster startup times from not blocking serially on drmModeSetCrtc), but we are at least using it. 38-45 begin to attack the state _generation_ path in assign_planes, extracting common helpers. The old path had a mismatch of capability: between scanout, overlay and cursor, it was a crapshoot as to whether the particular path would support viewport/scaling/cropping, or dmabuf, etc. This part of the series pulls them towards more common code. 46-50 take advantage of the above, by adding support for complex client dmabuf buffers: multi-planar, or with modifiers. 51-60 returns to the state generation path, splitting it in two. It takes an incremental approach of generating a proposed state with overlay planes in use, testing it (the atomic API _requires_ kernel drivers to provide a meaningful 'will this state work if I set it?' path), and tearing it down if it fails. This required some fairly heavy surgery on assign_planes, but leaves us with some self-contained walks. Some 61 and 62 add support for rendering tiled/compressed buffers for composition output through GBM. They depend on unmerged kernel/Mesa ABI so are not currently suitable for merging, though again, having review and acks on these is going to be essential to getting those ABIs merged in the first place. I've tested these on Intel (Skylake, dual-head), Rockchip (with the Mali driver), RPi2 (VC4 driver), and a DragonBoard 410c (with Freedreno). I have a few more systems I'll try to bring up and do more testing on over the next couple of weeks. But the nice takeaway is that I could start weston-simple-egl -o, move my cursor over it, and observe that simple-egl was promoted to a plane, with no other repaints at all. Previously this wouldn't happen for many reasons: Weston would recomposite all non-plane content, even if unchanged, the different outputs would try to steal planes from each other and thus constantly force repaints on each other, etc. As always, I'm more than open to any suggestions, or even dumb questions: 'I don't understand this, what is it / why does it exist?', is probably a good pointer for me to go write some documentation. I will happily walk through all of this with anyone who wants to review it. Have a great weekend. Cheers, Daniel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel