/*
 * 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 <gst/video/video.h>

#include <gst/gl/gstglbasememory.h>
#include <gst/gl/gstglmemory.h>

/**
 * SECTION:gstglmemory
 * @short_description: memory subclass for GL textures
 * @see_also: #GstMemory, #GstAllocator, #GstGLBufferPool
 *
 * GstGLMemory is a #GstGLBaseMemory subclass providing support for the mapping of
 * OpenGL textures.  
 *
 * #GstGLMemory is created or wrapped through gst_gl_base_memory_alloc()
 * with #GstGLVideoAllocationParams.
 *
 * Data is uploaded or downloaded from the GPU as is necessary.
 */

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

#define GL_MEM_WIDTH(gl_mem) _get_plane_width (&gl_mem->info, gl_mem->plane)
#define GL_MEM_HEIGHT(gl_mem) _get_plane_height (&gl_mem->info, gl_mem->plane)
#define GL_MEM_STRIDE(gl_mem) GST_VIDEO_INFO_PLANE_STRIDE (&gl_mem->info, gl_mem->plane)

static GstAllocator *_gl_memory_allocator;

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY);
#define GST_CAT_DEFAULT GST_CAT_GL_MEMORY

/* compatability definitions... */
#ifndef GL_UNPACK_ROW_LENGTH
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#endif

#ifndef GL_TEXTURE_RECTANGLE
#define GL_TEXTURE_RECTANGLE 0x84F5
#endif
#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif

G_DEFINE_TYPE (GstGLMemoryAllocator, gst_gl_memory_allocator,
    GST_TYPE_GL_BASE_MEMORY_ALLOCATOR);

typedef struct
{
  /* in */
  GstGLMemory *src;
  GstVideoGLTextureType out_format;
  guint out_width, out_height;
  GstGLTextureTarget tex_target;
  GstVideoGLTextureType tex_type;
  /* inout */
  guint tex_id;
  /* out */
  gboolean result;
} GstGLMemoryCopyParams;

static inline guint
_get_plane_width (GstVideoInfo * info, guint plane)
{
  if (GST_VIDEO_INFO_IS_YUV (info))
    /* For now component width and plane width are the same and the
     * plane-component mapping matches
     */
    return GST_VIDEO_INFO_COMP_WIDTH (info, plane);
  else                          /* RGB, GRAY */
    return GST_VIDEO_INFO_WIDTH (info);
}

static inline guint
_get_plane_height (GstVideoInfo * info, guint plane)
{
  if (GST_VIDEO_INFO_IS_YUV (info))
    /* For now component width and plane width are the same and the
     * plane-component mapping matches
     */
    return GST_VIDEO_INFO_COMP_HEIGHT (info, plane);
  else                          /* RGB, GRAY */
    return GST_VIDEO_INFO_HEIGHT (info);
}

static inline void
_calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
{
  guint n_gl_bytes;

  gl_mem->tex_scaling[0] = 1.0f;
  gl_mem->tex_scaling[1] = 1.0f;
  gl_mem->unpack_length = 1;
  gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);

  n_gl_bytes = gst_gl_texture_type_n_bytes (gl_mem->tex_type);
  if (n_gl_bytes == 0) {
    GST_ERROR ("Unsupported texture type %d", gl_mem->tex_type);
    return;
  }

  if (USING_OPENGL (context) || USING_GLES3 (context)
      || USING_OPENGL3 (context)) {
    gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
  } else if (USING_GLES2 (context)) {
    guint j = 8;

    while (j >= n_gl_bytes) {
      /* GST_ROUND_UP_j(GL_MEM_WIDTH (gl_mem) * n_gl_bytes) */
      guint round_up_j =
          ((GL_MEM_WIDTH (gl_mem) * n_gl_bytes) + j - 1) & ~(j - 1);

      if (round_up_j == GL_MEM_STRIDE (gl_mem)) {
        GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based on "
            "width (with plane width:%u, plane stride:%u and pixel stride:%u. "
            "RU%u(%u*%u) = %u)", j, GL_MEM_WIDTH (gl_mem),
            GL_MEM_STRIDE (gl_mem), n_gl_bytes, j, GL_MEM_WIDTH (gl_mem),
            n_gl_bytes, round_up_j);

        gl_mem->unpack_length = j;
        break;
      }
      j >>= 1;
    }

    if (j < n_gl_bytes) {
      /* Failed to find a suitable alignment, try based on plane_stride and
       * scale in the shader.  Useful for alignments that are greater than 8.
       */
      j = 8;

      while (j >= n_gl_bytes) {
        /* GST_ROUND_UP_j((GL_MEM_STRIDE (gl_mem)) */
        guint round_up_j = ((GL_MEM_STRIDE (gl_mem)) + j - 1) & ~(j - 1);

        if (round_up_j == (GL_MEM_STRIDE (gl_mem))) {
          GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based "
              "on stride (with plane stride:%u and pixel stride:%u. "
              "RU%u(%u) = %u)", j, GL_MEM_STRIDE (gl_mem), n_gl_bytes, j,
              GL_MEM_STRIDE (gl_mem), round_up_j);

          gl_mem->unpack_length = j;
          gl_mem->tex_scaling[0] =
              (gfloat) (GL_MEM_WIDTH (gl_mem) * n_gl_bytes) /
              (gfloat) GL_MEM_STRIDE (gl_mem);
          gl_mem->tex_width = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
          break;
        }
        j >>= 1;
      }

      if (j < n_gl_bytes) {
        GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to find matching "
            "alignment. Image may look corrupted. plane width:%u, "
            "plane stride:%u and pixel stride:%u", GL_MEM_WIDTH (gl_mem),
            GL_MEM_STRIDE (gl_mem), n_gl_bytes);
      }
    }
  }

  if (gl_mem->tex_target == GST_GL_TEXTURE_TARGET_RECTANGLE) {
    guint w_sub =
        GST_VIDEO_FORMAT_INFO_W_SUB (gl_mem->info.finfo, gl_mem->plane);
    guint h_sub =
        GST_VIDEO_FORMAT_INFO_H_SUB (gl_mem->info.finfo, gl_mem->plane);

    if (w_sub)
      gl_mem->tex_scaling[0] /= (1 << w_sub);
    if (h_sub)
      gl_mem->tex_scaling[1] /= (1 << h_sub);
  }
}

