Commit 8ee306eb authored by Nicolas Dufresne's avatar Nicolas Dufresne

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
parent 4696ecab
......@@ -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
......
......@@ -34,9 +34,9 @@
* Since: 1.2
*/
#ifdef HAVE_MMAP
#include <sys/mman.h>
#include <unistd.h>
#ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#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;
}
/**
......
......@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment