/* 
 * 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_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
 *
 * Returns: whether whether the current framebuffer is complete
 *
 * Since: 1.10
 */
gboolean
gst_gl_context_check_framebuffer_status (GstGLContext * context, GLenum 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;
}