static guint
_new_texture (GstGLContext * context, guint target, guint internal_format,
    guint format, guint type, guint width, guint height)
{
  const GstGLFuncs *gl = context->gl_vtable;
  guint tex_id;

  gl->GenTextures (1, &tex_id);
  gl->BindTexture (target, tex_id);
  if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
    gl->TexImage2D (target, 0, internal_format, width, height, 0, format, type,
        NULL);

  gl->TexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  gl->BindTexture (target, 0);

  return tex_id;
}

static gboolean
_gl_tex_create (GstGLMemory * gl_mem, GError ** error)
{
  GstGLContext *context = gl_mem->mem.context;
  GLenum internal_format;
  GLenum tex_format;
  GLenum tex_type;

  tex_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
  tex_type = GL_UNSIGNED_BYTE;
  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    tex_type = GL_UNSIGNED_SHORT_5_6_5;

  internal_format =
      gst_gl_sized_gl_format_from_gl_format_type (context, tex_format,
      tex_type);

  if (!gl_mem->texture_wrapped) {
    gl_mem->tex_id =
        _new_texture (context, gst_gl_texture_target_to_gl (gl_mem->tex_target),
        internal_format, tex_format, tex_type, gl_mem->tex_width,
        GL_MEM_HEIGHT (gl_mem));

    GST_TRACE ("Generating texture id:%u format:%u type:%u dimensions:%ux%u",
        gl_mem->tex_id, tex_format, tex_type, gl_mem->tex_width,
        GL_MEM_HEIGHT (gl_mem));
  }

  return TRUE;
}

/**
 * gst_gl_memory_init:
 * @mem: the #GstGLBaseMemory to initialize
 * @allocator: the #GstAllocator to initialize with
 * @parent: (allow-none): the parent #GstMemory to initialize with
 * @context: the #GstGLContext to initialize with
 * @target: the #GstGLTextureTarget for this #GstGLMemory
 * @tex_type: the #GstVideoGLTextureType for this #GstGLMemory
 * @params: (allow-none): the @GstAllocationParams to initialize with
 * @info: the #GstVideoInfo for this #GstGLMemory
 * @plane: the plane number (starting from 0) for this #GstGLMemory
 * @valign: (allow-none): optional #GstVideoAlignment parameters
 * @notify: (allow-none): a #GDestroyNotify
 * @user_data: (allow-none): user data to call @notify with
 *
 * Initializes @mem with the required parameters.  @info is assumed to have
 * already have been modified with gst_video_info_align().
 *
 * Since: 1.8
 */
void
gst_gl_memory_init (GstGLMemory * mem, GstAllocator * allocator,
    GstMemory * parent, GstGLContext * context, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type, GstAllocationParams * params,
    GstVideoInfo * info, guint plane, GstVideoAlignment * valign,
    gpointer user_data, GDestroyNotify notify)
{
  const gchar *target_str;
  gsize size;

  g_return_if_fail (plane < GST_VIDEO_INFO_N_PLANES (info));

  mem->info = *info;
  if (valign)
    mem->valign = *valign;
  else
    gst_video_alignment_reset (&mem->valign);

  /* double-check alignment requirements (caller should've taken care of this) */
  if (params) {
    guint max_align, n;

    max_align = gst_memory_alignment;
    max_align |= params->align;
    for (n = 0; n < GST_VIDEO_MAX_PLANES; ++n)
      max_align |= mem->valign.stride_align[n];

    if (params->align < max_align && max_align > gst_memory_alignment) {
      GST_WARNING ("allocation params alignment %" G_GSIZE_FORMAT " is smaller "
          "than the max required video alignment %u", params->align, max_align);
    }
  }

  size = gst_gl_get_plane_data_size (info, valign, plane);

  mem->tex_target = target;
  mem->tex_type = tex_type;
  mem->plane = plane;

  _calculate_unpack_length (mem, context);

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

  target_str = gst_gl_texture_target_to_string (target);
  GST_CAT_DEBUG (GST_CAT_GL_MEMORY, "new GL texture context:%"
      GST_PTR_FORMAT " memory:%p target:%s format:%u dimensions:%ux%u "
      "stride:%u size:%" G_GSIZE_FORMAT, context, mem, target_str,
      mem->tex_type, mem->tex_width, GL_MEM_HEIGHT (mem), GL_MEM_STRIDE (mem),
      mem->mem.mem.size);
}

/**
 * gst_gl_memory_read_pixels:
 * @gl_mem: a #GstGLMemory
 * @read_pointer: the data pointer to pass to glReadPixels
 *
 * Reads the texture in #GstGLMemory into @read_pointer if no buffer is bound
 * to %GL_PIXEL_PACK_BUFFER.  Otherwise @read_pointer is the byte offset into
 * the currently bound %GL_PIXEL_PACK_BUFFER buffer to store the result of
 * glReadPixels.  See the OpenGL specification for glReadPixels for more
 * details.
 *
 * Returns: whether theread operation succeeded
 *
 * Since: 1.8
 */
