/*
 * GStreamer
 * Copyright (c) 2016, Freescale Semiconductor, Inc. 
 *
 * 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 Foundatdma; either
 * versdma 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 more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundatdma, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

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

#include "gstglfuncs.h"

#include <string.h>

#include <gst/allocators/gstdmabuf.h>
#include <gst/gl/gstglmemorydma.h>

#if GST_GL_HAVE_IONDMA
#include <gst/allocators/gstionmemory.h>
#endif

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_DMA_MEMORY);
#define GST_CAT_DEFAULT GST_CAT_GL_DMA_MEMORY

#define parent_class gst_gl_memory_dma_allocator_parent_class
G_DEFINE_TYPE (GstGLMemoryDMAAllocator, gst_gl_memory_dma_allocator,
    GST_TYPE_GL_MEMORY_ALLOCATOR);

static void
gst_gl_memory_dma_init_instance (void)
{
  GstAllocator *ion_allocator = NULL;
  GstGLMemoryDMAAllocator *_gl_allocator;

  GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_DMA_MEMORY, "glmemorydma", 0, "OpenGL dma memory");

#if GST_GL_HAVE_IONDMA
  ion_allocator = gst_ion_allocator_obtain();
#endif

  if (!ion_allocator)
    return;

  gst_gl_memory_init_once ();

  _gl_allocator = (GstGLMemoryDMAAllocator *) g_object_new (GST_TYPE_GL_MEMORY_DMA_ALLOCATOR, NULL);
  _gl_allocator->ion_allocator = ion_allocator;

  gst_allocator_register (GST_GL_MEMORY_DMA_ALLOCATOR_NAME,
      gst_object_ref (_gl_allocator));
}

GstAllocator *
gst_gl_memory_dma_allocator_obtain (void)
{

  static GOnce once = G_ONCE_INIT;
  GstAllocator *allocator;

  g_once (&once, (GThreadFunc) gst_gl_memory_dma_init_instance, NULL);

  allocator = gst_allocator_find (GST_GL_MEMORY_DMA_ALLOCATOR_NAME);
  if (allocator == NULL)
    GST_WARNING ("No allocator named %s found", GST_GL_MEMORY_DMA_ALLOCATOR_NAME);

  return allocator;
}

static void
gst_gl_memory_dma_allocator_dispose (GObject * object)
{
  GstGLMemoryDMAAllocator *gl_dma_alloc= GST_GL_MEMORY_DMA_ALLOCATOR (object);

  if (gl_dma_alloc->ion_allocator) {
    GST_DEBUG ("free ion allocator");
    gst_object_unref (gl_dma_alloc->ion_allocator);
    gl_dma_alloc->ion_allocator = NULL;
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static gboolean
_gl_mem_create (GstGLMemoryDMA * gl_mem, GError ** error)
{
  GstGLContext *context = gl_mem->mem.mem.context;
  GstGLBaseMemoryAllocatorClass *alloc_class;
  guint dma_fd;

  alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class);
  if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error))
    return FALSE;

  dma_fd = gst_dmabuf_memory_get_fd ((GstMemory*) gl_mem->dma);

  gl_mem->eglimage = 
    gst_egl_image_from_dmabuf (context, dma_fd, &gl_mem->mem.info, 0,0);

  if (!gl_mem->eglimage) {
    GST_CAT_ERROR (GST_CAT_GL_DMA_MEMORY, "Can't allocate eglimage memory");
    return FALSE;
  }

  const GstGLFuncs *gl = context->gl_vtable;

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, gl_mem->mem.tex_id);
  gl->EGLImageTargetTexture2D (GL_TEXTURE_2D,
      gst_egl_image_get_image (gl_mem->eglimage));

  GST_CAT_DEBUG (GST_CAT_GL_DMA_MEMORY, "generated dma buffer %p fd %u texid %u",
      gl_mem, dma_fd, gl_mem->mem.tex_id);

  return TRUE;
}

static GstMemory *
_gl_mem_alloc (GstAllocator * allocator, gsize size,
    GstAllocationParams * params)
{
  g_warning ("Use gst_gl_base_memory_alloc () to allocate from this "
      "GstGLMemoryDMA allocator");

  return NULL;
}

static void
_gl_mem_destroy (GstGLMemoryDMA * gl_mem)
{
  GST_CAT_DEBUG (GST_CAT_GL_DMA_MEMORY, "destroy gl dma buffer %p", gl_mem);

  if (gl_mem->eglimage)
    gst_egl_image_unref (gl_mem->eglimage);
  gl_mem->eglimage = NULL;
  if (gl_mem->dma)
    gst_memory_unref (GST_MEMORY_CAST (gl_mem->dma));
  gl_mem->dma = NULL;

  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->destroy ((GstGLBaseMemory
          *) gl_mem);
}

static GstGLMemoryDMA *
_gl_mem_dma_alloc (GstGLBaseMemoryAllocator * allocator,
    GstGLVideoAllocationParams * params)
{
  GstGLMemoryDMA *mem;
  guint alloc_flags;
  gsize size;
  GstGLMemoryDMAAllocator *gl_dma_alloc = GST_GL_MEMORY_DMA_ALLOCATOR (allocator);

  alloc_flags = params->parent.alloc_flags;

  g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
      NULL);

  mem = g_new0 (GstGLMemoryDMA, 1);

  mem->params = params->parent.alloc_params;

  /* GstVideoInfo defaults to 4 b stride align for RGB/BGR but we can and want to
   * pack the buffer as tightly as possible (i.e. stride == width * bpp).
   */
  switch (params->v_info->finfo->format) {
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
      params->v_info->stride[0] = params->v_info->width * 3;
      params->v_info->size = params->v_info->stride[0] * params->v_info->height;
      break;
    default:
      break;
  }

  size = gst_gl_get_plane_data_size (params->v_info, params->valign, params->plane);
  mem->dma = gst_allocator_alloc (gl_dma_alloc->ion_allocator, size, mem->params);

  if (!mem->dma) {
    GST_CAT_ERROR (GST_CAT_GL_DMA_MEMORY, "Can't allocate dma memory size %d", size);
    g_free(mem);
    return NULL;
  }

  gst_gl_memory_init (GST_GL_MEMORY_CAST (mem), GST_ALLOCATOR_CAST (allocator),
      NULL, params->parent.context, params->target, params->tex_format,
      params->parent.alloc_params, params->v_info, params->plane,
      params->valign, params->parent.user_data, params->parent.notify);

  return mem;
}

