When a screencast is started we do a roundtrip on get the offered
formats from wlr_screencopy. This roundtrip can fail [1]. In this case
the formats won't be initialized and we will just error out of the
screencast session.
[1] https://github.com/emersion/xdg-desktop-portal-wlr/issues/214
We teardown all existing screencast_instances using the removed output
by destroying the frame, removing all timers and then marking the
instance as ready for teardown so we can destroy it after the last connected
session is closed.
Any wlr_screencopy_frame_v1 has to be destroyed before the connected
output can be removed. Otherwise wlr_screencopy_frame_v1_destroy
segfaults the whole program. To ensure this we will make all frame
callbacks safe to be triggered for a previous destroyed frame.
wl_array is a better fit than wl_list. It's less intensive on memory and
fits nicely with the flow of dmabuf_feedback announcing all format
modifier pairs at once and reseting them on change.
The compositor can announce it's default rendering device via
linux_dmabuf_feedback as the main_device [1]. We should use this device
whenever possible. If aquiring this device fails we are adviced to use
force linear layout on buffers allocated with the implicit api.
With linux_dmabuf_v1 the modifier event is deprecated. Instead the
format_table event in combination with the tranches of
linux_dmabuf_feedback_v1 has to be used.
[1] https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/unstable/linux-dmabuf/feedback.rst
Calling gbm_bo_create_with_modifiers2(...) and setting the modifiers
pointer to NULL for the same result as gmb_bo_create(...) is a MESA hack,
which I missed to remove from 84282e9b5f.
We query the supported modifiers via a wrapper and announce them via
PipeWire.
This wrapper queries the supported formats from wlroots and returns them
as a simple array. The purpose of this wrapper is to ease the use of the
query functions which are kept in the style of the equivalent egl
queries.
Registering a zwp_linux_dmabuf_v1_listener gives access to the supported
format modifier pairs of the compositor.
This handler emits events for each format modifier pair. Those are stored
and will later be used to announce capabilities via PipeWire.
It has shown that the assumption: "Allocation with implicit modifier will
always be available" doesn't hold true in all cases. Thus if allocation
of any dmabuf fails we mark the session to avoid dmabufs, thus falling
back to shm transport.
This implements the modifier fixation procedure. The producer of a
stream has to ensure that it can create a buffer with the negotiated
properties. To do that we will take the result of the intersection of
supported modifiers by PipeWire and select the "best" modifier from that
list.
To do this we do the following allocations and fixate on the
modifier of the created buffer should the allocation suceed.
* Try to allocate a buffer with explicit modifiers using the list
provided by PipeWire
* Walk the list of modifiers and do single allocations for implicit and
linear modifiers using the old api.
If none of the allocations above succeed we fall back to shm buffers.
This is implemented in the next commit.
If an allocation was successfull we fixate the modifier with
fixate_format().
This function creates an EnumFormat like build_format, but will only
announce support for a single modifier.
It is used to finish the negotiation process by announcing it together
with EnumFormats of our full supported formats.
Using SPA_POD_PROP_FLAG_DONT_FIXATE pipewire can return a list of
supported modifiers. In that case are we responsible to select one
modifier and fixate it.