gboolean
gst_gl_memory_read_pixels (GstGLMemory * gl_mem, gpointer read_pointer)
{
  GstGLContext *context = gl_mem->mem.context;
  const GstGLFuncs *gl = context->gl_vtable;
  guint format, type;
  guint fbo;

  format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
  type = GL_UNSIGNED_BYTE;
  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    type = GL_UNSIGNED_SHORT_5_6_5;

  /* FIXME: avoid creating a framebuffer every download/copy */
  gl->GenFramebuffers (1, &fbo);
  gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);

  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      gst_gl_texture_target_to_gl (gl_mem->tex_target), gl_mem->tex_id, 0);

  if (!gst_gl_context_check_framebuffer_status (context)) {
    GST_CAT_WARNING (GST_CAT_GL_MEMORY,
        "Could not create framebuffer to read pixels for memory %p", gl_mem);
    gl->DeleteFramebuffers (1, &fbo);
    return FALSE;
  }

  if (USING_GLES2 (context) || USING_GLES3 (context)) {
    if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
      /* explicitly supported */
    } else {
      gint supported_format, supported_type;

      gl->GetIntegerv (GL_IMPLEMENTATION_COLOR_READ_FORMAT, &supported_format);
      gl->GetIntegerv (GL_IMPLEMENTATION_COLOR_READ_TYPE, &supported_type);

      if (supported_format != format || supported_type != type) {
        GST_CAT_ERROR (GST_CAT_GL_MEMORY, "cannot read pixels with "
            "unsupported format and type.  Supported format 0x%x type 0x%x",
            supported_format, supported_type);
        gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
        gl->DeleteFramebuffers (1, &fbo);
        return FALSE;
      }
    }
  }

  gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (gl_mem)->query,
      GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "glReadPixels took");
  gl->ReadPixels (0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), format,
      type, read_pointer);
  gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (gl_mem)->query);

  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
  gl->DeleteFramebuffers (1, &fbo);

  return TRUE;
}

static gpointer
_gl_tex_download_get_tex_image (GstGLMemory * gl_mem, GstMapInfo * info,
    gsize size)
{
  GstGLContext *context = gl_mem->mem.context;
  const GstGLFuncs *gl = context->gl_vtable;

  if (size != -1 && size != ((GstMemory *) gl_mem)->maxsize)
    return NULL;

  if (USING_GLES2 (context) || USING_GLES3 (context))
    return NULL;

  /* taken care of by read pixels */
  if (gl_mem->tex_type != GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
      && gl_mem->tex_type != GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)
    return NULL;

  if (info->flags & GST_MAP_READ
      && GST_MEMORY_FLAG_IS_SET (gl_mem,
          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
    guint format, type;
    guint target;

    GST_CAT_TRACE (GST_CAT_GL_MEMORY, "attempting download of texture %u "
        "using glGetTexImage", gl_mem->tex_id);

    format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
    type = GL_UNSIGNED_BYTE;
    if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
      type = GL_UNSIGNED_SHORT_5_6_5;

    target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
    gl->BindTexture (target, gl_mem->tex_id);
    gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (gl_mem)->query,
        GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "glGetTexImage took");
    gl->GetTexImage (target, 0, format, type, gl_mem->mem.data);
    gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (gl_mem)->query);
    gl->BindTexture (target, 0);
  }

  return gl_mem->mem.data;
}

static gpointer
_gl_tex_download_read_pixels (GstGLMemory * gl_mem, GstMapInfo * info,
    gsize size)
{
  if (size != -1 && size != ((GstMemory *) gl_mem)->maxsize)
    return NULL;

  if (info->flags & GST_MAP_READ
      && GST_MEMORY_FLAG_IS_SET (gl_mem,
          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
    GST_CAT_TRACE (GST_CAT_GL_MEMORY,
        "attempting download of texture %u " "using glReadPixels",
        gl_mem->tex_id);
    if (!gst_gl_memory_read_pixels (gl_mem, gl_mem->mem.data))
      return NULL;
  }

  return gl_mem->mem.data;
}

static gpointer
_gl_tex_map_cpu_access (GstGLMemory * gl_mem, GstMapInfo * info, gsize size)
{
  gpointer data = NULL;

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

  if (!data)
    data = _gl_tex_download_get_tex_image (gl_mem, info, size);

  if (!data)
    data = _gl_tex_download_read_pixels (gl_mem, info, size);

  return data;
}

static void
_upload_cpu_write (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize)
{
  gst_gl_memory_texsubimage (gl_mem, gl_mem->mem.data);
}

/**
 * gst_gl_memory_texsubimage:
 * @gl_mem: a #GstGLMemory
 * @read_pointer: the data pointer to pass to glTexSubImage
 *
 * See gst_gl_memory_read_pixels() for what @read_pointer signifies.
 *
 * Since: 1.8
 */
void
gst_gl_memory_texsubimage (GstGLMemory * gl_mem, gpointer read_pointer)
{
  GstGLContext *context = gl_mem->mem.context;
  const GstGLFuncs *gl;
  GLenum gl_format, gl_type, gl_target;
  gpointer data;
  gsize plane_start;

  if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD))
    return;

  gl = context->gl_vtable;

  gl_type = GL_UNSIGNED_BYTE;
  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    gl_type = GL_UNSIGNED_SHORT_5_6_5;

  gl_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
  gl_target = gst_gl_texture_target_to_gl (gl_mem->tex_target);

  if (USING_OPENGL (context) || USING_GLES3 (context)
      || USING_OPENGL3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->unpack_length);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->unpack_length);
  }

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, %ux%u",
      gl_mem->tex_id, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem));

  /* find the start of the plane data including padding */
  plane_start =
      gst_gl_get_plane_start (&gl_mem->info, &gl_mem->valign,
      gl_mem->plane) + gl_mem->mem.mem.offset;

  data = (gpointer) ((gintptr) plane_start + (gintptr) read_pointer);

  gl->BindTexture (gl_target, gl_mem->tex_id);
  gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (gl_mem)->query,
      GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "glTexSubImage took");
  gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->tex_width,
      GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, data);
  gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (gl_mem)->query);

  /* Reset to default values */
  if (USING_OPENGL (context) || USING_GLES3 (context)
      || USING_OPENGL3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4);
  }

  gl->BindTexture (gl_target, 0);
}

