/*
 * GStreamer
 * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
 * 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:gstgldisplay
 * @short_description: window system display connection abstraction
 * @title: GstGLDisplay
 * @see_also: #GstContext, #GstGLContext, #GstGLWindow
 *
 * #GstGLDisplay represents a connection to the underlying windowing system. 
 * Elements are required to make use of #GstContext to share and propogate
 * a #GstGLDisplay.
 *
 * There are a number of environment variables that influence the choice of
 * platform and window system specific functionality.
 * - GST_GL_WINDOW influences the window system to use.  Common values are
 *   'x11', 'wayland', 'win32' or 'cocoa'.
 * - GST_GL_PLATFORM influences the OpenGL platform to use.  Common values are
 *   'egl', 'glx', 'wgl' or 'cgl'.
 * - GST_GL_API influences the OpenGL API requested by the OpenGL platform.
 *   Common values are 'opengl' and 'gles2'.
 *
 * <note>Certain window systems require a special function to be called to
 * initialize threading support.  As this GStreamer GL library does not preclude
 * concurrent access to the windowing system, it is strongly advised that
 * applications ensure that threading support has been initialized before any
 * other toolkit/library functionality is accessed.  Failure to do so could
 * result in sudden application abortion during execution.  The most notably
 * example of such a function is X11's XInitThreads().</note>
 */

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

#include "gl.h"
#include "gstgldisplay.h"

#if GST_GL_HAVE_WINDOW_COCOA
#include <gst/gl/cocoa/gstgldisplay_cocoa.h>
#endif
#if GST_GL_HAVE_WINDOW_X11
#include <gst/gl/x11/gstgldisplay_x11.h>
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
#include <gst/gl/wayland/gstgldisplay_wayland.h>
#endif
#if GST_GL_HAVE_PLATFORM_EGL
#include <gst/gl/egl/gstgldisplay_egl.h>
#include <gst/gl/egl/gsteglimage.h>
#include <gst/gl/egl/gstglmemoryegl.h>
#endif

GST_DEBUG_CATEGORY_STATIC (gst_context);
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0, "opengl display"); \
  GST_DEBUG_CATEGORY_GET (gst_context, "GST_CONTEXT");

G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, GST_TYPE_OBJECT,
    DEBUG_INIT);

#define GST_GL_DISPLAY_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_DISPLAY, GstGLDisplayPrivate))

enum
{
  SIGNAL_0,
  CREATE_CONTEXT,
  LAST_SIGNAL
};

static guint gst_gl_display_signals[LAST_SIGNAL] = { 0 };

static void gst_gl_display_finalize (GObject * object);
static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);

struct _GstGLDisplayPrivate
{
  GstGLAPI gl_api;

  GList *contexts;
};

static void
gst_gl_display_class_init (GstGLDisplayClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));

  /**
   * GstGLDisplay::create-context:
   * @object: the #GstGLDisplay
   * @context: (transfer none): other context to share resources with.
   *
   * Overrides the @GstGLContext creation mechanism.
   * It can be called in any thread and it is emitted with
   * display's object lock held.
   *
   * Returns: (transfer full): the new context.
   */
  gst_gl_display_signals[CREATE_CONTEXT] =
      g_signal_new ("create-context", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      GST_GL_TYPE_CONTEXT, 1, GST_GL_TYPE_CONTEXT);

  klass->get_handle = gst_gl_display_default_get_handle;

  G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
}

static void
gst_gl_display_init (GstGLDisplay * display)
{
  display->priv = GST_GL_DISPLAY_GET_PRIVATE (display);

  display->type = GST_GL_DISPLAY_TYPE_ANY;
  display->priv->gl_api = GST_GL_API_ANY;

  GST_TRACE ("init %p", display);

  gst_gl_buffer_init_once ();
  gst_gl_memory_pbo_init_once ();
  gst_gl_renderbuffer_init_once ();

#if GST_GL_HAVE_PLATFORM_EGL
  gst_gl_memory_egl_init_once ();
#endif
}

static void
gst_gl_display_finalize (GObject * object)
{
  GstGLDisplay *display = GST_GL_DISPLAY (object);
  GList *l;

  GST_TRACE_OBJECT (object, "finalizing");

  for (l = display->priv->contexts; l; l = l->next) {
    g_weak_ref_clear ((GWeakRef *) l->data);
    g_free (l->data);
  }

  g_list_free (display->priv->contexts);

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

/**
 * gst_gl_display_new:
 *
 * Returns: (transfer full): a new #GstGLDisplay
 *
 * Since: 1.4
 */
GstGLDisplay *
gst_gl_display_new (void)
{
  GstGLDisplay *display = NULL;
  const gchar *user_choice, *platform_choice;
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0,
        "gldisplay element");
    g_once_init_leave (&_init, 1);
  }

  user_choice = g_getenv ("GST_GL_WINDOW");
  platform_choice = g_getenv ("GST_GL_PLATFORM");
  GST_INFO ("creating a display, user choice:%s (platform: %s)",
      GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));

#if GST_GL_HAVE_WINDOW_COCOA
  if (!display && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) {
    display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
    if (!display)
      return NULL;
  }
