/*
 * 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 "gstglrenderbuffer.h"

#include "gstglcontext.h"
#include "gstglfuncs.h"
#include "gstglmemory.h"

/**
 * SECTION:gstglrenderbuffer
 * @title: GstGLRenderBuffer
 * @short_description: memory subclass for GL renderbuffer objects
 * @see_also: #GstMemory, #GstAllocator
 *
 * GstGLRenderbuffer is a #GstGLBaseMemory subclass providing support for
 * OpenGL renderbuffers.
 *
 * #GstGLRenderbuffer is created or wrapped through gst_gl_base_memory_alloc()
 * with #GstGLRenderbufferAllocationParams.
 *
 * Since: 1.10
 */

#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))

static GstAllocator *_gl_renderbuffer_allocator;

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_RENDERBUFFER);
#define GST_CAT_DEFAULT GST_CAT_GL_RENDERBUFFER

G_DEFINE_TYPE (GstGLRenderbufferAllocator, gst_gl_renderbuffer_allocator,
    GST_TYPE_GL_BASE_MEMORY_ALLOCATOR);

static guint
_new_renderbuffer (GstGLContext * context, guint format, guint width,
    guint height)
{
  const GstGLFuncs *gl = context->gl_vtable;
  guint rbo_id;

  gl->GenRenderbuffers (1, &rbo_id);
  gl->BindRenderbuffer (GL_RENDERBUFFER, rbo_id);

  gl->RenderbufferStorage (GL_RENDERBUFFER, format, width, height);

  gl->BindRenderbuffer (GL_RENDERBUFFER, 0);

  return rbo_id;
}

static gboolean
_gl_rbo_create (GstGLRenderbuffer * gl_mem, GError ** error)
{
  if (!gl_mem->renderbuffer_wrapped) {
    GstGLContext *context = gl_mem->mem.context;
    GLenum internal_format;
    GLenum tex_format;
    GLenum renderbuffer_type;

    tex_format = gl_mem->renderbuffer_format;
    renderbuffer_type = GL_UNSIGNED_BYTE;
    if (gl_mem->renderbuffer_format == GST_GL_RGB565) {
      tex_format = GST_GL_RGB;
      renderbuffer_type = GL_UNSIGNED_SHORT_5_6_5;
    }

    internal_format =
        gst_gl_sized_gl_format_from_gl_format_type (context, tex_format,
        renderbuffer_type);

    gl_mem->renderbuffer_id =
        _new_renderbuffer (context, internal_format,
        gst_gl_renderbuffer_get_width (gl_mem),
        gst_gl_renderbuffer_get_height (gl_mem));

    GST_CAT_TRACE (GST_CAT_GL_RENDERBUFFER, "Generating renderbuffer id:%u "
        "format:%u dimensions:%ux%u", gl_mem->renderbuffer_id, internal_format,
        gst_gl_renderbuffer_get_width (gl_mem),
        gst_gl_renderbuffer_get_height (gl_mem));
  }

  return TRUE;
}

static void
gst_gl_renderbuffer_init (GstGLRenderbuffer * mem, GstAllocator * allocator,
    GstMemory * parent, GstGLContext * context,
    GstGLFormat renderbuffer_format, GstAllocationParams * params,
    guint width, guint height, gpointer user_data, GDestroyNotify notify)
{
  gsize size;
  guint tex_type;

  tex_type = GL_UNSIGNED_BYTE;
  if (renderbuffer_format == GST_GL_RGB565)
    tex_type = GL_UNSIGNED_SHORT_5_6_5;
  size =
      gst_gl_format_type_n_bytes (renderbuffer_format,
      tex_type) * width * height;

  mem->renderbuffer_format = renderbuffer_format;
  mem->width = width;
  mem->height = height;

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

  GST_CAT_DEBUG (GST_CAT_GL_RENDERBUFFER, "new GL renderbuffer context:%"
      GST_PTR_FORMAT " memory:%p format:%u dimensions:%ux%u ", context, mem,
      mem->renderbuffer_format, gst_gl_renderbuffer_get_width (mem),
      gst_gl_renderbuffer_get_height (mem));
}

static gpointer
_gl_rbo_map (GstGLRenderbuffer * gl_mem, GstMapInfo * info, gsize maxsize)
{
  GST_CAT_WARNING (GST_CAT_GL_RENDERBUFFER, "Renderbuffer's cannot be mapped");

  return NULL;
}

static void
_gl_rbo_unmap (GstGLRenderbuffer * gl_mem, GstMapInfo * info)
{
}

static GstMemory *
_gl_rbo_copy (GstGLRenderbuffer * src, gssize offset, gssize size)
{
  GST_CAT_WARNING (GST_CAT_GL_RENDERBUFFER, "Renderbuffer's cannot be copied");

  return NULL;
}

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

  return NULL;
}