static gpointer
_default_gl_tex_map (GstGLMemory * gl_mem, GstMapInfo * info, gsize size)
{
  if ((info->flags & GST_MAP_GL) == GST_MAP_GL) {
    _upload_cpu_write (gl_mem, info, size);
    return &gl_mem->tex_id;
  } else {
    return _gl_tex_map_cpu_access (gl_mem, info, size);
  }
}

static gpointer
_gl_tex_map (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize)
{
  GstGLMemoryAllocatorClass *alloc_class;
  gpointer data;

  alloc_class = GST_GL_MEMORY_ALLOCATOR_GET_CLASS (gl_mem->mem.mem.allocator);

  if ((info->flags & GST_MAP_GL) == GST_MAP_GL) {
    if (gl_mem->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
      return &gl_mem->tex_id;
  } else {                      /* not GL */
    if (gl_mem->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
      GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot map External OES textures");
      return NULL;
    }
  }

  g_return_val_if_fail (alloc_class->map != NULL, NULL);
  data = alloc_class->map (GST_GL_BASE_MEMORY_CAST (gl_mem), info, maxsize);

  return data;
}

static void
_default_gl_tex_unmap (GstGLMemory * gl_mem, GstMapInfo * info)
{
}

static void
_gl_tex_unmap (GstGLMemory * gl_mem, GstMapInfo * info)
{
  GstGLMemoryAllocatorClass *alloc_class;

  alloc_class = GST_GL_MEMORY_ALLOCATOR_GET_CLASS (gl_mem->mem.mem.allocator);
  g_return_if_fail (alloc_class->unmap != NULL);

  alloc_class->unmap (GST_GL_BASE_MEMORY_CAST (gl_mem), info);
}

/**
 * gst_gl_memory_copy_texiamge:
 * @gl_mem: the source #GstGLMemory
 * @tex_id: the destination texture id
 * @out_target: the destination #GstGLTextureTarget
 * @out_tex_type: the destination #GstVideoGLTextureType
 * @out_width: the destination width
 * @out_height: the destination height
 *
 * Copies the texture in #GstGLMemory into the texture specified by @tex_id,
 * @out_target, @out_tex_type, @out_width and @out_height.
 *
 * Returns: whether the copy succeeded.
 *
 * Since: 1.8
 */
gboolean
gst_gl_memory_copy_teximage (GstGLMemory * src, guint tex_id,
    GstGLTextureTarget out_target, GstVideoGLTextureType out_tex_type,
    gint out_width, gint out_height)
{
  const GstGLFuncs *gl;
  guint out_gl_format, out_tex_target;
  GstMapInfo sinfo;
  guint src_tex_id;
  guint fbo;

  gl = src->mem.context->gl_vtable;
  out_tex_target = gst_gl_texture_target_to_gl (out_target);
  out_gl_format = gst_gl_format_from_gl_texture_type (out_tex_type);

  if (!gl->GenFramebuffers) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Framebuffer objects not supported");
    goto error;
  }

  if (USING_GLES2 (src->mem.context)
      && (src->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
          || src->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)) {
    GST_CAT_FIXME (GST_CAT_GL_MEMORY,
        "Cannot copy Luminance/Luminance Alpha textures in GLES");
    goto error;
  }

  if (!gst_memory_map (GST_MEMORY_CAST (src), &sinfo,
          GST_MAP_READ | GST_MAP_GL)) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY,
        "Failed to map source memory for copying");
    goto error;
  }

  src_tex_id = *(guint *) sinfo.data;

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "copying memory %p, tex %u into "
      "texture %i", src, src_tex_id, tex_id);

  /* FIXME: try and avoid creating and destroying fbo's every copy... */
  /* create a framebuffer object */
  gl->GenFramebuffers (1, &fbo);
  gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);

  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      gst_gl_texture_target_to_gl (src->tex_target), src_tex_id, 0);

//  if (!gst_gl_context_check_framebuffer_status (src->context))
//    goto fbo_error;

  gl->BindTexture (out_tex_target, tex_id);
  gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (src)->query,
      GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "CopyTexImage2D took");
  gl->CopyTexImage2D (out_tex_target, 0, out_gl_format, 0, 0, out_width,
      out_height, 0);
  gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (src)->query);

  gl->BindTexture (out_tex_target, 0);
  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  gl->DeleteFramebuffers (1, &fbo);

  gst_memory_unmap (GST_MEMORY_CAST (src), &sinfo);

  return TRUE;

error:
  return FALSE;
}

static void
_gl_tex_copy_thread (GstGLContext * context, gpointer data)
{
  GstGLMemoryCopyParams *copy_params;

  copy_params = (GstGLMemoryCopyParams *) data;

  if (!copy_params->tex_id) {
    guint internal_format, out_gl_format, out_gl_type, out_tex_target;

    out_tex_target = gst_gl_texture_target_to_gl (copy_params->tex_target);
    out_gl_format =
        gst_gl_format_from_gl_texture_type (copy_params->src->tex_type);
    out_gl_type = GL_UNSIGNED_BYTE;
    if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
      out_gl_type = GL_UNSIGNED_SHORT_5_6_5;

    internal_format =
        gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
        out_gl_type);

    copy_params->tex_id =
        _new_texture (context, out_tex_target,
        internal_format, out_gl_format, out_gl_type, copy_params->out_width,
        copy_params->out_height);
  }

  copy_params->result = gst_gl_memory_copy_teximage (copy_params->src,
      copy_params->tex_id, copy_params->tex_target, copy_params->tex_type,
      copy_params->out_width, copy_params->out_height);
}