static void
gst_gl_memory_dma_allocator_class_init (GstGLMemoryDMAAllocatorClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstGLBaseMemoryAllocatorClass *gl_base;
  GstAllocatorClass *allocator_class;

  gl_base = (GstGLBaseMemoryAllocatorClass *) klass;
  allocator_class = (GstAllocatorClass *) klass;

  gl_base->alloc = (GstGLBaseMemoryAllocatorAllocFunction) _gl_mem_dma_alloc;
  gl_base->create = (GstGLBaseMemoryAllocatorCreateFunction) _gl_mem_create;
  gl_base->destroy = (GstGLBaseMemoryAllocatorDestroyFunction) _gl_mem_destroy;
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_gl_memory_dma_allocator_dispose);

  allocator_class->alloc = _gl_mem_alloc;
}

static void
gst_gl_memory_dma_allocator_init (GstGLMemoryDMAAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_GL_MEMORY_DMA_ALLOCATOR_NAME;

  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}

gboolean
gst_is_gl_memory_dma (GstMemory * mem)
{
  return mem != NULL && mem->allocator != NULL
      && g_type_is_a (G_OBJECT_TYPE (mem->allocator),
      GST_TYPE_GL_MEMORY_DMA_ALLOCATOR);
}

static void
_finish_texture (GstGLContext * ctx, gpointer *data)
{
  GstGLFuncs *gl = ctx->gl_vtable;

  gl->Finish ();
}

GstBuffer *
gst_gl_memory_dma_buffer_to_gstbuffer (GstGLContext *ctx, GstVideoInfo * info,
    GstBuffer * glbuf)
{
  GstBuffer *buf;
  GstGLMemoryDMA *glmem;
  GstGLSyncMeta *sync_meta;

  sync_meta = gst_buffer_get_gl_sync_meta (glbuf);
  if (!sync_meta) {
    GstClockTime ts = gst_util_get_timestamp ();
    gst_gl_context_thread_add (ctx, (GstGLContextThreadFunc) _finish_texture, NULL);
    ts = gst_util_get_timestamp () - ts;
    GST_CAT_DEBUG (GST_CAT_GL_DMA_MEMORY,
        "glFinish %.2g ms", (double) ts / GST_MSECOND);
  }

  glmem = gst_buffer_peek_memory (glbuf, 0);

  /* Use GstVideoInfo from alloc time, not parsed from caps with default strides. */
  info = &glmem->mem.info;

  buf = gst_buffer_new ();
  gst_buffer_append_memory (buf, (GstMemory *) glmem->dma);
  gst_memory_ref ((GstMemory *)glmem->dma);

  gst_buffer_add_video_meta_full (buf, 0,
      GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
      GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride);
  GST_BUFFER_FLAGS (buf) = GST_BUFFER_FLAGS (glbuf);
  GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (glbuf);
  GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (glbuf);
  GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (glbuf);

  return buf;
}
