/*
 * GStreamer
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * 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 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 Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

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

#include "gstglphymemory.h"
#include "gstglfuncs.h"
#include <g2d.h>

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_PHY_MEMORY);
#define GST_CAT_DEFAULT GST_CAT_GL_PHY_MEMORY

#ifndef GL_BGRA_EXT
#define GL_BGRA_EXT                                             0x80E1
#endif
#ifndef GL_VIV_YV12
#define GL_VIV_YV12                                             0x8FC0
#endif
#ifndef GL_VIV_NV12
#define GL_VIV_NV12                                             0x8FC1
#endif
#ifndef GL_VIV_YUY2
#define GL_VIV_YUY2                                             0x8FC2
#endif
#ifndef GL_VIV_UYVY
#define GL_VIV_UYVY                                             0x8FC3
#endif
#ifndef GL_VIV_NV21
#define GL_VIV_NV21                                             0x8FC4
#endif
#ifndef GL_VIV_I420
#define GL_VIV_I420                                             0x8FC5
#endif

typedef void (*TexDirectVIVMap) (GLenum Target, GLsizei Width, GLsizei Height,
    GLenum Format, GLvoid ** Logical, const GLuint * Physical);
typedef void (*TexDirectInvalidateVIV) (GLenum Target);
static TexDirectVIVMap pTexDirectVIVMap = NULL;
static TexDirectInvalidateVIV pTexDirectInvalidateVIV = NULL;

typedef struct {
  guint tex_id;
  guint w;
  guint h;
  guint fmt;
  void *vaddr;
  guint paddr;
  gboolean ret;
}DirectVIVData;

typedef struct _GstPhyMemAllocator GstPhyMemAllocator;
typedef struct _GstPhyMemAllocatorClass GstPhyMemAllocatorClass;

struct _GstPhyMemAllocator
{
  GstAllocatorPhyMem parent;
};

struct _GstPhyMemAllocatorClass
{
  GstAllocatorPhyMemClass parent_class;
};

GType gst_phy_mem_allocator_get_type (void);
G_DEFINE_TYPE (GstPhyMemAllocator, gst_phy_mem_allocator, GST_TYPE_ALLOCATOR_PHYMEM);

static int
alloc_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk)
{
  struct g2d_buf *pbuf = NULL;

  memblk->size = PAGE_ALIGN(memblk->size);

  pbuf = g2d_alloc (memblk->size, 0);
  if (!pbuf) {
    GST_ERROR("G2D allocate %u bytes memory failed: %s",
        memblk->size, strerror(errno));
    return -1;
  }

  memblk->vaddr = (guchar*) pbuf->buf_vaddr;
  memblk->paddr = (guchar*) pbuf->buf_paddr;
  memblk->user_data = (gpointer) pbuf;
  GST_DEBUG("G2D allocated memory (%p)", memblk->paddr);

  return 1;
}

static int
free_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk)
{
  GST_DEBUG("G2D free memory (%p)", memblk->paddr);
  gint ret = g2d_free ((struct g2d_buf*)(memblk->user_data));
  memblk->user_data = NULL;
  memblk->vaddr = NULL;
  memblk->paddr = NULL;
  memblk->size = 0;

  return ret;
}

static void
gst_phy_mem_allocator_class_init (GstPhyMemAllocatorClass * klass)
{
  GstAllocatorPhyMemClass *phy_allocator_klass = (GstAllocatorPhyMemClass *) klass;

  phy_allocator_klass->alloc_phymem = alloc_phymem;
  phy_allocator_klass->free_phymem = free_phymem;
}

static void
gst_phy_mem_allocator_init (GstPhyMemAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_GL_PHY_MEM_ALLOCATOR;
}


static gpointer
gst_phy_mem_allocator_init_instance (gpointer data)
{
  GstAllocator *allocator =
      g_object_new (gst_phy_mem_allocator_get_type (), NULL);

  GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_PHY_MEMORY, "glphymemory", 0,
      "GLPhysical Memory");

  gst_allocator_register (GST_GL_PHY_MEM_ALLOCATOR, gst_object_ref (allocator));

  return allocator;
}

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

  gl->Finish ();
}

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

  GST_DEBUG ("viv direct bind, tex_id %d, fmt: %d, res: (%dx%d)", data->tex_id, data->fmt, data->w, data->h);
  GST_DEBUG ("Physical memory buffer, vaddr: %p, paddr: %p", data->vaddr, data->paddr);

  gl->BindTexture (GL_TEXTURE_2D, data->tex_id);
  pTexDirectVIVMap (GL_TEXTURE_2D, data->w, data->h, data->fmt, &data->vaddr, &data->paddr);
  pTexDirectInvalidateVIV (GL_TEXTURE_2D);
  data->ret = TRUE;
}

static GLenum
_directviv_video_format_to_gl_format (GstVideoFormat format)
{
  switch (format) {
    case GST_VIDEO_FORMAT_I420:
      return GL_VIV_I420;
    case GST_VIDEO_FORMAT_YV12:
      return GL_VIV_YV12;
    case GST_VIDEO_FORMAT_NV12:
      return GL_VIV_NV12;
    case GST_VIDEO_FORMAT_NV21:
      return GL_VIV_NV21;
    case GST_VIDEO_FORMAT_YUY2:
      return GL_VIV_YUY2;
    case GST_VIDEO_FORMAT_UYVY:
      return GL_VIV_UYVY;
    case GST_VIDEO_FORMAT_RGB16:
      return GL_RGB565;
    case GST_VIDEO_FORMAT_RGBA:
      return GL_RGBA;
    case GST_VIDEO_FORMAT_BGRA:
      return GL_BGRA_EXT;
    case GST_VIDEO_FORMAT_RGBx:
      return GL_RGBA;
    case GST_VIDEO_FORMAT_BGRx:
      return GL_BGRA_EXT;
    default:
      return 0;
  }
}

static void
gst_gl_phy_mem_destroy (GstMemory *mem)
{
  gst_memory_unref (mem);
}


GstAllocator *
gst_phy_mem_allocator_obtain (void)
{
  static GOnce once = G_ONCE_INIT;

  g_once (&once, gst_phy_mem_allocator_init_instance, NULL);

  g_return_val_if_fail (once.retval != NULL, NULL);

  return (GstAllocator *) (g_object_ref (once.retval));
}

gboolean
gst_is_gl_physical_memory (GstMemory * mem)
{
  GstGLBaseMemory *glmem;
  g_return_val_if_fail (gst_is_gl_memory (mem), FALSE);

  glmem = (GstGLBaseMemory*) mem;

  if (glmem->user_data
      && GST_IS_MINI_OBJECT_TYPE(glmem->user_data, GST_TYPE_MEMORY))
    return gst_memory_is_type ((GstMemory*)glmem->user_data, GST_GL_PHY_MEM_ALLOCATOR);
  else
    return FALSE;
}

gboolean
gst_is_gl_physical_memory_supported_fmt (GstVideoInfo * info)
{
  if (GST_VIDEO_INFO_IS_RGB(info)
      && _directviv_video_format_to_gl_format (GST_VIDEO_INFO_FORMAT (info))) {
    return TRUE;
  }
  else
    return FALSE;
}

gboolean
gst_gl_physical_memory_setup_buffer (GstAllocator * allocator, GstBuffer *buffer, 
    GstGLVideoAllocationParams * params)
{
  GstGLBaseMemoryAllocator *gl_alloc;
  GstMemory *mem = NULL;
  PhyMemBlock *memblk = NULL;
  GstGLMemory *glmem = NULL;
  gsize size;

  GstVideoInfo * info = params->v_info;
  GstVideoAlignment * valign = params->valign;

  GST_DEBUG ("glphymemory setup buffer format %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
  
  if (!gst_is_gl_physical_memory_supported_fmt (info)) {
    GST_DEBUG ("Not support format.");
    return FALSE;
  }

  if(!pTexDirectVIVMap || !pTexDirectInvalidateVIV) {
    pTexDirectVIVMap =
      gst_gl_context_get_proc_address (params->parent.context, "glTexDirectVIVMap");
    pTexDirectInvalidateVIV =
      gst_gl_context_get_proc_address (params->parent.context, "glTexDirectInvalidateVIV");
  }

  if(!pTexDirectVIVMap || !pTexDirectInvalidateVIV) {
    GST_DEBUG ("Load directviv functions failed.");
    return FALSE;
  }

  size = gst_gl_get_plane_data_size (info, valign, 0);
  mem = gst_allocator_alloc (allocator, size, params->parent.alloc_params);
  if (!mem) {
    GST_DEBUG ("Can't allocate physical memory size %d", size);
    return FALSE;
  }

  memblk = gst_memory_query_phymem_block (mem);
  if (!memblk) {
    GST_ERROR("Can't find physic memory block.");
    return FALSE;
  }

  gl_alloc =
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_gl_memory_allocator_get_default
      (params->parent.context));

  params->plane = 0;
  params->parent.user_data = mem;
  params->parent.notify = gst_gl_phy_mem_destroy;
  params->tex_format =
    gst_gl_format_from_video_info(params->parent.context, info, 0);

  glmem = (GstGLMemory *)gst_gl_base_memory_alloc (gl_alloc, (GstGLAllocationParams *) params);
  gst_object_unref (gl_alloc);
  if (!glmem) {
    GST_ERROR("Can't get gl memory.");
    return FALSE;
  }

  gst_buffer_append_memory (buffer, (GstMemory *) glmem);

  gst_buffer_add_video_meta_full (buffer, 0,
      GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
      GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride);

  guint viv_fmt = _directviv_video_format_to_gl_format (GST_VIDEO_INFO_FORMAT (info));

  DirectVIVData directvivdata = 
  {
    glmem->tex_id,
    GST_VIDEO_INFO_WIDTH (info),
    GST_VIDEO_INFO_HEIGHT (info),
    viv_fmt,
    memblk->vaddr,
    memblk->paddr,
    FALSE
  };

  gst_gl_context_thread_add (params->parent.context,
      _do_viv_direct_tex_bind_mem, &directvivdata);

  return directvivdata.ret;
}

GstBuffer *
gst_gl_phymem_buffer_to_gstbuffer (GstGLContext * ctx,
    GstVideoInfo * info, GstBuffer *glbuf)
{
  GstBuffer *buf;
  GstGLBaseMemory *glmem;

  gst_gl_context_thread_add (ctx, (GstGLContextThreadFunc) _finish_texture, NULL);

  glmem = gst_buffer_peek_memory (glbuf, 0);

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

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

