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

#include "gstglcontext.h"
#include "gstglfuncs.h"
#include "gstglmemory.h"
#include "gstglrenderbuffer.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

#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif
#ifndef GL_DRAW_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#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: (transfer full): 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);
  gst_object_ref_sink (fb);

  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_COLOR_ATTACHMENT0);
  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
 * @fbo_target: the GL value of the framebuffer target, GL_FRAMEBUFFER,
 *              GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER
 *
 * Returns: whether whether the current framebuffer is complete
 *
 * Since: 1.10
 */
gboolean
gst_gl_context_check_framebuffer_status (GstGLContext * context,
    guint fbo_target)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  if (fbo_target != GL_FRAMEBUFFER && fbo_target != GL_READ_FRAMEBUFFER
      && fbo_target != GL_DRAW_FRAMEBUFFER) {
    GST_ERROR_OBJECT (context, "fbo target is invalid");
    return FALSE;
  }

  switch (context->gl_vtable->CheckFramebufferStatus (fbo_target)) {
    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;
}
