diff --git a/doc/dox/internals/dma-buf.dox b/doc/dox/internals/dma-buf.dox index 4e1b1e5e2..74569766b 100644 --- a/doc/dox/internals/dma-buf.dox +++ b/doc/dox/internals/dma-buf.dox @@ -89,6 +89,8 @@ modifier-aware one, or supporting both. \ref SPA_CHOICE_Enum. In this case announce the \ref SPA_PARAM_Buffers accordingly 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. + You might also want to add the option of adding explicit sync support to the + buffers, as explained below. Note: When test allocating a buffer, collect all possible modifiers, while omitting `DRM_FORMAT_MOD_INVALID` from the \ref SPA_FORMAT_VIDEO_modifier property and @@ -177,4 +179,127 @@ no modifier is present, if it can guarantee, that the used buffer is mmapable. Note: For now v4l2 uses planar buffers without modifiers. This is the reason for this special case. +# Explicit sync + +In addition to DMABUF, a set of synchronization primitives (a SyncObjTimeline) and +associated metadata can be negotiated on the buffers. + +The explicit sync step is performed *after* the Format has been negotiated. + +## Query support for explicit sync in the driver. + +You might first want to check that the drm render you are using is capable of explicit +sync by checking support for DRM_CAP_SYNCOBJ and DRM_CAP_SYNCOBJ_TIMELINE before +attempting to negotiate explicit sync. + +## Provide space in the buffer for explicit sync + +Explicit sync requires two extra fds in the buffers and an extra +\ref SPA_META_SyncTimeline metadata structure. + +The metadata structure will only be allocated when both sides support explicit +sync. We can use this to make a fallback \ref SPA_PARAM_Buffers so that we can +support both explicit sync and a fallback to implicit sync. + +So, first announce support for \ref SPA_META_SyncTimeline by adding the +\ref SPA_TYPE_OBJECT_ParamMeta object to the stream: + +``` + params[n_params++] = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_SyncTimeline), + SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_sync_timeline))); +``` + +Next make a \ref SPA_PARAM_Buffers that depends on the negotiation of the SyncTimelime metadata: + +``` + spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers); + spa_pod_builder_add(&b, + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(8, 2, MAX_BUFFERS), + SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(3), + SPA_PARAM_BUFFERS_size, SPA_POD_Int(size), + SPA_PARAM_BUFFERS_stride, SPA_POD_Int(data->stride), + SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int((1<stride), + SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int((1<datas[buf->n_datas - 2].fd, &acquire_handle); + drmSyncobjFDToHandle(drm_fd, buf->datas[buf->n_datas - 1].fd, &release_handle); +``` + +## Use the SPA_META_SyncTimeline when processing buffers + +The \ref struct spa_meta_sync_timeline contains 2 fields: the acquire_point and +release_point. + +Producers will start a render operation on the DMABUF of the buffer and place +the acquire_point in the \ref struct spa_meta_sync_timeline. When the rendering is +complete, the producer should signal the acquire_point on the acquire SyncObjTimeline. + +Producers will also add a release_point on the release SyncObjTimeline. They are +only allowed to reuse the buffer when the release_point has been signaled. + +Consumers use the acquire_point to wait for rendering to complete before processing +the buffer. This can be offloaded to the hardware when submitting the rendering +operation or it can be done explicitly with drmSyncobjTimelineWait() on the acquire +SyncObjTimeline handle and the acquire_point of the metadata. + +Consumers should then also signal the release_point on the release SyncObjTimeline when +they complete processing the buffer. This can be done in the hardware as part of +the render pipeline or explicitly with drmSyncobjTimelineSignal() on the release +handle and the release_point of the metadata. + + */