/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
 *
 * 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 <string.h>

#include "gstglbuffer.h"
#include "gstglutils.h"

/**
 * SECTION:gstglbuffer
 * @short_description: memory subclass for GL buffers
 * @see_also: #GstMemory, #GstAllocator
 *
 * GstGLBuffer is a #GstMemory subclass providing support for the mapping of
 * GL buffers.  
 *
 * Data is uploaded or downloaded from the GPU as is necessary.
 */

/* Implementation notes:
 *
 * Currently does not take into account GLES2 differences (no mapbuffer)
 */

#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))

/* compatibility definitions... */
#ifndef GL_MAP_READ_BIT
#define GL_MAP_READ_BIT 0x0001
#endif
#ifndef GL_MAP_WRITE_BIT
#define GL_MAP_WRITE_BIT 0x0002
#endif
#ifndef GL_COPY_READ_BUFFER
#define GL_COPY_READ_BUFFER 0x8F36
#endif
#ifndef GL_COPY_WRITE_BUFFER
#define GL_COPY_WRITE_BUFFER 0x8F37
#endif

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_BUFFER);
#define GST_CAT_DEFUALT GST_CAT_GL_BUFFER

static GstAllocator *_gl_buffer_allocator;

static gboolean
_gl_buffer_create (GstGLBuffer * gl_mem, GError ** error)
{
  const GstGLFuncs *gl = gl_mem->mem.context->gl_vtable;

  gl->GenBuffers (1, &gl_mem->id);
  gl->BindBuffer (gl_mem->target, gl_mem->id);
  gl->BufferData (gl_mem->target, gl_mem->mem.mem.maxsize, NULL,
      gl_mem->usage_hints);
  gl->BindBuffer (gl_mem->target, 0);

  return TRUE;
}

struct create_data
{
  GstGLBuffer *mem;
  gboolean result;
};

static void
_gl_buffer_init (GstGLBuffer * mem, GstAllocator * allocator,
    GstMemory * parent, GstGLContext * context, guint gl_target, guint gl_usage,
    GstAllocationParams * params, gsize size)
{
  mem->target = gl_target;
  mem->usage_hints = gl_usage;

  gst_gl_base_memory_init ((GstGLBaseMemory *) mem, allocator, parent, context,
      params, size, NULL, NULL);

  GST_CAT_DEBUG (GST_CAT_GL_BUFFER, "new GL buffer memory:%p size:%"
      G_GSIZE_FORMAT, mem, mem->mem.mem.maxsize);
}

static GstGLBuffer *
_gl_buffer_new (GstAllocator * allocator, GstMemory * parent,
    GstGLContext * context, guint gl_target, guint gl_usage,
    GstAllocationParams * params, gsize size)
{
  GstGLBuffer *ret = g_new0 (GstGLBuffer, 1);
  _gl_buffer_init (ret, allocator, parent, context, gl_target, gl_usage,
      params, size);

  return ret;
}

static gpointer
gst_gl_buffer_cpu_access (GstGLBuffer * mem, GstMapInfo * info, gsize size)
{
  const GstGLFuncs *gl = mem->mem.context->gl_vtable;
  gpointer data, ret;

  if (!gst_gl_base_memory_alloc_data (GST_GL_BASE_MEMORY_CAST (mem)))
    return NULL;

  ret = mem->mem.data;

  GST_CAT_LOG (GST_CAT_GL_BUFFER, "mapping id %d size %" G_GSIZE_FORMAT,
      mem->id, size);

  /* The extra data pointer indirection/memcpy is needed for coherent across
   * concurrent map()'s in both GL and CPU */
  if (GST_MEMORY_FLAG_IS_SET (mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD)
      && (info->flags & GST_MAP_GL) == 0 && (info->flags & GST_MAP_READ) != 0) {
    gl->BindBuffer (mem->target, mem->id);

    if (gl->MapBufferRange) {
      /* FIXME: optionally remove this with a flag and return the
       * glMapBufferRange pointer (requires
       * GL_ARB_buffer_storage/GL4/GL_COHERENT_BIT) */
      guint gl_map_flags = GL_MAP_READ_BIT;

      data = gl->MapBufferRange (mem->target, 0, size, gl_map_flags);

      if (data)
        memcpy (mem->mem.data, data, size);

      gl->UnmapBuffer (mem->target);
      ret = mem->mem.data;
    } else if (gl->GetBufferSubData) {
      gl->GetBufferSubData (mem->target, 0, size, mem->mem.data);
      ret = mem->mem.data;
    } else {
      ret = NULL;
    }
    gl->BindBuffer (mem->target, 0);
  }

  return ret;
}

