/* 
 * GStreamer
 * Copyright (C) 2013 Matthew Waters <ystreet00@gmail.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.
 */

/**
 * SECTION:gstglframebuffer
 * @short_description: OpenGL framebuffer abstraction
 * @title: GstGLFramebuffer
 * @see_also: #GstGLBaseMemory, #GstGLMemory, #GstGLContext
 *
 * A #GstGLFramebuffer represents and holds an OpenGL framebuffer object with
 * it's associated attachments.
 *
 * A #GstGLFramebuffer can be created with gst_gl_framebuffer_new() or
 * gst_gl_framebuffer_new_with_default_depth() and bound with
 * gst_gl_framebuffer_bind().  Other resources can be bound with
 * gst_gl_framebuffer_attach()
 *
 * Note: OpenGL framebuffers are not shareable resources so cannot be used
 * between multiple OpenGL contexts.
 *
 * Since: 1.10
 */

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

#include "gl.h"
#include "gstglframebuffer.h"

#ifndef GL_FRAMEBUFFER_UNDEFINED
#define GL_FRAMEBUFFER_UNDEFINED          0x8219
#endif
#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#endif
#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#endif
#ifndef GL_FRAMEBUFFER_UNSUPPORTED
#define GL_FRAMEBUFFER_UNSUPPORTED        0x8CDD
#endif
#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#endif

#ifndef GL_DEPTH_STENCIL_ATTACHMENT
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#endif

GST_DEBUG_CATEGORY_STATIC (gst_gl_framebuffer_debug);
#define GST_CAT_DEFAULT gst_gl_framebuffer_debug

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_framebuffer_debug, "glframebuffer", 0, "GL Framebuffer");

G_DEFINE_TYPE_WITH_CODE (GstGLFramebuffer, gst_gl_framebuffer, GST_TYPE_OBJECT,
    DEBUG_INIT);

#define GST_GL_FRAMEBUFFER_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_FRAMEBUFFER, GstGLFramebufferPrivate))

static void gst_gl_framebuffer_finalize (GObject * object);

struct _GstGLFramebufferPrivate
{
  guint effective_width;
  guint effective_height;
};

struct fbo_attachment
{
  guint attachment_point;
  GstGLBaseMemory *mem;
};

static void
_fbo_attachment_init (struct fbo_attachment *attach, guint point,
    GstGLBaseMemory * mem)
{
  attach->attachment_point = point;
  attach->mem = (GstGLBaseMemory *) gst_memory_ref (GST_MEMORY_CAST (mem));
}

static void
_fbo_attachment_unset (struct fbo_attachment *attach)
{
  if (!attach)
    return;

  if (attach->mem)
    gst_memory_unref (GST_MEMORY_CAST (attach->mem));
  attach->mem = NULL;
}

static void
gst_gl_framebuffer_class_init (GstGLFramebufferClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLFramebufferPrivate));

  G_OBJECT_CLASS (klass)->finalize = gst_gl_framebuffer_finalize;
}

static void
gst_gl_framebuffer_init (GstGLFramebuffer * fb)
{
  fb->priv = GST_GL_FRAMEBUFFER_GET_PRIVATE (fb);

  fb->attachments =
      g_array_new (FALSE, FALSE, (sizeof (struct fbo_attachment)));
  g_array_set_clear_func (fb->attachments,
      (GDestroyNotify) _fbo_attachment_unset);
}

static void
_delete_fbo_gl (GstGLContext * context, GstGLFramebuffer * fb)
{
  const GstGLFuncs *gl = context->gl_vtable;

  if (fb->fbo_id)
    gl->DeleteFramebuffers (1, &fb->fbo_id);
  fb->fbo_id = 0;
}

static void
gst_gl_framebuffer_finalize (GObject * object)
{
  GstGLFramebuffer *fb = GST_GL_FRAMEBUFFER (object);

  if (fb->context) {
    if (fb->fbo_id)
      gst_gl_context_thread_add (fb->context,
          (GstGLContextThreadFunc) _delete_fbo_gl, fb);

    gst_object_unref (fb->context);
    fb->context = NULL;
  }

  if (fb->attachments)
    g_array_free (fb->attachments, TRUE);
  fb->attachments = NULL;

  G_OBJECT_CLASS (gst_gl_framebuffer_parent_class)->finalize (object);
}