static GstMemory *
_default_gl_tex_copy (GstGLMemory * src, gssize offset, gssize size)
{
  GstAllocationParams params = { 0, GST_MEMORY_CAST (src)->align, 0, 0 };
  GstGLBaseMemoryAllocator *base_mem_allocator;
  GstAllocator *allocator;
  GstGLMemory *dest = NULL;

  allocator = GST_MEMORY_CAST (src)->allocator;
  base_mem_allocator = (GstGLBaseMemoryAllocator *) allocator;

  if (src->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot copy External OES textures");
    return NULL;
  }

  /* If not doing a full copy, then copy to sysmem, the 2D represention of the
   * texture would become wrong */
  if (offset > 0 || size < GST_MEMORY_CAST (src)->size) {
    return base_mem_allocator->fallback_mem_copy (GST_MEMORY_CAST (src), offset,
        size);
  }

  dest = g_new0 (GstGLMemory, 1);

  gst_gl_memory_init (dest, allocator, NULL, src->mem.context, src->tex_target,
      src->tex_type, &params, &src->info, src->plane, &src->valign, NULL, NULL);

  if (!GST_MEMORY_FLAG_IS_SET (src, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) {
    GstMapInfo dinfo;

    if (!gst_memory_map (GST_MEMORY_CAST (dest), &dinfo,
            GST_MAP_WRITE | GST_MAP_GL)) {
      GST_CAT_WARNING (GST_CAT_GL_MEMORY,
          "Failed not map destination for writing");
      gst_memory_unref (GST_MEMORY_CAST (dest));
      return NULL;
    }

    if (!gst_gl_memory_copy_into ((GstGLMemory *) src,
            ((GstGLMemory *) dest)->tex_id, src->tex_target,
            src->tex_type, src->tex_width, GL_MEM_HEIGHT (src))) {
      GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory");
      gst_memory_unmap (GST_MEMORY_CAST (dest), &dinfo);
      goto memcpy;
    }

    gst_memory_unmap (GST_MEMORY_CAST (dest), &dinfo);
  } else {
  memcpy:
    if (!gst_gl_base_memory_memcpy ((GstGLBaseMemory *) src,
            (GstGLBaseMemory *) dest, offset, size)) {
      GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory");
      gst_memory_unref (GST_MEMORY_CAST (dest));
      return NULL;
    }
  }

  return (GstMemory *) dest;
}

static GstMemory *
_gl_tex_copy (GstGLMemory * src, gssize offset, gssize size)
{
  GstGLMemoryAllocatorClass *alloc_class;

  alloc_class = GST_GL_MEMORY_ALLOCATOR_GET_CLASS (src->mem.mem.allocator);

  if (src->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot copy External OES textures");
    return NULL;
  }

  g_return_val_if_fail (alloc_class->copy, NULL);
  return (GstMemory *) alloc_class->copy (GST_GL_BASE_MEMORY_CAST (src), offset,
      size);
}

static GstMemory *
_gl_tex_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_tex_destroy (GstGLMemory * gl_mem)
{
  const GstGLFuncs *gl = gl_mem->mem.context->gl_vtable;

  if (gl_mem->tex_id && !gl_mem->texture_wrapped)
    gl->DeleteTextures (1, &gl_mem->tex_id);
}

static GstGLMemory *
_default_gl_tex_alloc (GstGLMemoryAllocator * allocator,
    GstGLVideoAllocationParams * params)
{
  guint alloc_flags = params->parent.alloc_flags;
  GstGLMemory *mem;

  g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
      NULL);

  mem = g_new0 (GstGLMemory, 1);

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

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

  if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
    GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD);
  }
  if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) {
    mem->mem.data = params->parent.wrapped_data;
    GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD);
  }

  return mem;
}

static void
gst_gl_memory_allocator_class_init (GstGLMemoryAllocatorClass * klass)
{
  GstGLBaseMemoryAllocatorClass *gl_base;
  GstAllocatorClass *allocator_class;

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

  klass->map = (GstGLBaseMemoryAllocatorMapFunction) _default_gl_tex_map;
  klass->unmap = (GstGLBaseMemoryAllocatorUnmapFunction) _default_gl_tex_unmap;
  klass->copy = (GstGLBaseMemoryAllocatorCopyFunction) _default_gl_tex_copy;

  gl_base->alloc =
      (GstGLBaseMemoryAllocatorAllocFunction) _default_gl_tex_alloc;
  gl_base->create = (GstGLBaseMemoryAllocatorCreateFunction) _gl_tex_create;
  gl_base->map = (GstGLBaseMemoryAllocatorMapFunction) _gl_tex_map;
  gl_base->unmap = (GstGLBaseMemoryAllocatorUnmapFunction) _gl_tex_unmap;
  gl_base->copy = (GstGLBaseMemoryAllocatorCopyFunction) _gl_tex_copy;
  gl_base->destroy = (GstGLBaseMemoryAllocatorDestroyFunction) _gl_tex_destroy;

  allocator_class->alloc = _gl_tex_alloc;
}

static void
gst_gl_memory_allocator_init (GstGLMemoryAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_GL_MEMORY_ALLOCATOR_NAME;

  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}

/**
 * gst_gl_memory_copy_into:
 * @gl_mem:a #GstGLMemory
 * @tex_id:OpenGL texture id
 * @target: the #GstGLTextureTarget
 * @tex_type: the #GstVideoGLTextureType
 * @width: width of @tex_id
 * @height: height of @tex_id
 *
 * Copies @gl_mem into the texture specfified by @tex_id.  The format of @tex_id
 * is specified by @tex_type, @width and @height.
 *
 * Returns: Whether the copy suceeded
 *
 * Since: 1.8
 */