static void
gst_gl_buffer_upload_cpu_write (GstGLBuffer * mem, GstMapInfo * info,
    gsize size)
{
  const GstGLFuncs *gl = mem->mem.context->gl_vtable;
  gpointer data;

  if (!mem->mem.data)
    /* no data pointer has been written */
    return;

  /* The extra data pointer indirection/memcpy is needed for coherent across
   * concurrent map()'s in both GL and CPU */
  /* FIXME: uploading potentially half-written data for libav pushing READWRITE
   * mapped buffers */
  if (GST_MEMORY_FLAG_IS_SET (mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)
      || (mem->mem.map_flags & GST_MAP_WRITE) != 0) {
    gl->BindBuffer (mem->target, mem->id);

    if (gl->MapBufferRange) {
      /* FIXME: optionally remove this with a flag and return the
       * glMapBufferRange pointer (requires
       * GL_ARB_buffer_storage/GL4/GL_COHERENT_BIT) */
      guint gl_map_flags = GL_MAP_WRITE_BIT;

      data = gl->MapBufferRange (mem->target, 0, size, gl_map_flags);

      if (data)
        memcpy (data, mem->mem.data, size);

      gl->UnmapBuffer (mem->target);
    } else if (gl->BufferSubData) {
      gl->BufferSubData (mem->target, 0, size, mem->mem.data);
    }
    gl->BindBuffer (mem->target, 0);
  }
}

static gpointer
_gl_buffer_map (GstGLBuffer * mem, GstMapInfo * info, gsize size)
{
  const GstGLFuncs *gl = mem->mem.context->gl_vtable;

  if ((info->flags & GST_MAP_GL) != 0) {
    if (info->flags & GST_MAP_READ) {
      gst_gl_buffer_upload_cpu_write (mem, info, size);
    }
    gl->BindBuffer (mem->target, mem->id);
    return &mem->id;
  } else {
    return gst_gl_buffer_cpu_access (mem, info, size);
  }

  return NULL;
}

static void
_gl_buffer_unmap (GstGLBuffer * mem, GstMapInfo * info)
{
  const GstGLFuncs *gl = mem->mem.context->gl_vtable;

  if ((info->flags & GST_MAP_GL) != 0) {
    gl->BindBuffer (mem->target, 0);
  }
  /* XXX: optimistically transfer data */
}

/**
 * gst_gl_buffer_copy_buffer_sub_data:
 * @src: the source #GstGLBuffer
 * @dest: the destination #GstGLBuffer
 * @offset: the offset to copy from @src
 * @size: the size to copy from @src
 *
 * Copies @src into @dest using glCopyBufferSubData().
 *
 * Returns: whether the copy operation succeeded
 *
 * Since: 1.8
 */
