/* GStreamer dmabuf allocator
 * Copyright (C) 2013 Linaro SA
 * Author: Benjamin Gaignard <benjamin.gaignard@linaro.org> for Linaro.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for mordetails.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstfdmemory.h"
#include "gstdmabuf.h"

/**
 * SECTION:gstdmabuf
 * @title: GstDmaBufAllocator
 * @short_description: Memory wrapper for Linux dmabuf memory
 * @see_also: #GstMemory
 *
 * Since: 1.2
 */

#ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#endif

GST_DEBUG_CATEGORY_STATIC (dmabuf_debug);
#define GST_CAT_DEFAULT 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)
{
}

static void
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;
}

/**
 * gst_dmabuf_allocator_new:
 *
 * Return a new dmabuf allocator.
 *
 * Returns: (transfer full): a new dmabuf allocator, or NULL if the allocator
 *    isn't available. Use gst_object_unref() to release the allocator after
 *    usage
 *
 * Since: 1.2
 */
GstAllocator *
gst_dmabuf_allocator_new (void)
{
  GstAllocator *alloc;

  GST_DEBUG_CATEGORY_INIT (dmabuf_debug, "dmabuf", 0, "dmabuf memory");

  alloc = g_object_new (GST_TYPE_DMABUF_ALLOCATOR, NULL);
  gst_object_ref_sink (alloc);

  return alloc;
}

/**
 * gst_dmabuf_allocator_alloc:
 * @allocator: allocator to be used for this memory
 * @fd: dmabuf file descriptor
 * @size: memory size
 *
 * Return a %GstMemory that wraps a dmabuf file descriptor.
 *
 * Returns: (transfer full): a GstMemory based on @allocator.
 * When the buffer will be released dmabuf allocator will close the @fd.
 * The memory is only mmapped on gst_buffer_mmap() request.
 *
 * Since: 1.2
 */
GstMemory *
gst_dmabuf_allocator_alloc (GstAllocator * allocator, gint fd, gsize size)
{
  g_return_val_if_fail (GST_IS_DMABUF_ALLOCATOR (allocator), NULL);

  return gst_fd_allocator_alloc (allocator, fd, size, GST_FD_MEMORY_FLAG_NONE);
}

/**
 * gst_dmabuf_memory_get_fd:
 * @mem: the memory to get the file descriptor
 *
 * Return the file descriptor associated with @mem.
 *
 * Returns: the file descriptor associated with the memory, or -1.  The file
 *     descriptor is still owned by the GstMemory.  Use dup to take a copy
 *     if you intend to use it beyond the lifetime of this GstMemory.
 *
 * Since: 1.2
 */
gint
gst_dmabuf_memory_get_fd (GstMemory * mem)
{
  g_return_val_if_fail (gst_is_dmabuf_memory (mem), -1);

  return gst_fd_memory_get_fd (mem);
}

/**
 * gst_is_dmabuf_memory:
 * @mem: the memory to be check
 *
 * Check if @mem is dmabuf memory.
 *
 * Returns: %TRUE if @mem is dmabuf memory, otherwise %FALSE
 *
 * Since: 1.2
 */
gboolean
gst_is_dmabuf_memory (GstMemory * mem)
{
  g_return_val_if_fail (mem != NULL, FALSE);

  return GST_IS_DMABUF_ALLOCATOR (mem->allocator);
}