static void
_gl_rbo_destroy (GstGLRenderbuffer * gl_mem)
{
  const GstGLFuncs *gl = gl_mem->mem.context->gl_vtable;

  if (gl_mem->renderbuffer_id && !gl_mem->renderbuffer_wrapped)
    gl->DeleteRenderbuffers (1, &gl_mem->renderbuffer_id);
}

static GstGLRenderbuffer *
_default_gl_rbo_alloc (GstGLRenderbufferAllocator * allocator,
    GstGLRenderbufferAllocationParams * params)
{
  guint alloc_flags = params->parent.alloc_flags;
  GstGLRenderbuffer *mem;

  g_return_val_if_fail ((alloc_flags &
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) == 0, NULL);

  mem = g_new0 (GstGLRenderbuffer, 1);

  if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
    mem->renderbuffer_id = GPOINTER_TO_UINT (params->parent.gl_handle);
    mem->renderbuffer_wrapped = TRUE;
  }

  gst_gl_renderbuffer_init (mem, GST_ALLOCATOR_CAST (allocator), NULL,
      params->parent.context, params->renderbuffer_format,
      params->parent.alloc_params, params->width, params->height,
      params->parent.user_data, params->parent.notify);

  return mem;
}

static void
gst_gl_renderbuffer_allocator_class_init (GstGLRenderbufferAllocatorClass *
    klass)
{
  GstGLBaseMemoryAllocatorClass *gl_base;
  GstAllocatorClass *allocator_class;

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

  gl_base->alloc =
      (GstGLBaseMemoryAllocatorAllocFunction) _default_gl_rbo_alloc;
  gl_base->create = (GstGLBaseMemoryAllocatorCreateFunction) _gl_rbo_create;
  gl_base->destroy = (GstGLBaseMemoryAllocatorDestroyFunction) _gl_rbo_destroy;

  allocator_class->alloc = _gl_rbo_alloc;
}

static void
gst_gl_renderbuffer_allocator_init (GstGLRenderbufferAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_GL_RENDERBUFFER_ALLOCATOR_NAME;

  alloc->mem_map_full = (GstMemoryMapFullFunction) _gl_rbo_map;
  alloc->mem_unmap_full = (GstMemoryUnmapFullFunction) _gl_rbo_unmap;
  alloc->mem_copy = (GstMemoryCopyFunction) _gl_rbo_copy;

  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}

/**
 * gst_gl_renderbuffer_get_width:
 * @gl_mem: a #GstGLRenderbuffer
 *
 * Returns: the configured width of @gl_mem
 *
 * Since: 1.10
 */
gint
gst_gl_renderbuffer_get_width (GstGLRenderbuffer * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_renderbuffer ((GstMemory *) gl_mem), 0);

  return gl_mem->width;
}

/**
 * gst_gl_renderbuffer_get_height:
 * @gl_mem: a #GstGLRenderbuffer
 *
 * Returns: the configured height of @gl_mem
 *
 * Since: 1.10
 */
gint
gst_gl_renderbuffer_get_height (GstGLRenderbuffer * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_renderbuffer ((GstMemory *) gl_mem), 0);

  return gl_mem->height;
}

/**
 * gst_gl_renderbuffer_get_format:
 * @gl_mem: a #GstGLRenderbuffer
 *
 * Returns: the #GstGLFormat of @gl_mem
 *
 * Since: 1.12
 */
GstGLFormat
gst_gl_renderbuffer_get_format (GstGLRenderbuffer * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_renderbuffer ((GstMemory *) gl_mem), 0);

  return gl_mem->renderbuffer_format;
}

/**
 * gst_gl_renderbuffer_get_id:
 * @gl_mem: a #GstGLRenderbuffer
 *
 * Returns: the OpenGL renderbuffer handle of @gl_mem
 *
 * Since: 1.10
 */
guint
gst_gl_renderbuffer_get_id (GstGLRenderbuffer * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_renderbuffer ((GstMemory *) gl_mem), 0);

  return gl_mem->renderbuffer_id;
}

/**
 * gst_gl_renderbuffer_init_once:
 *
 * Initializes the GL Base Texture allocator. It is safe to call this function
 * multiple times.  This must be called before any other GstGLRenderbuffer operation.
 *
 * Since: 1.10
 */
void
gst_gl_renderbuffer_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_RENDERBUFFER, "glrenderbuffermemory", 0,
        "OpenGL Renderbuffer memory");

    _gl_renderbuffer_allocator =
        g_object_new (GST_TYPE_GL_RENDERBUFFER_ALLOCATOR, NULL);
    gst_object_ref_sink (_gl_renderbuffer_allocator);
    GST_OBJECT_FLAG_SET (_gl_renderbuffer_allocator,
        GST_OBJECT_FLAG_MAY_BE_LEAKED);

    gst_allocator_register (GST_GL_RENDERBUFFER_ALLOCATOR_NAME,
        _gl_renderbuffer_allocator);

    g_once_init_leave (&_init, 1);
  }
}

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