static gboolean
gst_gl_buffer_copy_buffer_sub_data (GstGLBuffer * src,
    GstGLBuffer * dest, gssize offset, gssize size)
{
  const GstGLFuncs *gl = src->mem.context->gl_vtable;
  GstMapInfo sinfo, dinfo;

  if (!gl->CopyBufferSubData)
    /* This is GL(ES) 3.0+ only */
    return FALSE;

  if (!gst_memory_map ((GstMemory *) src, &sinfo, GST_MAP_READ | GST_MAP_GL)) {
    GST_CAT_WARNING (GST_CAT_GL_BUFFER,
        "failed to read map source memory %p", src);
    return FALSE;
  }

  if (!gst_memory_map ((GstMemory *) dest, &dinfo, GST_MAP_WRITE | GST_MAP_GL)) {
    GST_CAT_WARNING (GST_CAT_GL_BUFFER,
        "failed to write map destination memory %p", dest);
    gst_memory_unmap ((GstMemory *) src, &sinfo);
    return FALSE;
  }

  gl->BindBuffer (GL_COPY_READ_BUFFER, src->id);
  gl->BindBuffer (GL_COPY_WRITE_BUFFER, dest->id);
  gl->CopyBufferSubData (GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
      offset, 0, size);

  gst_memory_unmap ((GstMemory *) src, &sinfo);
  gst_memory_unmap ((GstMemory *) dest, &dinfo);

  return TRUE;
}

static GstGLBuffer *
_gl_buffer_copy (GstGLBuffer * src, gssize offset, gssize size)
{
  GstAllocator *allocator = src->mem.mem.allocator;
  GstAllocationParams params = { 0, src->mem.mem.align, 0, 0 };
  GstGLBuffer *dest = NULL;

  dest = _gl_buffer_new (allocator, NULL, src->mem.context,
      src->target, src->usage_hints, &params, src->mem.mem.maxsize);

  /* If not doing a full copy, then copy to sysmem, the 2D represention of the
   * texture would become wrong */
  if (GST_MEMORY_FLAG_IS_SET (src, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) {
    if (!gst_gl_base_memory_memcpy (GST_GL_BASE_MEMORY_CAST (src),
            GST_GL_BASE_MEMORY_CAST (dest), offset, size)) {
      GST_CAT_WARNING (GST_CAT_GL_BUFFER, "Could not copy GL Buffer");
      gst_memory_unref (GST_MEMORY_CAST (dest));
      dest = NULL;
    }
  } else {
    if (!gst_gl_buffer_copy_buffer_sub_data (src, dest, offset, size)) {
      if (!gst_gl_base_memory_memcpy (GST_GL_BASE_MEMORY_CAST (src),
              GST_GL_BASE_MEMORY_CAST (dest), offset, size)) {
        GST_CAT_WARNING (GST_CAT_GL_BUFFER, "Could not copy GL Buffer");
        gst_memory_unref (GST_MEMORY_CAST (dest));
        dest = NULL;
      }
    }
  }

  return dest;
}

static GstMemory *
_gl_buffer_alloc (GstAllocator * allocator, gsize size,
    GstAllocationParams * params)
{
  g_critical ("Need to use gst_gl_base_memory_alloc() to allocate from "
      "this allocator");

  return NULL;
}

static void
_gl_buffer_destroy (GstGLBuffer * mem)
{
  const GstGLFuncs *gl = mem->mem.context->gl_vtable;

  gl->DeleteBuffers (1, &mem->id);
}

static void
_gst_gl_buffer_allocation_params_copy_data (GstGLBufferAllocationParams * src,
    GstGLBufferAllocationParams * dest)
{
  memset (dest, 0, sizeof (*dest));

  gst_gl_allocation_params_copy_data (&src->parent, &dest->parent);

  dest->gl_target = src->gl_target;
  dest->gl_usage = src->gl_usage;
}

static void
_gst_gl_buffer_allocation_params_free_data (GstGLBufferAllocationParams *
    params)
{
  gst_gl_allocation_params_free_data (&params->parent);
}

/**
 * gst_gl_buffer_allocation_params_new:
 * @context: a #GstGLContext
 * @alloc_size: the size in bytes to allocate
 * @alloc_params: (allow-none): the #GstAllocationParams for @tex_id
 * @gl_target: the OpenGL target to allocate
 * @gl_usage: the OpenGL usage hint to allocate with
 *
 * Returns: a new #GstGLBufferAllocationParams for allocating OpenGL buffer
 *          objects
 *
 * Since: 1.8
 */
GstGLBufferAllocationParams *
gst_gl_buffer_allocation_params_new (GstGLContext * context, gsize alloc_size,
    GstAllocationParams * alloc_params, guint gl_target, guint gl_usage)
{
  GstGLBufferAllocationParams *params;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
  g_return_val_if_fail (alloc_size > 0, NULL);

  params = g_new0 (GstGLBufferAllocationParams, 1);

  if (!gst_gl_allocation_params_init (&params->parent, sizeof (*params),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_BUFFER |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC,
          (GstGLAllocationParamsCopyFunc)
          _gst_gl_buffer_allocation_params_copy_data,
          (GstGLAllocationParamsFreeFunc)
          _gst_gl_buffer_allocation_params_free_data, context, alloc_size,
          alloc_params, NULL, 0, NULL, NULL)) {
    g_free (params);
    return NULL;
  }

  params->gl_target = gl_target;
  params->gl_usage = gl_usage;

  return params;
}

static GstGLBuffer *
_gl_buffer_alloc_mem (GstGLBufferAllocator * allocator,
    GstGLBufferAllocationParams * params)
{
  guint alloc_flags = params->parent.alloc_flags;

  g_return_val_if_fail (alloc_flags &
      GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_BUFFER, NULL);
  g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC,
      NULL);

  return _gl_buffer_new (GST_ALLOCATOR (allocator), NULL,
      params->parent.context, params->gl_target, params->gl_usage,
      params->parent.alloc_params, params->parent.alloc_size);
}