gboolean
gst_gl_memory_copy_into (GstGLMemory * gl_mem, guint tex_id,
    GstGLTextureTarget target, GstVideoGLTextureType tex_type, gint width,
    gint height)
{
  GstGLMemoryCopyParams copy_params;

  copy_params.src = gl_mem;
  copy_params.tex_id = tex_id;
  copy_params.tex_target = target;
  copy_params.tex_type = tex_type;
  copy_params.out_width = width;
  copy_params.out_height = height;

  gst_gl_context_thread_add (gl_mem->mem.context, _gl_tex_copy_thread,
      &copy_params);

  return copy_params.result;
}

/**
 * gst_gl_memory_get_texture_width:
 * @gl_mem: a #GstGLMemory
 *
 * Returns: the texture width of @gl_mem
 *
 * Since: 1.8
 */
gint
gst_gl_memory_get_texture_width (GstGLMemory * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem), 0);

  return gl_mem->tex_width;
}

/**
 * gst_gl_memory_get_texture_height:
 * @gl_mem: a #GstGLMemory
 *
 * Returns: the texture height of @gl_mem
 *
 * Since: 1.8
 */
gint
gst_gl_memory_get_texture_height (GstGLMemory * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem), 0);

  return _get_plane_height (&gl_mem->info, gl_mem->plane);
}

/**
 * gst_gl_memory_get_texture_type:
 * @gl_mem: a #GstGLMemory
 *
 * Returns: the #GstVideoGLTextureType of @gl_mem
 *
 * Since: 1.8
 */
GstVideoGLTextureType
gst_gl_memory_get_texture_type (GstGLMemory * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem), 0);

  return gl_mem->tex_type;
}

/**
 * gst_gl_memory_get_texture_target:
 * @gl_mem: a #GstGLMemory
 *
 * Returns: the #GstGLTextureTarget of @gl_mem
 *
 * Since: 1.8
 */
GstGLTextureTarget
gst_gl_memory_get_texture_target (GstGLMemory * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem), 0);

  return gl_mem->tex_target;
}

/**
 * gst_gl_memory_get_texture_id:
 * @gl_mem: a #GstGLMemory
 *
 * Returns: the OpenGL texture handle of @gl_mem
 *
 * Since: 1.8
 */
guint
gst_gl_memory_get_texture_id (GstGLMemory * gl_mem)
{
  g_return_val_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem), 0);

  return gl_mem->tex_id;
}

/**
 * gst_gl_memory_init_once:
 *
 * Initializes the GL Base Texture allocator. It is safe to call this function
 * multiple times.  This must be called before any other GstGLMemory operation.
 *
 * Since: 1.4
 */
void
gst_gl_memory_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_MEMORY, "glbasetexture", 0,
        "OpenGL Base Texture Memory");

    _gl_memory_allocator = g_object_new (GST_TYPE_GL_MEMORY_ALLOCATOR, NULL);

    gst_allocator_register (GST_GL_MEMORY_ALLOCATOR_NAME, _gl_memory_allocator);

    g_once_init_leave (&_init, 1);
  }
}

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

static void
_gst_gl_video_allocation_params_set_video_alignment (GstGLVideoAllocationParams
    * params, GstVideoAlignment * valign)
{
  g_return_if_fail (params != NULL);

  if (!params->valign)
    params->valign = g_new0 (GstVideoAlignment, 1);

  if (valign) {
    *params->valign = *valign;
  } else {
    gst_video_alignment_reset (params->valign);
  }
}

/**
 * gst_gl_video_allocation_params_init_full:
 * @params: a #GstGLVideoAllocationParams to initialize
 * @struct_size: the size of the struct in @params
 * @alloc_flags: some allocation flags
 * @copy: a copy function
 * @free: a free function
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for @wrapped_data
 * @v_info: the #GstVideoInfo for @wrapped_data
 * @plane: the video plane @wrapped_data represents
 * @valign: (allow-none): any #GstVideoAlignment applied to symem mappings of @wrapped_data
 * @target: the #GstGLTextureTarget
 * @tex_type: the #GstVideoGLTextureType
 * @wrapped_data: (allow-none): the optional data pointer to wrap
 * @gl_handle: the optional OpenGL handle to wrap or 0
 * @user_data: (allow-none): user data to call @notify with
 * @notify: (allow-none): a #GDestroyNotify
 *
 * Intended for subclass usage
 *
 * Returns: initializes @params with the parameters specified
 *
 * Since: 1.8
 */
gboolean
gst_gl_video_allocation_params_init_full (GstGLVideoAllocationParams * params,
    gsize struct_size, guint alloc_flags, GstGLAllocationParamsCopyFunc copy,
    GstGLAllocationParamsFreeFunc free, GstGLContext * context,
    GstAllocationParams * alloc_params, GstVideoInfo * v_info,
    guint plane, GstVideoAlignment * valign, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type, gpointer wrapped_data, gpointer gl_handle,
    gpointer user_data, GDestroyNotify notify)
{
  guint i;

  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);
  g_return_val_if_fail (v_info != NULL, 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->v_info = g_new0 (GstVideoInfo, 1);
  *params->v_info = *v_info;
  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
    params->v_info->offset[i] = v_info->offset[i];
    params->v_info->stride[i] = v_info->stride[i];
  }
  _gst_gl_video_allocation_params_set_video_alignment (params, valign);
  params->target = target;
  params->tex_type = tex_type;
  params->plane = plane;

  return TRUE;
}

/**
 * gst_gl_video_allocation_params_new:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for sysmem mappings of the texture
 * @v_info: the #GstVideoInfo for the texture
 * @plane: the video plane of @v_info to allocate
 * @valign: (allow-none): any #GstVideoAlignment applied to symem mappings of the texture
 * @target: the #GstGLTextureTarget for the created textures
 * @tex_type: the #GstVideoGLTextureType for the created textures
 *
 * Returns: a new #GstGLVideoAllocationParams for allocating #GstGLMemory's
 *
 * Since: 1.8
 */