G_DEFINE_BOXED_TYPE (GstGLRenderbufferAllocationParams,
    gst_gl_renderbuffer_allocation_params,
    (GBoxedCopyFunc) gst_gl_allocation_params_copy,
    (GBoxedFreeFunc) gst_gl_allocation_params_free);

static void
_gst_gl_rb_alloc_params_free_data (GstGLRenderbufferAllocationParams * params)
{
  gst_gl_allocation_params_free_data (&params->parent);
}

static void
_gst_gl_rb_alloc_params_copy_data (GstGLRenderbufferAllocationParams * src_vid,
    GstGLRenderbufferAllocationParams * dest_vid)
{
  GstGLAllocationParams *src = (GstGLAllocationParams *) src_vid;
  GstGLAllocationParams *dest = (GstGLAllocationParams *) dest_vid;

  gst_gl_allocation_params_copy_data (src, dest);

  dest_vid->renderbuffer_format = src_vid->renderbuffer_format;
  dest_vid->width = src_vid->width;
  dest_vid->height = src_vid->height;
}

static gboolean
    _gst_gl_renderbuffer_allocation_params_init_full
    (GstGLRenderbufferAllocationParams * params, gsize struct_size,
    guint alloc_flags, GstGLAllocationParamsCopyFunc copy,
    GstGLAllocationParamsFreeFunc free, GstGLContext * context,
    GstAllocationParams * alloc_params, guint width, guint height,
    GstGLFormat renderbuffer_format, gpointer wrapped_data,
    gpointer gl_handle, gpointer user_data, GDestroyNotify notify)
{
  g_return_val_if_fail (params != NULL, FALSE);
  g_return_val_if_fail (copy != NULL, FALSE);
  g_return_val_if_fail (free != NULL, FALSE);
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  memset (params, 0, sizeof (*params));

  if (!gst_gl_allocation_params_init ((GstGLAllocationParams *) params,
          struct_size, alloc_flags, copy, free, context, 0, alloc_params,
          wrapped_data, gl_handle, user_data, notify))
    return FALSE;

  params->renderbuffer_format = renderbuffer_format;
  params->width = width;
  params->height = height;

  return TRUE;
}

/**
 * gst_gl_renderbuffer_allocation_params_new:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for sysmem mappings of the texture
 * @width: the width of the renderbuffer
 * @height: the height of the renderbuffer
 * @renderbuffer_format: the #GstGLFormat for the created textures
 *
 * Returns: a new #GstGLRenderbufferAllocationParams for allocating #GstGLRenderbuffer's
 *
 * Since: 1.10
 */
GstGLRenderbufferAllocationParams *
gst_gl_renderbuffer_allocation_params_new (GstGLContext * context,
    GstAllocationParams * alloc_params, GstGLFormat renderbuffer_format,
    guint width, guint height)
{
  GstGLRenderbufferAllocationParams *params =
      g_new0 (GstGLRenderbufferAllocationParams, 1);

  if (!_gst_gl_renderbuffer_allocation_params_init_full (params,
          sizeof (GstGLRenderbufferAllocationParams),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
          (GstGLAllocationParamsCopyFunc) _gst_gl_rb_alloc_params_copy_data,
          (GstGLAllocationParamsFreeFunc) _gst_gl_rb_alloc_params_free_data,
          context, alloc_params, width, height, renderbuffer_format, NULL, 0,
          NULL, NULL)) {
    g_free (params);
    return NULL;
  }

  return params;
}

/**
 * gst_gl_renderbuffer_allocation_params_new_wrapped:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for @tex_id
 * @width: the width of the renderbuffer
 * @height: the height of the renderbuffer
 * @renderbuffer_format: the #GstGLFormat for @tex_id
 * @gl_handle: the GL handle to wrap
 * @user_data: (allow-none): user data to call @notify with
 * @notify: (allow-none): a #GDestroyNotify
 *
 * Returns: a new #GstGLRenderbufferAllocationParams for wrapping @gl_handle as a
 *          renderbuffer
 *
 * Since: 1.10
 */
GstGLRenderbufferAllocationParams *
gst_gl_renderbuffer_allocation_params_new_wrapped (GstGLContext * context,
    GstAllocationParams * alloc_params, GstGLFormat renderbuffer_format,
    guint width, guint height, gpointer gl_handle, gpointer user_data,
    GDestroyNotify notify)
{
  GstGLRenderbufferAllocationParams *params =
      g_new0 (GstGLRenderbufferAllocationParams, 1);

  if (!_gst_gl_renderbuffer_allocation_params_init_full (params,
          sizeof (GstGLRenderbufferAllocationParams),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
          (GstGLAllocationParamsCopyFunc) _gst_gl_rb_alloc_params_copy_data,
          (GstGLAllocationParamsFreeFunc) _gst_gl_rb_alloc_params_free_data,
          context, alloc_params, width, height, renderbuffer_format, NULL,
          gl_handle, user_data, notify)) {
    g_free (params);
    return NULL;
  }

  return params;
}
