/*
 * 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 */
}

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

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.
 */
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);

    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
 */
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);
}