G_DEFINE_TYPE (GstGLBufferAllocator, gst_gl_buffer_allocator,
    GST_TYPE_GL_BASE_MEMORY_ALLOCATOR);

static void
gst_gl_buffer_allocator_class_init (GstGLBufferAllocatorClass * klass)
{
  GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
  GstGLBaseMemoryAllocatorClass *gl_base;

  gl_base = (GstGLBaseMemoryAllocatorClass *) klass;

  gl_base->alloc = (GstGLBaseMemoryAllocatorAllocFunction) _gl_buffer_alloc_mem;
  gl_base->create = (GstGLBaseMemoryAllocatorCreateFunction) _gl_buffer_create;
  gl_base->map = (GstGLBaseMemoryAllocatorMapFunction) _gl_buffer_map;
  gl_base->unmap = (GstGLBaseMemoryAllocatorUnmapFunction) _gl_buffer_unmap;
  gl_base->copy = (GstGLBaseMemoryAllocatorCopyFunction) _gl_buffer_copy;
  gl_base->destroy =
      (GstGLBaseMemoryAllocatorDestroyFunction) _gl_buffer_destroy;

  allocator_class->alloc = _gl_buffer_alloc;
}

static void
gst_gl_buffer_allocator_init (GstGLBufferAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_GL_BUFFER_ALLOCATOR_NAME;

  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}

/**
 * gst_gl_buffer_init_once:
 *
 * Initializes the GL Buffer allocator. It is safe to call this function
 * multiple times.  This must be called before any other #GstGLBuffer operation.
 *
 * Since: 1.8
 */
void
gst_gl_buffer_init_once (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    gst_gl_base_memory_init_once ();

    GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_BUFFER, "glbuffer", 0, "OpenGL Buffer");

    _gl_buffer_allocator =
        g_object_new (gst_gl_buffer_allocator_get_type (), NULL);

    /* The allocator is never unreffed */
    GST_OBJECT_FLAG_SET (_gl_buffer_allocator, GST_OBJECT_FLAG_MAY_BE_LEAKED);

    gst_allocator_register (GST_GL_BUFFER_ALLOCATOR_NAME,
        gst_object_ref (_gl_buffer_allocator));
    g_once_init_leave (&_init, 1);
  }
}

/**
 * gst_is_gl_buffer:
 * @mem:a #GstMemory
 * 
 * Returns: whether the memory at @mem is a #GstGLBuffer
 *
 * Since: 1.8
 */
gboolean
gst_is_gl_buffer (GstMemory * mem)
{
  return mem != NULL && mem->allocator != NULL &&
      g_type_is_a (G_OBJECT_TYPE (mem->allocator),
      GST_TYPE_GL_BUFFER_ALLOCATOR);
}
