doc: add warning about mapping DMA-BUFs

A list of reasons why DMA-BUFs have to be treated specially. This
should make it clearer why mmaping DMA-BUFs should be avoided and hint
clients on how treat them correctly

Co-authored-by: columbarius <co1umbarius@protonmail.com>
This commit is contained in:
Simon Ser 2021-08-17 15:02:56 +02:00 committed by Wim Taymans
parent 112d50c8b9
commit 7a618390ec

View file

@ -35,12 +35,12 @@ The second stream parameter should not contain any `SPA_FORMAT_VIDEO_modifier`
property. property.
To prioritise DMA-BUFs place those `SPA_PARAM_EnumFormat` containing modifiers To prioritise DMA-BUFs place those `SPA_PARAM_EnumFormat` containing modifiers
first, when emitting them to PipeWire first, when emitting them to PipeWire.
## param_changed hook ## param_changed hook
When the `param_changed` hook is called for a `SPA_PARAM_Format` the client When the `param_changed` hook is called for a `SPA_PARAM_Format` the client
has to parse the 'spa_pod' directly. Use has to parse the `spa_pod` directly. Use
`spa_pod_find_prop(param, NULL, SPA_FORMAT_VIDEO_modifier)` to check `spa_pod_find_prop(param, NULL, SPA_FORMAT_VIDEO_modifier)` to check
whether modifiers were negotiated. If they were negotiated, set the whether modifiers were negotiated. If they were negotiated, set the
`SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_DmaBuf`. If they were `SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_DmaBuf`. If they were
@ -48,7 +48,7 @@ not negotiated, fall back to shared memory by setting the
`SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_MemFd`, `SPA_PARAM_BUFFERS_dataType` property to `1 << SPA_DATA_MemFd`,
`1 << SPA_DATA_MemPtr`, or both. `1 << SPA_DATA_MemPtr`, or both.
While consumers only have to parse the resulting 'SPA_PARAM_Format' for any While consumers only have to parse the resulting `SPA_PARAM_Format` for any
format related information, it's up to the producer to fixate onto a single format related information, it's up to the producer to fixate onto a single
format modifier pair. The producer is also responsible to check if all clients format modifier pair. The producer is also responsible to check if all clients
announce sufficient capabilities or fallback to shared memory buffers when announce sufficient capabilities or fallback to shared memory buffers when
@ -72,23 +72,23 @@ modifier aware one, or supporting both.
else fall back to SHM, if possible. else fall back to SHM, if possible.
- modifier-aware: - modifier-aware:
In this case a list with all supported modifiers will be returned in the format. In this case a list with all supported modifiers will be returned in the format.
(using 'DRM_FORMAT_MOD_INVALID' as the token for the modifier-less API). (using `DRM_FORMAT_MOD_INVALID` as the token for the modifier-less API).
On the 'param_changed' event check if the modifier key is present and has the flag On the `param_changed` event check if the modifier key is present and has the flag
'SPA_POD_PROP_FLAG_DONT_FIXATE'. attached to it. In this case extract all modifiers `SPA_POD_PROP_FLAG_DONT_FIXATE`. attached to it. In this case extract all modifiers
from the list and do a test allocation with your allocator to choose the preferred from the list and do a test allocation with your allocator to choose the preferred
modifier. Fixate on that 'EnumFormat' by announcing a 'SPA_PARAM_EnumFormat' with modifier. Fixate on that `EnumFormat` by announcing a `SPA_PARAM_EnumFormat` with
only one modifier in the 'SPA_CHOICE_Enum' and without the only one modifier in the `SPA_CHOICE_Enum` and without the
'SPA_POD_PROP_FLAG_DONT_FIXATE', followed by the previous announced `SPA_POD_PROP_FLAG_DONT_FIXATE`, followed by the previous announced
'EnumFormat's. This will retrigger (**TBD**) the 'param_changed' event with an `EnumFormat`s. This will retrigger (**TBD**) the `param_changed` event with an
'SPA__PARAM_Format' as described below. `SPA_PARAM_Format` as described below.
If the 'SPA_PARAM_Format' contains a modifier key, without the flag If the `SPA_PARAM_Format` contains a modifier key, without the flag
'SPA_POD_PROP_FLAG_DONT_FIXATE', it should only contain one value in the `SPA_POD_PROP_FLAG_DONT_FIXATE`, it should only contain one value in the
'SPA_CHOICE_Enum'. In this case announce the 'SPA_PARAM_Buffers' accordingly `SPA_CHOICE_Enum`. In this case announce the `SPA_PARAM_Buffers` accordingly
to the selected format and modifier. It is important to query the plane count to the selected format and modifier. It is important to query the plane count
of the used format modifier pair and set 'SPA_PARAM_BUFFERS_blocks' accordingly. of the used format modifier pair and set `SPA_PARAM_BUFFERS_blocks` accordingly.
Note: When test allocating a buffer, collect all possible modifiers, while omitting Note: When test allocating a buffer, collect all possible modifiers, while omitting
'DRM_FORMAT_MOD_INVALID' from the `SPA_FORMAT_VIDEO_modifier` property and `DRM_FORMAT_MOD_INVALID` from the `SPA_FORMAT_VIDEO_modifier` property and
pass them all to the graphics API. If the allocation fails and the list of pass them all to the graphics API. If the allocation fails and the list of
possible modifiers contains `DRM_FORMAT_MOD_INVALID`, fall back to allocating possible modifiers contains `DRM_FORMAT_MOD_INVALID`, fall back to allocating
without an explicit modifier if the graphics API allows it. without an explicit modifier if the graphics API allows it.
@ -113,4 +113,21 @@ Note: Some graphics APIs have separated functions for the modifier-less case
(`DRM_FORMAT_MOD_INVALID`) or are omitting the modifier, since it might be used (`DRM_FORMAT_MOD_INVALID`) or are omitting the modifier, since it might be used
for error handling. for error handling.
# DMA-BUF mapping warning
It's important to make sure all consumers of the PipeWire stream are prepared
to deal with DMA-BUFs. Most DMA-BUFs cannot be treated like shared memory in general
because of the following issues:
- DMA-BUFs can use hardware-specific tiling and compression as described by
modifiers. Thus, a `mmap(3)` on the DMA-BUF FD will not give a linear view of
the buffer contents.
- DMA-BUFs need to be properly synchronized with the asynchronous reads and
writes of the hardware. A `mmap(3)` call is not enough to guarantee proper
synchronization. (Maybe add link to linux syscall doc??)
- Blindly accessing the DMA-BUFs via `mmap(3)` can be extremely slow if the
buffer has been allocated on discrete hardware. Consumers are better off
using a proper graphics API (such as EGL, Vulkan or VA-API) to process the
DMA-BUFs.
*/ */