#endif
#if GST_GL_HAVE_WINDOW_X11
  if (!display && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
    display = GST_GL_DISPLAY (gst_gl_display_x11_new (NULL));
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
  if (!display && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
    display = GST_GL_DISPLAY (gst_gl_display_wayland_new (NULL));
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (!display && (!platform_choice
          || g_strstr_len (platform_choice, 3, "egl")))
    display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
#endif
  if (!display) {
    GST_INFO ("Could not create platform/winsys display. user specified %s "
        "(platform: %s), creating dummy",
        GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));

    return g_object_new (GST_TYPE_GL_DISPLAY, NULL);
  }

  return display;
}

/**
 * gst_gl_display_get_handle:
 * @display: a #GstGLDisplay
 *
 * Returns: the native handle for the display
 *
 * Since: 1.4
 */
guintptr
gst_gl_display_get_handle (GstGLDisplay * display)
{
  GstGLDisplayClass *klass;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), 0);
  klass = GST_GL_DISPLAY_GET_CLASS (display);
  g_return_val_if_fail (klass->get_handle != NULL, 0);

  return klass->get_handle (display);
}

static guintptr
gst_gl_display_default_get_handle (GstGLDisplay * display)
{
  return 0;
}

/**
 * gst_gl_display_filter_gl_api:
 * @display: a #GstGLDisplay
 * @gl_api: a #GstGLAPI to filter with
 *
 * limit the use of OpenGL to the requested @gl_api.  This is intended to allow
 * application and elements to request a specific set of OpenGL API's based on
 * what they support.  See gst_gl_context_get_gl_api() for the retreiving the
 * API supported by a #GstGLContext.
 */
void
gst_gl_display_filter_gl_api (GstGLDisplay * display, GstGLAPI gl_api)
{
  gchar *gl_api_s;

  g_return_if_fail (GST_IS_GL_DISPLAY (display));

  gl_api_s = gst_gl_api_to_string (gl_api);
  GST_TRACE_OBJECT (display, "filtering with api %s", gl_api_s);
  g_free (gl_api_s);

  GST_OBJECT_LOCK (display);
  display->priv->gl_api &= gl_api;
  GST_OBJECT_UNLOCK (display);
}

GstGLAPI
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
{
  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);

  return display->priv->gl_api;
}

/**
 * gst_gl_display_get_gl_api:
 * @display: a #GstGLDisplay
 *
 * see gst_gl_display_filter_gl_api() for what the returned value represents
 *
 * Returns: the #GstGLAPI configured for @display
 */
GstGLAPI
gst_gl_display_get_gl_api (GstGLDisplay * display)
{
  GstGLAPI ret;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);

  GST_OBJECT_LOCK (display);
  ret = display->priv->gl_api;
  GST_OBJECT_UNLOCK (display);

  return ret;
}

/**
 * gst_gl_display_get_handle_type:
 * @display: a #GstGLDisplay
 *
 * Returns: the #GstGLDisplayType of @display
 *
 * Since: 1.4
 */
GstGLDisplayType
gst_gl_display_get_handle_type (GstGLDisplay * display)
{
  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_DISPLAY_TYPE_NONE);

  return display->type;
}

/**
 * gst_context_set_gl_display:
 * @context: a #GstContext
 * @display: resulting #GstGLDisplay
 *
 * Sets @display on @context
 *
 * Since: 1.4
 */
void
gst_context_set_gl_display (GstContext * context, GstGLDisplay * display)
{
  GstStructure *s;

  g_return_if_fail (context != NULL);

  if (display)
    GST_CAT_LOG (gst_context,
        "setting GstGLDisplay(%" GST_PTR_FORMAT ") on context(%" GST_PTR_FORMAT
        ")", display, context);

  s = gst_context_writable_structure (context);
  gst_structure_set (s, GST_GL_DISPLAY_CONTEXT_TYPE, GST_TYPE_GL_DISPLAY,
      display, NULL);
}

/**
 * gst_context_get_gl_display:
 * @context: a #GstContext
 * @display: resulting #GstGLDisplay
 *
 * Returns: Whether @display was in @context
 *
 * Since: 1.4
 */
gboolean
gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display)
{
  const GstStructure *s;
  gboolean ret;

  g_return_val_if_fail (display != NULL, FALSE);
  g_return_val_if_fail (context != NULL, FALSE);

  s = gst_context_get_structure (context);
  ret = gst_structure_get (s, GST_GL_DISPLAY_CONTEXT_TYPE,
      GST_TYPE_GL_DISPLAY, display, NULL);

  GST_CAT_LOG (gst_context, "got GstGLDisplay(%p) from context(%p)", *display,
      context);

  return ret;
}

/**
 * gst_gl_display_create_context:
 * @display: a #GstGLDisplay
 * @other_context: (transfer none): other #GstGLContext to share resources with.
 * @p_context: (transfer full) (out): resulting #GstGLContext
 * @error: (allow-none): resulting #GError
 *
 * It requires the display's object lock to be held.
 *
 * Returns: whether a new context could be created.
 *
 * Since: 1.6
 */
