DRM output writeback support
The KMS API now has support for writeback connectors, which attach to a CRTC and provide a snapshot of that CRTC's output into a FB ID nominated at atomic commit time.
The DRM backend does not currently provide native support for screenshots. If a screenshot is requested, planes will be temporarily disabled and another output repaint scheduled with the output from the renderer recorded. This is bad because it requires an extra repaint cycle (which isn't great for performance), but also totally precludes its use for debugging any issues with planes.
If supported, we should use a writeback connector to capture the output from the CRTC into a specially-allocated FB which we can then pass directly to the consumer, which avoids the above dance. Constant-capture mode would mean that, at the cost of allocating more buffers, we could also retain snapshots for every repaint for post-mortem debugging (#144).
The same also applies to, e.g., output streaming into VA-API, which would again allow us to use planes where possible.
A good implementation would, I think, proceed in steps of:
- adding awareness of writeback-connector types to the DRM backend, and ignoring them for regular output configuration
- storing lists of writeback connectors in the backends, with a set of CRTCs they can be associated with (maybe they need to be
drm_head
s?) - the ability to allocate buffers for writeback connectors (I think GBM +
USE_LINEAR
is what we want here) and createdrm_fb
s for them - the ability to capture content through writeback connectors for one commit on request, falling back to the renderer if unsupported
- using this for screenshots
- using this for screen recording (VA-API etc)
- implementing a per-output screenshot of last-repaint screenshots, to use for post-mortem debugging
Open questions:
- are writeback connectors best exposed as
drm_head
/weston_head
s which we just make sure libweston ignores? - how do we allocate buffers: GBM linear or dumb buffers?
- when a screenshot is requested, do we go through another repaint cycle or do we immediately screenshot (potentially delaying the next repaint)?