/**
 * gst_gl_framebuffer_new:
 * @context: a #GstGLContext
 *
 * Returns: a new #GstGLFramebuffer
 *
 * Since: 1.10
 */
GstGLFramebuffer *
gst_gl_framebuffer_new (GstGLContext * context)
{
  GstGLFramebuffer *fb;
  const GstGLFuncs *gl;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
  g_return_val_if_fail (gst_gl_context_get_current () == context, NULL);

  gl = context->gl_vtable;

  if (!gl->GenFramebuffers) {
    GST_ERROR_OBJECT (context, "Framebuffers are not supported!");
    return NULL;
  }

  fb = g_object_new (GST_TYPE_GL_FRAMEBUFFER, NULL);
  fb->context = gst_object_ref (context);
  gl->GenFramebuffers (1, &fb->fbo_id);

  return fb;
}

/**
 * gst_gl_framebuffer_new_with_default_depth:
 * @context: a #GstGLContext
 * @width: width for the depth buffer
 * @height: for the depth buffer
 *
 * Returns: a new #GstGLFramebuffer with a depth buffer of @width and @height
 *
 * Since: 1.10
 */
GstGLFramebuffer *
gst_gl_framebuffer_new_with_default_depth (GstGLContext * context, guint width,
    guint height)
{
  GstGLFramebuffer *fb = gst_gl_framebuffer_new (context);
  GstGLBaseMemoryAllocator *render_alloc;
  GstGLAllocationParams *params;
  GstGLBaseMemory *renderbuffer;
  guint attach_point, attach_type;

  if (!fb)
    return NULL;

  if (gst_gl_context_get_gl_api (fb->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3)) {
    attach_point = GL_DEPTH_STENCIL_ATTACHMENT;
    attach_type = GST_GL_DEPTH24_STENCIL8;
  } else if (gst_gl_context_get_gl_api (fb->context) & GST_GL_API_GLES2) {
    attach_point = GL_DEPTH_ATTACHMENT;
    attach_type = GST_GL_DEPTH_COMPONENT16;
  } else {
    g_assert_not_reached ();
    return NULL;
  }

  render_alloc = (GstGLBaseMemoryAllocator *)
      gst_allocator_find (GST_GL_RENDERBUFFER_ALLOCATOR_NAME);
  params = (GstGLAllocationParams *)
      gst_gl_renderbuffer_allocation_params_new (context, NULL, attach_type,
      width, height);

  renderbuffer = gst_gl_base_memory_alloc (render_alloc, params);
  gst_gl_allocation_params_free (params);
  gst_object_unref (render_alloc);

  gst_gl_framebuffer_bind (fb);
  gst_gl_framebuffer_attach (fb, attach_point, renderbuffer);
  gst_gl_context_clear_framebuffer (fb->context);
  gst_memory_unref (GST_MEMORY_CAST (renderbuffer));

  return fb;
}

/**
 * gst_gl_framebuffer_draw_to_texture:
 * @fb: a #GstGLFramebuffer
 * @mem: the #GstGLMemory to draw to
 * @func: (scope call): the function to run
 * @user_data: data to pass to @func
 *
 * Perform the steps necessary to have the output of a glDraw* command in
 * @func update the contents of @mem.
 *
 * Returns: the result of executing @func
 *
 * Since: 1.10
 */
gboolean
gst_gl_framebuffer_draw_to_texture (GstGLFramebuffer * fb, GstGLMemory * mem,
    GstGLFramebufferFunc func, gpointer user_data)
{
  GLint viewport_dim[4] = { 0 };
  const GstGLFuncs *gl;
  gboolean ret;

  g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (fb), FALSE);
  g_return_val_if_fail (gst_is_gl_memory (GST_MEMORY_CAST (mem)), FALSE);

  gl = fb->context->gl_vtable;

  GST_TRACE_OBJECT (fb, "drawing to texture %u, dimensions %ix%i", mem->tex_id,
      gst_gl_memory_get_texture_width (mem),
      gst_gl_memory_get_texture_height (mem));

  gst_gl_framebuffer_bind (fb);
  gst_gl_framebuffer_attach (fb, GL_COLOR_ATTACHMENT0, (GstGLBaseMemory *) mem);

  gl->GetIntegerv (GL_VIEWPORT, viewport_dim);
  gl->Viewport (0, 0, fb->priv->effective_width, fb->priv->effective_height);
  if (gst_gl_context_get_gl_api (fb->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3))
    gl->DrawBuffer (GL_COLOR_ATTACHMENT0);

  ret = func (user_data);

  if (gst_gl_context_get_gl_api (fb->context) & (GST_GL_API_OPENGL |
          GST_GL_API_OPENGL3))
    gl->DrawBuffer (GL_NONE);
  gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2],
      viewport_dim[3]);
  gst_gl_context_clear_framebuffer (fb->context);

  return ret;
}