gboolean
gst_gl_display_create_context (GstGLDisplay * display,
    GstGLContext * other_context, GstGLContext ** p_context, GError ** error)
{
  GstGLContext *context = NULL;
  gboolean ret = FALSE;

  g_return_val_if_fail (display != NULL, FALSE);
  g_return_val_if_fail (p_context != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  g_signal_emit (display, gst_gl_display_signals[CREATE_CONTEXT], 0,
      other_context, &context);

  if (context) {
    *p_context = context;
    return TRUE;
  }

  context = gst_gl_context_new (display);
  if (!context) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "Failed to create GL context");
    return FALSE;
  }

  GST_DEBUG_OBJECT (display,
      "creating context %" GST_PTR_FORMAT " from other context %"
      GST_PTR_FORMAT, context, other_context);

  ret = gst_gl_context_create (context, other_context, error);

  if (ret)
    *p_context = context;

  return ret;
}

static GstGLContext *
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
{
  GstGLContext *context = NULL;
  GList *prev = NULL, *l = display->priv->contexts;

  while (l) {
    GWeakRef *ref = l->data;
    GThread *context_thread;

    context = g_weak_ref_get (ref);
    if (!context) {
      /* remove dead contexts */
      g_weak_ref_clear (l->data);
      g_free (l->data);
      display->priv->contexts = g_list_delete_link (display->priv->contexts, l);
      l = prev ? prev->next : display->priv->contexts;
      continue;
    }

    if (thread == NULL) {
      GST_DEBUG_OBJECT (display, "Returning GL context %" GST_PTR_FORMAT " for "
          "NULL thread", context);
      return context;
    }

    context_thread = gst_gl_context_get_thread (context);
    if (thread != context_thread) {
      g_thread_unref (context_thread);
      gst_object_unref (context);
      prev = l;
      l = l->next;
      continue;
    }

    if (context_thread)
      g_thread_unref (context_thread);

    GST_DEBUG_OBJECT (display, "Returning GL context %" GST_PTR_FORMAT " for "
        "thread %p", context, thread);
    return context;
  }

  GST_DEBUG_OBJECT (display, "No GL context for thread %p", thread);
  return NULL;
}

/**
 * gst_gl_display_get_gl_context_for_thread:
 * @display: a #GstGLDisplay
 * @thread: a #GThread
 *
 * Returns: (transfer full): the #GstGLContext current on @thread or %NULL
 *
 * Must be called with the object lock held.
 *
 * Since: 1.6
 */
GstGLContext *
gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
    GThread * thread)
{
  GstGLContext *context;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);

  context = _get_gl_context_for_thread_unlocked (display, thread);
  GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread "
      "%p", context, thread);

  return context;
}

static gboolean
_check_collision (GstGLContext * context, GstGLContext * collision)
{
  GThread *thread, *collision_thread;
  gboolean ret = FALSE;

  if (!context || !collision)
    return FALSE;

  thread = gst_gl_context_get_thread (context);
  collision_thread = gst_gl_context_get_thread (collision);

  if (!thread || !collision_thread) {
    ret = FALSE;
    goto out;
  }

  if (thread == collision_thread) {
    ret = TRUE;
    goto out;
  }

out:
  if (thread)
    g_thread_unref (thread);
  if (collision_thread)
    g_thread_unref (collision_thread);

  return ret;
}

/**
 * gst_gl_display_add_context:
 * @display: a #GstGLDisplay
 * @context: (transfer none): a #GstGLContext
 *
 * Returns: whether @context was successfully added. %FALSE may be returned
 * if there already exists another context for @context's active thread.
 *
 * Must be called with the object lock held.
 *
 * Since: 1.6
 */
gboolean
gst_gl_display_add_context (GstGLDisplay * display, GstGLContext * context)
{
  GstGLContext *collision = NULL;
  GstGLDisplay *context_display;
  gboolean ret = TRUE;
  GThread *thread;
  GWeakRef *ref;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), FALSE);
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  context_display = gst_gl_context_get_display (context);
  g_assert (context_display == display);
  gst_object_unref (context_display);

  thread = gst_gl_context_get_thread (context);
  if (thread) {
    collision = _get_gl_context_for_thread_unlocked (display, thread);
    g_thread_unref (thread);

    /* adding the same context is a no-op */
    if (context == collision) {
      GST_LOG_OBJECT (display, "Attempting to add the same GL context %"
          GST_PTR_FORMAT ". Ignoring", context);
      ret = TRUE;
      goto out;
    }

    if (_check_collision (context, collision)) {
      GST_DEBUG_OBJECT (display, "Collision detected adding GL context "
          "%" GST_PTR_FORMAT, context);
      ret = FALSE;
      goto out;
    }
  }

  ref = g_new0 (GWeakRef, 1);
  g_weak_ref_init (ref, context);

  GST_DEBUG_OBJECT (display, "Adding GL context %" GST_PTR_FORMAT, context);
  display->priv->contexts = g_list_prepend (display->priv->contexts, ref);

out:
  if (collision)
    gst_object_unref (collision);

  GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT,
      ret ? "" : "un", context);

  return ret;
}