GstGLVideoAllocationParams *
gst_gl_video_allocation_params_new (GstGLContext * context,
    GstAllocationParams * alloc_params, GstVideoInfo * v_info, guint plane,
    GstVideoAlignment * valign, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type)
{
  GstGLVideoAllocationParams *params = g_new0 (GstGLVideoAllocationParams, 1);

  if (!gst_gl_video_allocation_params_init_full (params,
          sizeof (GstGLVideoAllocationParams),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
          (GstGLAllocationParamsCopyFunc)
          gst_gl_video_allocation_params_copy_data,
          (GstGLAllocationParamsFreeFunc)
          gst_gl_video_allocation_params_free_data, context, alloc_params,
          v_info, plane, valign, target, tex_type, NULL, 0, NULL, NULL)) {
    g_free (params);
    return NULL;
  }

  return params;
}

/**
 * gst_gl_video_allocation_params_new_wrapped_data:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for @wrapped_data
 * @v_info: the #GstVideoInfo for @wrapped_data
 * @plane: the video plane @wrapped_data represents
 * @valign: (allow-none): any #GstVideoAlignment applied to symem mappings of @wrapped_data
 * @target: the #GstGLTextureTarget for @wrapped_data
 * @tex_type: the #GstVideoGLTextureType for @wrapped_data
 * @wrapped_data: the data pointer to wrap
 * @user_data: (allow-none): user data to call @notify with
 * @notify: (allow-none): a #GDestroyNotify
 *
 * Returns: a new #GstGLVideoAllocationParams for wrapping @wrapped_data
 *
 * Since: 1.8
 */
GstGLVideoAllocationParams *
gst_gl_video_allocation_params_new_wrapped_data (GstGLContext * context,
    GstAllocationParams * alloc_params, GstVideoInfo * v_info, guint plane,
    GstVideoAlignment * valign, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type, gpointer wrapped_data, gpointer user_data,
    GDestroyNotify notify)
{
  GstGLVideoAllocationParams *params = g_new0 (GstGLVideoAllocationParams, 1);

  if (!gst_gl_video_allocation_params_init_full (params,
          sizeof (GstGLVideoAllocationParams),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
          (GstGLAllocationParamsCopyFunc)
          gst_gl_video_allocation_params_copy_data,
          (GstGLAllocationParamsFreeFunc)
          gst_gl_video_allocation_params_free_data, context, alloc_params,
          v_info, plane, valign, target, tex_type, wrapped_data, 0, user_data,
          notify)) {
    g_free (params);
    return NULL;
  }

  return params;
}

/**
 * gst_gl_video_allocation_params_new_wrapped_gl_handle:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for @tex_id
 * @v_info: the #GstVideoInfo for @tex_id
 * @plane: the video plane @tex_id represents
 * @valign: (allow-none): any #GstVideoAlignment applied to symem mappings of @tex_id
 * @target: the #GstGLTextureTarget for @tex_id
 * @tex_type: the #GstVideoGLTextureType 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
 *
 * @gl_handle is defined by the specific OpenGL handle being wrapped
 * For #GstGLMemory and #GstGLMemoryPBO it is an OpenGL texture id.
 * Other memory types may define it to require a different type of parameter.
 *
 * Returns: a new #GstGLVideoAllocationParams for wrapping @gl_handle
 *
 * Since: 1.8
 */
GstGLVideoAllocationParams *
gst_gl_video_allocation_params_new_wrapped_gl_handle (GstGLContext * context,
    GstAllocationParams * alloc_params, GstVideoInfo * v_info, guint plane,
    GstVideoAlignment * valign, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type, gpointer gl_handle, gpointer user_data,
    GDestroyNotify notify)
{
  GstGLVideoAllocationParams *params = g_new0 (GstGLVideoAllocationParams, 1);

  if (!gst_gl_video_allocation_params_init_full (params,
          sizeof (GstGLVideoAllocationParams),
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE |
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
          (GstGLAllocationParamsCopyFunc)
          gst_gl_video_allocation_params_copy_data,
          (GstGLAllocationParamsFreeFunc)
          gst_gl_video_allocation_params_free_data, context, alloc_params,
          v_info, plane, valign, target, tex_type, NULL, gl_handle, user_data,
          notify)) {
    g_free (params);
    return NULL;
  }

  return params;
}

/**
 * gst_gl_video_allocation_params_new_wrapped_texture:
 * @context: a #GstGLContext
 * @alloc_params: (allow-none): the #GstAllocationParams for @tex_id
 * @v_info: the #GstVideoInfo for @tex_id
 * @plane: the video plane @tex_id represents
 * @valign: (allow-none): any #GstVideoAlignment applied to symem mappings of @tex_id
 * @target: the #GstGLTextureTarget for @tex_id
 * @tex_type: the #GstGLTextureType for @tex_id
 * @tex_id: the GL texture to wrap
 * @user_data: (allow-none): user data to call @notify with
 * @notify: (allow-none): a #GDestroyNotify
 *
 * Returns: a new #GstGLVideoAllocationParams for wrapping @tex_id
 *
 * Since: 1.8
 */
GstGLVideoAllocationParams *
gst_gl_video_allocation_params_new_wrapped_texture (GstGLContext * context,
    GstAllocationParams * alloc_params, GstVideoInfo * v_info, guint plane,
    GstVideoAlignment * valign, GstGLTextureTarget target,
    GstVideoGLTextureType tex_type, guint tex_id, gpointer user_data,
    GDestroyNotify notify)
{
  return gst_gl_video_allocation_params_new_wrapped_gl_handle (context,
      alloc_params, v_info, plane, valign, target, tex_type,
      GUINT_TO_POINTER (tex_id), user_data, notify);
}