/**
 * gst_gl_framebuffer_bind:
 * @fb: a #GstGLFramebuffer
 *
 * Bind @fb into the current thread
 *
 * Since: 1.10
 */
void
gst_gl_framebuffer_bind (GstGLFramebuffer * fb)
{
  const GstGLFuncs *gl;

  g_return_if_fail (GST_IS_GL_FRAMEBUFFER (fb));
  g_return_if_fail (gst_gl_context_get_current () == fb->context);
  g_return_if_fail (fb->fbo_id != 0);

  gl = fb->context->gl_vtable;

  gl->BindFramebuffer (GL_FRAMEBUFFER, fb->fbo_id);
}

/**
 * gst_gl_context_clear_framebuffer:
 * @context: a #GstGLContext
 *
 * Unbind the current framebuffer
 *
 * Since: 1.10
 */
void
gst_gl_context_clear_framebuffer (GstGLContext * context)
{
  const GstGLFuncs *gl;

  g_return_if_fail (GST_IS_GL_CONTEXT (context));

  gl = context->gl_vtable;

  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
}

static void
_update_effective_dimensions (GstGLFramebuffer * fb)
{
  int i;
  guint min_width = -1, min_height = -1;

  /* remove the previous attachment */
  for (i = 0; i < fb->attachments->len; i++) {
    struct fbo_attachment *attach;
    int width, height;

    attach = &g_array_index (fb->attachments, struct fbo_attachment, i);

    if (gst_is_gl_memory (GST_MEMORY_CAST (attach->mem))) {
      GstGLMemory *mem = (GstGLMemory *) attach->mem;

      width = gst_gl_memory_get_texture_width (mem);
      height = gst_gl_memory_get_texture_height (mem);
    } else if (gst_is_gl_renderbuffer (GST_MEMORY_CAST (attach->mem))) {
      GstGLRenderbuffer *mem = (GstGLRenderbuffer *) attach->mem;

      width = mem->width;
      height = mem->height;
    } else {
      g_assert_not_reached ();
    }

    if (width < min_width)
      min_width = width;
    if (height < min_height)
      min_height = height;
  }

  fb->priv->effective_width = min_width;
  fb->priv->effective_height = min_height;
}

static gboolean
_is_valid_attachment_point (guint attachment_point)
{
  /* all 31 possible color attachments */
  if (attachment_point >= 0x8CE0 && attachment_point <= 0x8CFF)
    return TRUE;

  /* depth-stencil attachment */
  if (attachment_point == 0x821A)
    return TRUE;

  /* depth attachment */
  if (attachment_point == 0x8D00)
    return TRUE;

  /* stencil attachment */
  if (attachment_point == 0x8D20)
    return TRUE;

  return FALSE;
}

static void
_attach_gl_memory (GstGLFramebuffer * fb, guint attachment_point,
    GstGLMemory * mem)
{
  struct fbo_attachment attach;
  const GstGLFuncs *gl = fb->context->gl_vtable;
  guint gl_target = gst_gl_texture_target_to_gl (mem->tex_target);

  gst_gl_framebuffer_bind (fb);

  gl->FramebufferTexture2D (GL_FRAMEBUFFER, attachment_point, gl_target,
      mem->tex_id, 0);

  _fbo_attachment_init (&attach, attachment_point, (GstGLBaseMemory *) mem);
  fb->attachments = g_array_append_val (fb->attachments, attach);
}

