From 8ee306eb3fb69c34c579874f6aedcecb6d94a855 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 9 Mar 2018 21:24:52 -0500 Subject: [PATCH] allocators: Add DMABuf synchronization When doing CPU Access, some architecture may require caches to be synchronize before use. Otherwise, some visual artifact may be visible, as the CPU modification may still resides in cache. https://bugzilla.gnome.org/show_bug.cgi?id=794216 --- configure.ac | 3 ++ gst-libs/gst/allocators/gstdmabuf.c | 59 +++++++++++++++++++++++++++-- meson.build | 1 + 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 67ebb75325..cca8233d0d 100644 --- a/configure.ac +++ b/configure.ac @@ -486,6 +486,9 @@ esac dnl Check for mmap (needed by allocators library) AC_CHECK_FUNC([mmap], [AC_DEFINE(HAVE_MMAP, 1, [Defined if mmap is supported])]) +dnl Check for DMABuf synchronization ioctl (needed for DMABuf CPU access) +AC_CHECK_HEADERS([linux/dma-buf.h], []) + dnl *** plug-ins to include *** dnl these are all the gst plug-ins, compilable without additional libs diff --git a/gst-libs/gst/allocators/gstdmabuf.c b/gst-libs/gst/allocators/gstdmabuf.c index 170267be5f..e9c5dd3736 100644 --- a/gst-libs/gst/allocators/gstdmabuf.c +++ b/gst-libs/gst/allocators/gstdmabuf.c @@ -34,9 +34,9 @@ * Since: 1.2 */ -#ifdef HAVE_MMAP -#include -#include +#ifdef HAVE_LINUX_DMA_BUF_H +#include +#include #endif GST_DEBUG_CATEGORY_STATIC (dmabuf_debug); @@ -44,6 +44,57 @@ GST_DEBUG_CATEGORY_STATIC (dmabuf_debug); G_DEFINE_TYPE (GstDmaBufAllocator, gst_dmabuf_allocator, GST_TYPE_FD_ALLOCATOR); +static gpointer +gst_dmabuf_mem_map (GstMemory * gmem, GstMapInfo * info, gsize maxsize) +{ + GstAllocator *allocator = gmem->allocator; +#ifdef HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { DMA_BUF_SYNC_START }; + gpointer ret; + + if (info->flags & GST_MAP_READ) + sync.flags |= DMA_BUF_SYNC_READ; + + if (info->flags & GST_MAP_WRITE) + sync.flags |= DMA_BUF_SYNC_WRITE; +#endif + + ret = allocator->mem_map (gmem, maxsize, info->flags); + +#ifdef HAVE_LINUX_DMA_BUF_H + if (ret) { + if (ioctl (gst_fd_memory_get_fd (gmem), DMA_BUF_IOCTL_SYNC, &sync) < 0) + GST_WARNING_OBJECT (allocator, "Failed to synchronize DMABuf: %s (%i)", + g_strerror (errno), errno); + } +#endif + + return ret; +} + +static void +gst_dmabuf_mem_unmap (GstMemory * gmem, GstMapInfo * info) +{ + GstAllocator *allocator = gmem->allocator; +#ifdef HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { DMA_BUF_SYNC_END }; + + if (info->flags & GST_MAP_READ) + sync.flags |= DMA_BUF_SYNC_READ; + + if (info->flags & GST_MAP_WRITE) + sync.flags |= DMA_BUF_SYNC_WRITE; + + if (ioctl (gst_fd_memory_get_fd (gmem), DMA_BUF_IOCTL_SYNC, &sync) < 0) + GST_WARNING_OBJECT (allocator, "Failed to synchronize DMABuf: %s (%i)", + g_strerror (errno), errno); +#else + GST_WARNING_OBJECT (allocator, "Using DMABuf without synchronization."); +#endif + + allocator->mem_unmap (gmem); +} + static void gst_dmabuf_allocator_class_init (GstDmaBufAllocatorClass * klass) { @@ -55,6 +106,8 @@ gst_dmabuf_allocator_init (GstDmaBufAllocator * allocator) GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); alloc->mem_type = GST_ALLOCATOR_DMABUF; + alloc->mem_map_full = gst_dmabuf_mem_map; + alloc->mem_unmap_full = gst_dmabuf_mem_unmap; } /** diff --git a/meson.build b/meson.build index 344f25f8bf..5c268112b4 100644 --- a/meson.build +++ b/meson.build @@ -79,6 +79,7 @@ check_headers = [ ['HAVE_UNISTD_H', 'unistd.h'], ['HAVE_WINSOCK2_H', 'winsock2.h'], ['HAVE_XMMINTRIN_H', 'xmmintrin.h'], + ['HAVE_LINUX_DMA_BUF_H', 'linux/dma-buf.h'], ] foreach h : check_headers if cc.has_header(h.get(1))