/**
 * gst_gl_video_allocation_params_free_data:
 * @params: a #GstGLVideoAllocationParams
 *
 * Unset and free any dynamically allocated resources.  Intended for subclass
 * usage only to chain up at the end of a subclass free function.
 *
 * Since: 1.8
 */
void
gst_gl_video_allocation_params_free_data (GstGLVideoAllocationParams * params)
{
  g_free (params->v_info);
  g_free (params->valign);

  gst_gl_allocation_params_free_data (&params->parent);
}

/**
 * gst_gl_video_allocation_params_copy_data:
 * @src_vid: source #GstGLVideoAllocationParams to copy from
 * @dest_vid: destination #GstGLVideoAllocationParams to copy into
 *
 * Copy and set any dynamically allocated resources in @dest_vid.  Intended
 * for subclass usage only to chain up at the end of a subclass copy function.
 *
 * Since: 1.8
 */
void
gst_gl_video_allocation_params_copy_data (GstGLVideoAllocationParams * src_vid,
    GstGLVideoAllocationParams * dest_vid)
{
  GstGLAllocationParams *src = (GstGLAllocationParams *) src_vid;
  GstGLAllocationParams *dest = (GstGLAllocationParams *) dest_vid;
  guint i;

  gst_gl_allocation_params_copy_data (src, dest);

  dest_vid->v_info = g_new0 (GstVideoInfo, 1);
  *dest_vid->v_info = *src_vid->v_info;
  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
    dest_vid->v_info->offset[i] = src_vid->v_info->offset[i];
    dest_vid->v_info->stride[i] = src_vid->v_info->stride[i];
  }
  _gst_gl_video_allocation_params_set_video_alignment (dest_vid,
      src_vid->valign);
  dest_vid->target = src_vid->target;
  dest_vid->tex_type = src_vid->tex_type;
  dest_vid->plane = src_vid->plane;
}

/**
 * gst_gl_memory_setup_buffer:
 * @allocator: the @GstGLMemoryAllocator to allocate from
 * @buffer: a #GstBuffer to setup
 * @params: the #GstGLVideoAllocationParams to allocate with
 * @tex_types: (allow-none): a list of #GstVideoGLTextureType's to allocate with.
 * @wrapped_data: a list of wrapped data pointers
 * @n_wrapped_pointers: the number of elements in @tex_types and @wrapped_data
 *
 * Returns: whether the buffer was correctly setup
 *
 * Since: 1.8
 */
gboolean
gst_gl_memory_setup_buffer (GstGLMemoryAllocator * allocator,
    GstBuffer * buffer, GstGLVideoAllocationParams * params,
    GstVideoGLTextureType * tex_types, gpointer * wrapped_data,
    gsize n_wrapped_pointers)
{
  GstGLBaseMemoryAllocator *base_allocator;
  guint n_mem, i, v, views;
  guint alloc_flags = params->parent.alloc_flags;

  g_return_val_if_fail (params != NULL, FALSE);
  g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
      FALSE);

  base_allocator = GST_GL_BASE_MEMORY_ALLOCATOR (allocator);
  n_mem = GST_VIDEO_INFO_N_PLANES (params->v_info);

  if (GST_VIDEO_INFO_MULTIVIEW_MODE (params->v_info) ==
      GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
    views = params->v_info->views;
  else
    views = 1;

  g_return_val_if_fail (!wrapped_data
      || views * n_mem != n_wrapped_pointers, FALSE);

  for (v = 0; v < views; v++) {
    for (i = 0; i < n_mem; i++) {
      GstGLMemory *gl_mem;

      if (tex_types) {
        params->tex_type = tex_types[i];
      } else {
        params->tex_type =
            gst_gl_texture_type_from_format (params->parent.context,
            GST_VIDEO_INFO_FORMAT (params->v_info), i);
      }

      params->plane = i;
      if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) {
        g_return_val_if_fail (wrapped_data != NULL, FALSE);
        params->parent.wrapped_data = wrapped_data[i];
      } else if (alloc_flags &
          GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
        g_return_val_if_fail (wrapped_data != NULL, FALSE);
        params->parent.gl_handle = wrapped_data[i];
      }

      if (!(gl_mem = (GstGLMemory *) gst_gl_base_memory_alloc (base_allocator,
                  (GstGLAllocationParams *) params)))
        return FALSE;

      gst_buffer_append_memory (buffer, (GstMemory *) gl_mem);
    }

    gst_buffer_add_video_meta_full (buffer, v,
        GST_VIDEO_INFO_FORMAT (params->v_info),
        GST_VIDEO_INFO_WIDTH (params->v_info),
        GST_VIDEO_INFO_HEIGHT (params->v_info), n_mem, params->v_info->offset,
        params->v_info->stride);
  }

  return TRUE;
}

/**
 * gst_gl_memory_allocator_get_default:
 * @context: a #GstGLContext
 *
 * Returns: (transfer full): the default #GstGLMemoryAllocator supported by
 *          @context
 *
 * Since: 1.8
 */
GstGLMemoryAllocator *
gst_gl_memory_allocator_get_default (GstGLContext * context)
{
  GstGLMemoryAllocator *allocator = NULL;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);

  /* we can only use the pbo allocator with GL > 3.0 contexts */
  if (gst_gl_context_check_gl_version (context,
          GST_GL_API_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2, 3, 0)) {
    allocator = (GstGLMemoryAllocator *)
        gst_allocator_find (GST_GL_MEMORY_PBO_ALLOCATOR_NAME);
  } else {
    allocator = (GstGLMemoryAllocator *)
        gst_allocator_find (GST_GL_MEMORY_ALLOCATOR_NAME);
  }

  return allocator;
}