static void
_attach_renderbuffer (GstGLFramebuffer * fb, guint attachment_point,
    GstGLRenderbuffer * rb)
{
  struct fbo_attachment attach;
  const GstGLFuncs *gl = fb->context->gl_vtable;

  gst_gl_framebuffer_bind (fb);
  gl->BindRenderbuffer (GL_RENDERBUFFER, rb->renderbuffer_id);

  gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, attachment_point,
      GL_RENDERBUFFER, rb->renderbuffer_id);

  _fbo_attachment_init (&attach, attachment_point, (GstGLBaseMemory *) rb);
  fb->attachments = g_array_append_val (fb->attachments, attach);
}

/**
 * gst_gl_framebuffer_attach:
 * @fb: a #GstGLFramebuffer
 * @attachment_point: the OpenGL attachment point to bind @mem to
 * @mem: the memory object to bind to @attachment_point
 *
 * attach @mem to @attachment_point
 *
 * Since: 1.10
 */
void
gst_gl_framebuffer_attach (GstGLFramebuffer * fb, guint attachment_point,
    GstGLBaseMemory * mem)
{
  int i;

  g_return_if_fail (GST_IS_GL_FRAMEBUFFER (fb));
  g_return_if_fail (gst_gl_context_get_current () == fb->context);
  g_return_if_fail (_is_valid_attachment_point (attachment_point));

  /* remove the previous attachment */
  for (i = 0; i < fb->attachments->len; i++) {
    struct fbo_attachment *attach;

    attach = &g_array_index (fb->attachments, struct fbo_attachment, i);

    if (attach->attachment_point == attachment_point) {
      g_array_remove_index_fast (fb->attachments, i);
      break;
    }
  }

  if (gst_is_gl_memory (GST_MEMORY_CAST (mem))) {
    _attach_gl_memory (fb, attachment_point, (GstGLMemory *) mem);
  } else if (gst_is_gl_renderbuffer (GST_MEMORY_CAST (mem))) {
    _attach_renderbuffer (fb, attachment_point, (GstGLRenderbuffer *) mem);
  } else {
    g_assert_not_reached ();
    return;
  }

  _update_effective_dimensions (fb);
}

/**
 * gst_gl_framebuffer_get_effective_dimensions:
 * @fb: a #GstGLFramebuffer
 * @width: (out) (allow-none): output width
 * @height: (out) (allow-none): output height
 *
 * Retreive the effective dimensions from the current attachments attached to
 * @fb.
 *
 * Since: 1.10
 */
void
gst_gl_framebuffer_get_effective_dimensions (GstGLFramebuffer * fb,
    guint * width, guint * height)
{
  g_return_if_fail (GST_IS_GL_FRAMEBUFFER (fb));

  if (width)
    *width = fb->priv->effective_width;
  if (height)
    *height = fb->priv->effective_height;
}

/**
 * gst_gl_context_check_framebuffer_status:
 * @context: a #GstGLContext
 *
 * Returns: whether whether the current framebuffer is complete
 *
 * Since: 1.10
 */
gboolean
gst_gl_context_check_framebuffer_status (GstGLContext * context)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  switch (context->gl_vtable->CheckFramebufferStatus (GL_FRAMEBUFFER)) {
    case GL_FRAMEBUFFER_COMPLETE:
      return TRUE;
      break;
    case GL_FRAMEBUFFER_UNSUPPORTED:
      GST_WARNING_OBJECT (context, "GL_FRAMEBUFFER_UNSUPPORTED");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
      GST_WARNING_OBJECT (context, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
      GST_WARNING_OBJECT (context,
          "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
      GST_WARNING_OBJECT (context, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
      break;
#if GST_GL_HAVE_OPENGL
    case GL_FRAMEBUFFER_UNDEFINED:
      GST_WARNING_OBJECT (context, "GL_FRAMEBUFFER_UNDEFINED");
      break;
#endif
    default:
      GST_WARNING_OBJECT (context, "Unknown FBO error");
      break;
  }

  return FALSE;
}

/**
 * gst_gl_framebuffer_get_id:
 * @fb: a #GstGLFramebuffer
 *
 * Returns: the OpenGL id for @fb
 *
 * Since: 1.10
 */
guint
gst_gl_framebuffer_get_id (GstGLFramebuffer * fb)
{
  g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (fb), 0);

  return fb->fbo_id;
}
