History

hwcontext_drm: issue DMA_BUF_IOCTL_SYNC when mapping FDs

This improves performance and helps a little when given FDs without any synchronization fences.

Lynne committed 5 years ago

Commit 993d8d91 parent dd348611 file · +31 −5Browse files

Unified · Split

libavutil/hwcontext_drm.c+31−5
@@ -19,6 +19,8 @@ · 18 unmodified lines
1919 #include <fcntl.h>
2020 #include <sys/mman.h>
2121 #include <unistd.h>
22+#include <linux/dma-buf.h>
23+#include <sys/ioctl.h>
2224
2325 #include <drm.h>
2426 #include <xf86drm.h>
@@ -85,6 +87,8 @@ static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) · 60 unmodified lines
8587 typedef struct DRMMapping {
8688 // Address and length of each mmap()ed region.
8789 int nb_regions;
90+ int sync_flags;
91+ int object[AV_DRM_MAX_PLANES];
8892 void *address[AV_DRM_MAX_PLANES];
8993 size_t length[AV_DRM_MAX_PLANES];
9094 } DRMMapping;
@@ -93,10 +97,16 @@ static void drm_unmap_frame(AVHWFramesContext *hwfc, · 2 unmodified lines
9397 HWMapDescriptor *hwmap)
9498 {
9599 DRMMapping *map = hwmap->priv;
96− int i;
97−
98− for (i = 0; i < map->nb_regions; i++)
100+ struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags };
101+ int i, ret;
102+
103+ for (i = 0; i < map->nb_regions; i++) {
104+ ret = ioctl(map->object[i], DMA_BUF_IOCTL_SYNC, &sync);
105+ if (ret)
106+ av_log(hwfc, AV_LOG_ERROR, "Failed to issue ioctl sync to DRM object "
107+ "%d: %d.\n", map->object[i], errno);
99108 munmap(map->address[i], map->length[i]);
109+ }
100110
101111 av_free(map);
102112 }
@@ -105,6 +115,7 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 2 unmodified lines
105115 AVFrame *dst, const AVFrame *src, int flags)
106116 {
107117 const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0];
118+ struct dma_buf_sync sync_start = { 0 };
108119 DRMMapping *map;
109120 int err, i, p, plane;
110121 int mmap_prot;
@@ -115,10 +126,16 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 4 unmodified lines
115126 return AVERROR(ENOMEM);
116127
117128 mmap_prot = 0;
118− if (flags & AV_HWFRAME_MAP_READ)
129+ if (flags & AV_HWFRAME_MAP_READ) {
119130 mmap_prot |= PROT_READ;
120− if (flags & AV_HWFRAME_MAP_WRITE)
131+ map->sync_flags |= DMA_BUF_SYNC_READ;
132+ }
133+ if (flags & AV_HWFRAME_MAP_WRITE) {
121134 mmap_prot |= PROT_WRITE;
135+ map->sync_flags |= DMA_BUF_SYNC_WRITE;
136+ }
137+
138+ sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags;
122139
123140 av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);
124141 for (i = 0; i < desc->nb_objects; i++) {
@@ -133,6 +150,15 @@ static int drm_map_frame(AVHWFramesContext *hwfc, · 8 unmodified lines
133150
134151 map->address[i] = addr;
135152 map->length[i] = desc->objects[i].size;
153+ map->object[i] = desc->objects[i].fd;
154+
155+ err = ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
156+ if (err) {
157+ err = AVERROR(errno);
158+ av_log(hwfc, AV_LOG_ERROR, "Failed to issue ioctl sync to DRM object "
159+ "%d: %d.\n", desc->objects[i].fd, errno);
160+ goto fail;
161+ }
136162 }
137163 map->nb_regions = i;
138164

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t