/*
 * 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:gstglcontext
 * @short_description: OpenGL context abstraction
 * @title: GstGLContext
 * @see_also: #GstGLDisplay, #GstGLWindow
 *
 * #GstGLContext wraps an OpenGL context object in a uniform API.  As a result
 * of the limitation on OpenGL context, this object is not thread safe unless
 * specified and must only be activated in a single thread.
 */

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

#if defined(ANDROID) || defined(__ANDROID__)
/* Avoid a linker error with _isoc99_sscanf() when building a shared library
 * for android
 */
#define _GNU_SOURCE
#endif

#include "gstglcontext.h"
#include <gst/gl/gl.h>

#include <gmodule.h>
#include <string.h>
#include <stdio.h>

#include "gstglcontext_private.h"
#include "gstglfeature.h"
#include "gstglfeature_private.h"
#include "gstglfuncs.h"

#ifndef GL_NUM_EXTENSIONS
#define GL_NUM_EXTENSIONS 0x0000821d
#endif

#if GST_GL_HAVE_PLATFORM_GLX
#include "x11/gstglcontext_glx.h"
#endif
#if GST_GL_HAVE_PLATFORM_EGL
#include "egl/gstglcontext_egl.h"
#endif
#if GST_GL_HAVE_PLATFORM_CGL
#include "cocoa/gstglcontext_cocoa.h"
#endif
#if GST_GL_HAVE_PLATFORM_WGL
#include "win32/gstglcontext_wgl.h"
#endif
#if GST_GL_HAVE_PLATFORM_EAGL
#include "eagl/gstglcontext_eagl.h"
#endif

extern void _gst_gl_debug_enable (GstGLContext * context);

static GPrivate current_context_key;

static GModule *module_self;
static GOnce module_self_gonce = G_ONCE_INIT;

#if GST_GL_HAVE_OPENGL
static GOnce module_opengl_gonce = G_ONCE_INIT;
static GModule *module_opengl;

static gpointer
load_opengl_module (gpointer user_data)
{
#ifdef GST_GL_LIBGL_MODULE_NAME
  module_opengl = g_module_open (GST_GL_LIBGL_MODULE_NAME, G_MODULE_BIND_LAZY);
#else
  /* On Linux the .so is only in -dev packages, try with a real soname
   * Proper compilers will optimize away the strcmp */
  if (g_strcmp0 (G_MODULE_SUFFIX, "so") == 0)
    module_opengl = g_module_open ("libGL.so.1", G_MODULE_BIND_LAZY);

  /* This automatically handles the suffix and even .la files */
  if (!module_opengl)
    module_opengl = g_module_open ("libGL", G_MODULE_BIND_LAZY);
#endif

  return NULL;
}
#endif

#if GST_GL_HAVE_GLES2
static GOnce module_gles2_gonce = G_ONCE_INIT;
static GModule *module_gles2;

static gpointer
load_gles2_module (gpointer user_data)
{
#ifdef GST_GL_LIBGLESV2_MODULE_NAME
  module_gles2 =
      g_module_open (GST_GL_LIBGLESV2_MODULE_NAME, G_MODULE_BIND_LAZY);
#else
  /* On Linux the .so is only in -dev packages, try with a real soname
   * Proper compilers will optimize away the strcmp */
  if (g_strcmp0 (G_MODULE_SUFFIX, "so") == 0)
    module_gles2 = g_module_open ("libGLESv2.so.2", G_MODULE_BIND_LAZY);

  /* This automatically handles the suffix and even .la files */
  if (!module_gles2)
    module_gles2 = g_module_open ("libGLESv2", G_MODULE_BIND_LAZY);

#endif

  return NULL;
}
#endif

static gpointer
load_self_module (gpointer user_data)
{
  module_self = g_module_open (NULL, G_MODULE_BIND_LAZY);

  return NULL;
}

/* Context sharedness is tracked by a refcounted pointer stored in each context
 * object to track complex creation/deletion scenarios.  As a result,
 * sharedness can only be successfully validated between two GstGLContext's
 * where one is not a wrapped context.
 *
 * As there is no API at the winsys level to tell whether two OpenGL contexts
 * can share GL resources, this is the next best thing.
 *
 * XXX: we may need a way to associate two wrapped GstGLContext's as being
 * shared however I have not come across a use case that requries this yet.
 */
struct ContextShareGroup
{
  volatile int refcount;
};

static struct ContextShareGroup *
_context_share_group_new (void)
{
  struct ContextShareGroup *ret = g_new0 (struct ContextShareGroup, 1);

  ret->refcount = 1;

  return ret;
}

static struct ContextShareGroup *
_context_share_group_ref (struct ContextShareGroup *share)
{
  g_atomic_int_inc (&share->refcount);
  return share;
}

static void
_context_share_group_unref (struct ContextShareGroup *share)
{
  if (g_atomic_int_dec_and_test (&share->refcount))
    g_free (share);
}

static gboolean
_context_share_group_is_shared (struct ContextShareGroup *share)
{
  return g_atomic_int_get (&share->refcount) > 1;
}

#define GST_CAT_DEFAULT gst_gl_context_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY_STATIC (gst_gl_debug);

#define gst_gl_context_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE (GstGLContext, gst_gl_context, GST_TYPE_OBJECT);

#define GST_GL_CONTEXT_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_CONTEXT, GstGLContextPrivate))

static void _init_debug (void);

static gpointer gst_gl_context_create_thread (GstGLContext * context);
static void gst_gl_context_finalize (GObject * object);
static void gst_gl_context_default_get_gl_platform_version (GstGLContext *
    context, gint * major, gint * minor);

struct _GstGLContextPrivate
{
  GThread *gl_thread;
  GThread *active_thread;

  /* conditions */
  GMutex render_lock;
  GCond create_cond;
  GCond destroy_cond;

  gboolean created;
  gboolean alive;

  GWeakRef other_context_ref;
  struct ContextShareGroup *sharegroup;
  GError **error;

  gint gl_major;
  gint gl_minor;

  gchar *gl_exts;
};

typedef struct
{
  GstGLContext parent;

  guintptr handle;
  GstGLPlatform platform;
  GstGLAPI available_apis;
} GstGLWrappedContext;

typedef struct
{
  GstGLContextClass parent;
} GstGLWrappedContextClass;

#define GST_TYPE_GL_WRAPPED_CONTEXT (gst_gl_wrapped_context_get_type())
static GType gst_gl_wrapped_context_get_type (void);
G_DEFINE_TYPE (GstGLWrappedContext, gst_gl_wrapped_context,
    GST_TYPE_GL_CONTEXT);

#define GST_GL_WRAPPED_CONTEXT(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_GL_WRAPPED_CONTEXT, GstGLWrappedContext))
#define GST_GL_WRAPPED_CONTEXT_CLASS(k)     (G_TYPE_CHECK_CLASS((k), GST_TYPE_GL_CONTEXT, GstGLContextClass))
#define GST_IS_GL_WRAPPED_CONTEXT(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_GL_WRAPPED_CONTEXT))
#define GST_IS_GL_WRAPPED_CONTEXT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_GL_WRAPPED_CONTEXT))
#define GST_GL_WRAPPED_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_GL_WRAPPED_CONTEXT, GstGLWrappedContextClass))

GQuark
gst_gl_context_error_quark (void)
{
  return g_quark_from_static_string ("gst-gl-context-error-quark");
}

static void
_ensure_window (GstGLContext * context)
{
  GstGLWindow *window;

  if (context->window)
    return;

  window = gst_gl_display_create_window (context->display);

  gst_gl_context_set_window (context, window);

  gst_object_unref (window);
}

static void
gst_gl_context_init (GstGLContext * context)
{
  context->priv = GST_GL_CONTEXT_GET_PRIVATE (context);

  context->window = NULL;
  context->gl_vtable = g_slice_alloc0 (sizeof (GstGLFuncs));

  g_mutex_init (&context->priv->render_lock);

  g_cond_init (&context->priv->create_cond);
  g_cond_init (&context->priv->destroy_cond);
  context->priv->created = FALSE;

  g_weak_ref_init (&context->priv->other_context_ref, NULL);
}

static void
gst_gl_context_class_init (GstGLContextClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLContextPrivate));

  klass->get_proc_address =
      GST_DEBUG_FUNCPTR (gst_gl_context_default_get_proc_address);
  klass->get_gl_platform_version =
      GST_DEBUG_FUNCPTR (gst_gl_context_default_get_gl_platform_version);

  G_OBJECT_CLASS (klass)->finalize = gst_gl_context_finalize;

  _init_debug ();
}

static void
_init_debug (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (gst_gl_context_debug, "glcontext", 0,
        "glcontext element");
    GST_DEBUG_CATEGORY_INIT (gst_gl_debug, "gldebug", 0, "OpenGL Debugging");
    g_once_init_leave (&_init, 1);
  }
}

/**
 * gst_gl_context_new:
 * @display: a #GstGLDisplay
 *
 * Create a new #GstGLContext with the specified @display
 *
 * Returns: a new #GstGLContext
 *
 * Since: 1.4
 */
GstGLContext *
gst_gl_context_new (GstGLDisplay * display)
{
  GstGLContext *context = NULL;
  const gchar *user_choice;

  _init_debug ();

  user_choice = g_getenv ("GST_GL_PLATFORM");
  GST_INFO ("creating a context for display %" GST_PTR_FORMAT
      ", user choice:%s", display, user_choice);
#if GST_GL_HAVE_PLATFORM_CGL
  if (!context && (!user_choice || g_strstr_len (user_choice, 3, "cgl")))
    context = GST_GL_CONTEXT (gst_gl_context_cocoa_new (display));
#endif
#if GST_GL_HAVE_PLATFORM_GLX
  if (!context && (!user_choice || g_strstr_len (user_choice, 3, "glx")))
    context = GST_GL_CONTEXT (gst_gl_context_glx_new (display));
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (!context && (!user_choice || g_strstr_len (user_choice, 3, "egl")))
    context = GST_GL_CONTEXT (gst_gl_context_egl_new (display));
#endif
#if GST_GL_HAVE_PLATFORM_WGL
  if (!context && (!user_choice || g_strstr_len (user_choice, 3, "wgl")))
    context = GST_GL_CONTEXT (gst_gl_context_wgl_new (display));
#endif
#if GST_GL_HAVE_PLATFORM_EAGL
  if (!context && (!user_choice || g_strstr_len (user_choice, 4, "eagl")))
    context = GST_GL_CONTEXT (gst_gl_context_eagl_new (display));
#endif

  if (!context) {
    /* subclass returned a NULL context */
    GST_WARNING ("Could not create context. user specified %s",
        user_choice ? user_choice : "(null)");

    return NULL;
  }

  context->display = gst_object_ref (display);

  GST_DEBUG_OBJECT (context,
      "Done creating context for display %" GST_PTR_FORMAT " (user_choice:%s)",
      display, user_choice);

  return context;
}

/**
 * gst_gl_context_new_wrapped:
 * @display: a #GstGLDisplay
 * @handle: the OpenGL context to wrap
 * @context_type: a #GstGLPlatform specifying the type of context in @handle
 * @available_apis: a #GstGLAPI containing the available OpenGL apis in @handle
 *
 * Wraps an existing OpenGL context into a #GstGLContext.
 *
 * Note: The caller is responsible for ensuring that the OpenGL context
 * represented by @handle stays alive while the returned #GstGLContext is
 * active.
 *
 * Returns: (transfer full): a #GstGLContext wrapping @handle
 *
 * Since: 1.4
 */
GstGLContext *
gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
    GstGLPlatform context_type, GstGLAPI available_apis)
{
  GstGLContext *context;
  GstGLWrappedContext *context_wrap = NULL;
  GstGLContextClass *context_class;
  GstGLAPI display_api;

  _init_debug ();

  display_api = gst_gl_display_get_gl_api (display);
  g_return_val_if_fail ((display_api & available_apis) != GST_GL_API_NONE,
      NULL);

  context_wrap = g_object_new (GST_TYPE_GL_WRAPPED_CONTEXT, NULL);
  gst_object_ref_sink (context_wrap);

  if (!context_wrap) {
    /* subclass returned a NULL context */
    GST_ERROR ("Could not wrap existing context");

    return NULL;
  }

  context = (GstGLContext *) context_wrap;

  context->display = gst_object_ref (display);
  context->priv->sharegroup = _context_share_group_new ();
  context_wrap->handle = handle;
  context_wrap->platform = context_type;
  context_wrap->available_apis = available_apis;

  context_class = GST_GL_CONTEXT_GET_CLASS (context);

#if GST_GL_HAVE_PLATFORM_GLX
  if (context_type == GST_GL_PLATFORM_GLX) {
    context_class->get_current_context = gst_gl_context_glx_get_current_context;
    context_class->get_proc_address = gst_gl_context_glx_get_proc_address;
  }
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (context_type == GST_GL_PLATFORM_EGL) {
    context_class->get_current_context = gst_gl_context_egl_get_current_context;
    context_class->get_proc_address = gst_gl_context_egl_get_proc_address;
  }
#endif
#if GST_GL_HAVE_PLATFORM_CGL
  if (context_type == GST_GL_PLATFORM_CGL) {
    context_class->get_current_context =
        gst_gl_context_cocoa_get_current_context;
    context_class->get_proc_address = gst_gl_context_default_get_proc_address;
  }
#endif
#if GST_GL_HAVE_PLATFORM_WGL
  if (context_type == GST_GL_PLATFORM_WGL) {
    context_class->get_current_context = gst_gl_context_wgl_get_current_context;
    context_class->get_proc_address = gst_gl_context_wgl_get_proc_address;
  }
#endif
#if GST_GL_HAVE_PLATFORM_EAGL
  if (context_type == GST_GL_PLATFORM_EAGL) {
    context_class->get_current_context =
        gst_gl_context_eagl_get_current_context;
    context_class->get_proc_address = gst_gl_context_default_get_proc_address;
  }
#endif

  if (!context_class->get_current_context) {
    /* we don't have API support */
    gst_object_unref (context);
    return NULL;
  }

  return context;
}

/**
 * gst_gl_context_get_current_gl_context:
 * @context_type: a #GstGLPlatform specifying the type of context to retrieve
 *
 * Returns: The OpenGL context handle current in the calling thread or %NULL
 *
 * Since: 1.6
 */
guintptr
gst_gl_context_get_current_gl_context (GstGLPlatform context_type)
{
  guintptr handle = 0;

  _init_debug ();

#if GST_GL_HAVE_PLATFORM_GLX
  if (!handle && (context_type & GST_GL_PLATFORM_GLX) != 0)
    handle = gst_gl_context_glx_get_current_context ();
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (!handle && (context_type & GST_GL_PLATFORM_EGL) != 0)
    handle = gst_gl_context_egl_get_current_context ();
#endif
#if GST_GL_HAVE_PLATFORM_CGL
  if (!handle && (context_type & GST_GL_PLATFORM_CGL) != 0)
    handle = gst_gl_context_cocoa_get_current_context ();
#endif
#if GST_GL_HAVE_PLATFORM_WGL
  if (!handle && (context_type & GST_GL_PLATFORM_WGL) != 0)
    handle = gst_gl_context_wgl_get_current_context ();
#endif
#if GST_GL_HAVE_PLATFORM_EAGL
  if (!handle && (context_type & GST_GL_PLATFORM_EAGL) != 0)
    handle = gst_gl_context_eagl_get_current_context ();
#endif

  if (!handle)
    GST_WARNING ("Could not retrieve current context");

  return handle;
}

/**
 * gst_gl_context_get_proc_address_with_platform:
 * @context_type: a #GstGLPlatform
 * @gl_api: a #GstGLAPI
 * @name: the name of the function to retrieve
 *
 * Attempts to use the @context_type specific GetProcAddress implementations
 * to retreive @name.
 *
 * See also gst_gl_context_get_proc_address().
 *
 * Returns: a function pointer for @name, or %NULL
 *
 * Since: 1.6
 */
gpointer
gst_gl_context_get_proc_address_with_platform (GstGLPlatform context_type,
    GstGLAPI gl_api, const gchar * name)
{
  gpointer ret = NULL;

#if GST_GL_HAVE_PLATFORM_GLX
  if (!ret && (context_type & GST_GL_PLATFORM_GLX) != 0)
    ret = gst_gl_context_glx_get_proc_address (gl_api, name);
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (!ret && (context_type & GST_GL_PLATFORM_EGL) != 0)
    ret = gst_gl_context_egl_get_proc_address (gl_api, name);
#endif
#if GST_GL_HAVE_PLATFORM_WGL
  if (!ret && (context_type & GST_GL_PLATFORM_WGL) != 0)
    ret = gst_gl_context_wgl_get_proc_address (gl_api, name);
#endif
  /* CGL and EAGL rely on the default impl */

  if (!ret)
    ret = gst_gl_context_default_get_proc_address (gl_api, name);

  return ret;
}

/**
 * gst_gl_context_get_current_gl_api:
 * @platform: the #GstGLPlatform to retrieve the API for
 * @major: (out) (allow-none): the major version
 * @minor: (out) (allow-none): the minor version
 *
 * If an error occurs, @major and @minor are not modified and %GST_GL_API_NONE is
 * returned.
 *
 * Returns: The version supported by the OpenGL context current in the calling
 *          thread or %GST_GL_API_NONE
 *
 * Since: 1.6
 */
GstGLAPI
gst_gl_context_get_current_gl_api (GstGLPlatform platform, guint * major,
    guint * minor)
{
  const GLubyte *(GSTGLAPI * GetString) (GLenum name);
#if GST_GL_HAVE_OPENGL
  void (GSTGLAPI * GetIntegerv) (GLenum name, GLuint * n);
#endif
  const gchar *version;
  gint maj, min, n;
  GstGLAPI ret = (1U << 31);

  _init_debug ();

  while (ret != GST_GL_API_NONE) {
    /* FIXME: attempt to delve into the platform specific GetProcAddress */
    GetString =
        gst_gl_context_get_proc_address_with_platform (platform, ret,
        "glGetString");
#if GST_GL_HAVE_OPENGL
    GetIntegerv =
        gst_gl_context_get_proc_address_with_platform (platform, ret,
        "glGetIntegerv");
#endif
    if (!GetString) {
      goto next;
    }

    version = (const gchar *) GetString (GL_VERSION);
    if (!version)
      goto next;

    /* strlen (x.x) == 3 */
    n = strlen (version);
    if (n < 3)
      goto next;

    if (g_strstr_len (version, 9, "OpenGL ES")) {
      /* strlen (OpenGL ES x.x) == 13 */
      if (n < 13)
        goto next;

      sscanf (&version[10], "%d.%d", &maj, &min);

      if (maj <= 0 || min < 0)
        goto next;

      if (maj == 1) {
        ret = GST_GL_API_GLES1;
        break;
      } else if (maj == 2 || maj == 3) {
        ret = GST_GL_API_GLES2;
        break;
      }

      goto next;
    } else {
      sscanf (version, "%d.%d", &maj, &min);

      if (maj <= 0 || min < 0)
        goto next;

#if GST_GL_HAVE_OPENGL
      if (GetIntegerv && (maj > 3 || (maj == 3 && min > 1))) {
        GLuint context_flags = 0;

        ret = GST_GL_API_NONE;
        GetIntegerv (GL_CONTEXT_PROFILE_MASK, &context_flags);
        if (context_flags & GL_CONTEXT_CORE_PROFILE_BIT)
          ret |= GST_GL_API_OPENGL3;
        if (context_flags & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
          ret |= GST_GL_API_OPENGL;
        break;
      }
#endif
      ret = GST_GL_API_OPENGL;
      break;
    }

  next:
    /* iterate through the apis */
    ret >>= 1;
  }

  if (ret == GST_GL_API_NONE)
    return GST_GL_API_NONE;

  if (major)
    *major = maj;
  if (minor)
    *minor = min;

  return ret;
}

static void
gst_gl_context_finalize (GObject * object)
{
  GstGLContext *context = GST_GL_CONTEXT (object);

  if (context->window) {
    gst_gl_window_set_resize_callback (context->window, NULL, NULL, NULL);
    gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);

    g_mutex_lock (&context->priv->render_lock);
    if (context->priv->alive) {
      GST_INFO_OBJECT (context, "send quit gl window loop");
      gst_gl_window_quit (context->window);

      GST_INFO_OBJECT (context, "joining gl thread");
      while (context->priv->alive)
        g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
      GST_INFO_OBJECT (context, "gl thread joined");

      if (context->priv->gl_thread) {
        g_thread_unref (context->priv->gl_thread);
        context->priv->gl_thread = NULL;
      }
    }
    g_mutex_unlock (&context->priv->render_lock);

    gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
    gst_object_unref (context->window);
    context->window = NULL;
  }

  if (context->priv->active_thread) {
    g_thread_unref (context->priv->active_thread);
    context->priv->active_thread = NULL;
  }

  if (context->priv->gl_thread) {
    g_thread_unref (context->priv->gl_thread);
    context->priv->gl_thread = NULL;
  }

  if (context->priv->sharegroup) {
    _context_share_group_unref (context->priv->sharegroup);
    context->priv->sharegroup = NULL;
  }

  if (context->display) {
    gst_object_unref (context->display);
    context->display = NULL;
  }

  if (context->gl_vtable) {
    g_slice_free (GstGLFuncs, context->gl_vtable);
    context->gl_vtable = NULL;
  }

  g_mutex_clear (&context->priv->render_lock);

  g_cond_clear (&context->priv->create_cond);
  g_cond_clear (&context->priv->destroy_cond);

  g_free (context->priv->gl_exts);
  g_weak_ref_clear (&context->priv->other_context_ref);

  GST_DEBUG_OBJECT (context, "End of finalize");
  G_OBJECT_CLASS (gst_gl_context_parent_class)->finalize (object);
}

/**
 * gst_gl_context_activate:
 * @context: a #GstGLContext
 * @activate: %TRUE to activate, %FALSE to deactivate
 *
 * (De)activate the OpenGL context represented by this @context.
 *
 * In OpenGL terms, calls eglMakeCurrent or similar with this context and the
 * currently set window.  See gst_gl_context_set_window() for details.
 *
 * Returns: Whether the activation succeeded
 *
 * Since: 1.4
 */
gboolean
gst_gl_context_activate (GstGLContext * context, gboolean activate)
{
  GstGLContextClass *context_class;
  gboolean result;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_val_if_fail (context_class->activate != NULL, FALSE);

  GST_DEBUG_OBJECT (context, "activate:%d", activate);

  GST_OBJECT_LOCK (context);
  result = context_class->activate (context, activate);

  if (result && activate) {
    GThread *old_thread = context->priv->active_thread;
    context->priv->active_thread = g_thread_ref (g_thread_self ());
    if (old_thread) {
      g_thread_unref (old_thread);
    }

    g_private_set (&current_context_key, context);
  } else {
    if (context->priv->active_thread) {
      g_thread_unref (context->priv->active_thread);
      context->priv->active_thread = NULL;
    }
    g_private_set (&current_context_key, NULL);
  }
  GST_OBJECT_UNLOCK (context);

  return result;
}

/**
 * gst_gl_context_get_thread:
 * @context: a #GstGLContext
 *
 * Returns: (transfer full): The #GThread, @context is current in or NULL
 *
 * Since: 1.6
 */
GThread *
gst_gl_context_get_thread (GstGLContext * context)
{
  GThread *ret;

  GST_OBJECT_LOCK (context);
  ret = context->priv->active_thread;
  if (ret)
    g_thread_ref (ret);
  GST_OBJECT_UNLOCK (context);

  return ret;
}

/**
 * gst_gl_context_get_gl_api:
 * @context: a #GstGLContext
 *
 * Get the currently enabled OpenGL api.
 *
 * The currently available API may be limited by the #GstGLDisplay in use and/or
 * the #GstGLWindow chosen.
 *
 * Returns: the available OpenGL api
 *
 * Since: 1.4
 */
GstGLAPI
gst_gl_context_get_gl_api (GstGLContext * context)
{
  GstGLContextClass *context_class;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), GST_GL_API_NONE);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_val_if_fail (context_class->get_gl_api != NULL, GST_GL_API_NONE);

  return context_class->get_gl_api (context);
}

/**
 * gst_gl_context_get_proc_address:
 * @context: a #GstGLContext
 * @name: an opengl function name
 *
 * Get a function pointer to a specified opengl function, @name.  If the the
 * specific function does not exist, NULL is returned instead.
 *
 * Platform specfic functions (names starting 'egl', 'glX', 'wgl', etc) can also
 * be retrieved using this method.
 *
 * Note: This function may return valid function pointers that may not be valid
 * to call in @context.  The caller is responsible for ensuring that the
 * returned function is a valid function to call in @context by either checking
 * the OpenGL API and version or for an appropriate OpenGL extension.
 *
 * Note: On success, you need to cast the returned function pointer to the
 * correct type to be able to call it correctly.  On 32-bit Windows, this will
 * include the %GSTGLAPI identifier to use the correct calling convention.
 * e.g.
 *
 * |[<!-- language="C" -->
 * void (GSTGLAPI *PFN_glGetIntegerv) (GLenum name, GLint * ret)
 * ]|
 *
 * Returns: a function pointer or %NULL
 *
 * Since: 1.4
 */
gpointer
gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
{
  gpointer ret;
  GstGLContextClass *context_class;
  GstGLAPI gl_api;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_val_if_fail (context_class->get_proc_address != NULL, NULL);

  gl_api = gst_gl_context_get_gl_api (context);
  ret = context_class->get_proc_address (gl_api, name);

  return ret;
}

/**
 * gst_gl_context_default_get_proc_address:
 * @gl_api: a #GstGLAPI
 * @name: then function to get the address of
 *
 * A default implementation of the various GetProcAddress functions that looks
 * for @name in the OpenGL shared libraries or in the current process.
 *
 * See also: gst_gl_context_get_proc_address()
 *
 * Returns: an address pointing to @name or %NULL
 *
 * Since: 1.4
 */
gpointer
gst_gl_context_default_get_proc_address (GstGLAPI gl_api, const gchar * name)
{
  gpointer ret = NULL;

  /* First try to load symbol from the selected GL API for this context */
#if GST_GL_HAVE_GLES2
  if (!ret && (gl_api & GST_GL_API_GLES2)) {
    g_once (&module_gles2_gonce, load_gles2_module, NULL);
    if (module_gles2)
      g_module_symbol (module_gles2, name, &ret);
  }
#endif

#if GST_GL_HAVE_OPENGL
  if (!ret && (gl_api & (GST_GL_API_OPENGL | GST_GL_API_OPENGL3))) {
    g_once (&module_opengl_gonce, load_opengl_module, NULL);
    if (module_opengl)
      g_module_symbol (module_opengl, name, &ret);
  }
#endif

  /* Otherwise fall back to the current module */
  g_once (&module_self_gonce, load_self_module, NULL);
  if (!ret)
    g_module_symbol (module_self, name, &ret);

  return ret;
}

/**
 * gst_gl_context_set_window:
 * @context: a #GstGLContext
 * @window: (transfer full): a #GstGLWindow
 *
 * Set's the current window on @context to @window.  The window can only be
 * changed before gst_gl_context_create() has been called and the @window is not
 * already running.
 *
 * Returns: Whether the window was successfully updated
 *
 * Since: 1.4
 */
gboolean
gst_gl_context_set_window (GstGLContext * context, GstGLWindow * window)
{
  g_return_val_if_fail (!GST_IS_GL_WRAPPED_CONTEXT (context), FALSE);

  GST_DEBUG_OBJECT (context, "window:%" GST_PTR_FORMAT, window);

  /* we can't change the window while we are running */
  if (context->priv->alive)
    return FALSE;

  if (window)
    g_weak_ref_set (&window->context_ref, context);

  if (context->window)
    gst_object_unref (context->window);

  context->window = window ? gst_object_ref (window) : NULL;

  return TRUE;
}

/**
 * gst_gl_context_get_window:
 * @context: a #GstGLContext
 *
 * Returns: (transfer full) (nullable): the currently set window
 *
 * Since: 1.4
 */
GstGLWindow *
gst_gl_context_get_window (GstGLContext * context)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);

  if (GST_IS_GL_WRAPPED_CONTEXT (context)) {
    GST_WARNING_OBJECT (context, "context is not toplevel, returning NULL");
    return NULL;
  }

  _ensure_window (context);

  return gst_object_ref (context->window);
}

/**
 * gst_gl_context_can_share:
 * @context: a #GstGLContext
 * @other_context: another #GstGLContext
 *
 * Note: This will always fail for two wrapped #GstGLContext's
 *
 * Returns: whether @context and @other_context are able to share OpenGL
 *      resources.
 *
 * Since: 1.6
 */
gboolean
gst_gl_context_can_share (GstGLContext * context, GstGLContext * other_context)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
  g_return_val_if_fail (GST_IS_GL_CONTEXT (other_context), FALSE);

  /* check if the contexts are descendants or the root nodes are the same */
  return context->priv->sharegroup != NULL
      && context->priv->sharegroup == other_context->priv->sharegroup;
}

/**
 * gst_gl_context_create:
 * @context: a #GstGLContext:
 * @other_context: (allow-none): a #GstGLContext to share OpenGL objects with
 * @error: (allow-none): a #GError
 *
 * Creates an OpenGL context with the specified @other_context as a context
 * to share shareable OpenGL objects with.  See the OpenGL specification for
 * what is shared between OpenGL contexts.
 *
 * If an error occurs, and @error is not %NULL, then error will contain details
 * of the error and %FALSE will be returned.
 *
 * Should only be called once.
 *
 * Returns: whether the context could successfully be created
 *
 * Since: 1.4
 */
gboolean
gst_gl_context_create (GstGLContext * context,
    GstGLContext * other_context, GError ** error)
{
  gboolean alive = FALSE;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
  g_return_val_if_fail (!GST_IS_GL_WRAPPED_CONTEXT (context), FALSE);

  GST_DEBUG_OBJECT (context, " other_context:%" GST_PTR_FORMAT, other_context);

  _ensure_window (context);

  g_mutex_lock (&context->priv->render_lock);

  if (!context->priv->created) {
    g_weak_ref_set (&context->priv->other_context_ref, other_context);
    context->priv->error = error;
    if (other_context == NULL)
      context->priv->sharegroup = _context_share_group_new ();
    else
      context->priv->sharegroup =
          _context_share_group_ref (other_context->priv->sharegroup);

    context->priv->gl_thread = g_thread_new ("gstglcontext",
        (GThreadFunc) gst_gl_context_create_thread, context);

    while (!context->priv->created)
      g_cond_wait (&context->priv->create_cond, &context->priv->render_lock);

    GST_INFO_OBJECT (context, "gl thread created");
  }

  alive = context->priv->alive;

  g_mutex_unlock (&context->priv->render_lock);

  return alive;
}

static gboolean
_create_context_info (GstGLContext * context, GstGLAPI gl_api, gint * gl_major,
    gint * gl_minor, GError ** error)
{
  const GstGLFuncs *gl;
  guint maj = 0, min = 0;
  GLenum gl_err = GL_NO_ERROR;
  const gchar *opengl_version = NULL;

  gl = context->gl_vtable;

  if (!gl->GetString || !gl->GetString (GL_VERSION)) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "glGetString not defined or returned invalid value");
    return FALSE;
  }

  if (!gl->GetString (GL_SHADING_LANGUAGE_VERSION)) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "No GL shader support available");
    return FALSE;
  }

  GST_INFO_OBJECT (context, "GL_VERSION: %s",
      GST_STR_NULL ((const gchar *) gl->GetString (GL_VERSION)));
  GST_INFO_OBJECT (context, "GL_SHADING_LANGUAGE_VERSION: %s",
      GST_STR_NULL ((const gchar *)
          gl->GetString (GL_SHADING_LANGUAGE_VERSION)));
  GST_INFO_OBJECT (context, "GL_VENDOR: %s",
      GST_STR_NULL ((const gchar *) gl->GetString (GL_VENDOR)));
  GST_INFO_OBJECT (context, "GL_RENDERER: %s",
      GST_STR_NULL ((const gchar *) gl->GetString (GL_RENDERER)));

  gl_err = gl->GetError ();
  if (gl_err != GL_NO_ERROR) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "glGetString error: 0x%x", gl_err);
    return FALSE;
  }

  opengl_version = (const gchar *) gl->GetString (GL_VERSION);
  if (opengl_version && gl_api & GST_GL_API_GLES2)
    /* gles starts with "OpenGL ES " */
    opengl_version = &opengl_version[10];

  if (opengl_version)
    sscanf (opengl_version, "%d.%d", &maj, &min);

  /* OpenGL > 1.2.0 */
  if (gl_api & GST_GL_API_OPENGL || gl_api & GST_GL_API_OPENGL3) {
    if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
      g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_OLD_LIBS,
          "OpenGL >= 1.2.0 required, found %u.%u", maj, min);
      return FALSE;
    }
  }

  if (gl_major)
    *gl_major = maj;
  if (gl_minor)
    *gl_minor = min;

  return TRUE;
}

static GstGLAPI
_compiled_api (void)
{
  GstGLAPI ret = GST_GL_API_NONE;

#if GST_GL_HAVE_OPENGL
  ret |= GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
#endif
#if GST_GL_HAVE_GLES2
  ret |= GST_GL_API_GLES2;
#endif

  return ret;
}

static void
_unlock_create_thread (GstGLContext * context)
{
  context->priv->created = TRUE;
  GST_INFO_OBJECT (context, "gl thread running");
  g_cond_signal (&context->priv->create_cond);
  g_mutex_unlock (&context->priv->render_lock);
}

static GString *
_build_extension_string (GstGLContext * context)
{
  const GstGLFuncs *gl = context->gl_vtable;
  GString *ext_g_str = g_string_sized_new (1024);
  const gchar *ext_const_c_str = NULL;
  GLint i = 0;
  GLint n = 0;

  gl->GetIntegerv (GL_NUM_EXTENSIONS, &n);

  for (i = 0; i < n; i++) {
    ext_const_c_str = (const gchar *) gl->GetStringi (GL_EXTENSIONS, i);
    if (ext_const_c_str)
      g_string_append_printf (ext_g_str, "%s ", ext_const_c_str);
  }

  return ext_g_str;
}

//gboolean
//gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error)
static gpointer
gst_gl_context_create_thread (GstGLContext * context)
{
  GstGLContextClass *context_class;
  GstGLWindowClass *window_class;
  GstGLAPI compiled_api, user_api, gl_api, display_api;
  gchar *api_string;
  gchar *compiled_api_s;
  gchar *user_api_s;
  gchar *display_api_s;
  const gchar *user_choice;
  GError **error;
  GstGLContext *other_context;

  g_mutex_lock (&context->priv->render_lock);

  GST_DEBUG_OBJECT (context, "Creating thread");

  error = context->priv->error;
  other_context = g_weak_ref_get (&context->priv->other_context_ref);

  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  window_class = GST_GL_WINDOW_GET_CLASS (context->window);

  display_api = gst_gl_display_get_gl_api_unlocked (context->display);
  if (display_api == GST_GL_API_NONE) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
        "Cannot create context with satisfying requested apis "
        "(display has no GL api!)");
    goto failure;
  }

  if (window_class->open) {
    if (!window_class->open (context->window, error)) {
      GST_WARNING_OBJECT (context, "Failed to open window");
      g_assert (error == NULL || *error != NULL);
      goto failure;
    }
  }

  compiled_api = _compiled_api ();
  compiled_api_s = gst_gl_api_to_string (compiled_api);

  user_choice = g_getenv ("GST_GL_API");
  user_api = gst_gl_api_from_string (user_choice);
  user_api_s = gst_gl_api_to_string (user_api);

  display_api_s = gst_gl_api_to_string (display_api);

  if ((user_api & compiled_api & display_api) == GST_GL_API_NONE) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
        "Cannot create context with the user requested api (%s).  "
        "We have support for (%s), display api (%s)", user_api_s,
        compiled_api_s, display_api_s);
    g_free (user_api_s);
    g_free (compiled_api_s);
    g_free (display_api_s);
    goto failure;
  }

  if (context_class->choose_format &&
      !context_class->choose_format (context, error)) {
    GST_WARNING_OBJECT (context, "Failed to choose format");
    g_assert (error == NULL || *error != NULL);
    g_free (compiled_api_s);
    g_free (user_api_s);
    g_free (display_api_s);
    goto failure;
  }

  GST_INFO_OBJECT (context,
      "Attempting to create opengl context. user chosen api(s) (%s), "
      "compiled api support (%s) display api (%s)", user_api_s, compiled_api_s,
      display_api_s);

  if (!context_class->create_context (context,
          compiled_api & user_api & display_api, other_context, error)) {
    GST_WARNING_OBJECT (context, "Failed to create context");
    g_assert (error == NULL || *error != NULL);
    g_free (compiled_api_s);
    g_free (user_api_s);
    g_free (display_api_s);
    goto failure;
  }
  GST_INFO_OBJECT (context, "created context");

  if (!gst_gl_context_activate (context, TRUE)) {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
        "Failed to activate the GL Context");
    g_free (compiled_api_s);
    g_free (user_api_s);
    g_free (display_api_s);
    goto failure;
  }

  gl_api = gst_gl_context_get_gl_api (context);
  g_assert (gl_api != GST_GL_API_NONE && gl_api != GST_GL_API_ANY);

  api_string = gst_gl_api_to_string (gl_api);
  GST_INFO_OBJECT (context, "available GL APIs: %s", api_string);

  if (((compiled_api & gl_api & display_api) & user_api) == GST_GL_API_NONE) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
        "failed to create context, context "
        "could not provide correct api. user (%s), compiled (%s), context (%s)",
        user_api_s, compiled_api_s, api_string);
    g_free (api_string);
    g_free (compiled_api_s);
    g_free (user_api_s);
    g_free (display_api_s);
    goto failure;
  }

  g_free (api_string);
  g_free (compiled_api_s);
  g_free (user_api_s);
  g_free (display_api_s);

  GST_DEBUG_OBJECT (context, "Filling info");
  if (!gst_gl_context_fill_info (context, error)) {
    g_assert (error == NULL || *error != NULL);
    goto failure;
  }

  context->priv->alive = TRUE;

#if !defined(GST_DISABLE_GST_DEBUG)
  _gst_gl_debug_enable (context);
#endif

  if (other_context) {
    GST_DEBUG_OBJECT (context, "Unreffing other_context %" GST_PTR_FORMAT,
        other_context);
    gst_object_unref (other_context);
  }

  /* unlocking of the render_lock happens when the
   * context's loop is running from inside that loop */
  gst_gl_window_send_message_async (context->window,
      (GstGLWindowCB) _unlock_create_thread, context, NULL);

  gst_gl_window_run (context->window);

  GST_INFO_OBJECT (context, "loop exited");

  g_mutex_lock (&context->priv->render_lock);
  context->priv->alive = FALSE;

  gst_gl_context_activate (context, FALSE);

  context_class->destroy_context (context);

  /* User supplied callback */
  if (context->window->close)
    context->window->close (context->window->close_data);

  /* window specific shutdown */
  if (window_class->close) {
    window_class->close (context->window);
  }

  context->priv->created = FALSE;
  g_cond_signal (&context->priv->destroy_cond);
  g_mutex_unlock (&context->priv->render_lock);

  return NULL;

failure:
  {
    if (other_context)
      gst_object_unref (other_context);

    /* A context that fails to be created is considered created but not alive
     * and will never be able to be alive as creation can't happen */
    context->priv->created = TRUE;
    g_cond_signal (&context->priv->create_cond);
    g_mutex_unlock (&context->priv->render_lock);
    return NULL;
  }
}

/**
 * gst_gl_context_destroy:
 * @context: a #GstGLContext:
 *
 * Destroys an OpenGL context.
 *
 * Should only be called after gst_gl_context_create() has been successfully
 * called for this context.
 *
 * Since: 1.6
 */
void
gst_gl_context_destroy (GstGLContext * context)
{
  GstGLContextClass *context_class;

  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_if_fail (context_class->destroy_context != NULL);

  context_class->destroy_context (context);
}

/**
 * gst_gl_context_fill_info:
 * @context: a #GstGLContext:
 * @error: (allow-none): a #GError to fill on failure
 *
 * Fills @context's info (version, extensions, vtable, etc) from the GL
 * context in the current thread.  Typically used with wrapped contexts to
 * allow wrapped contexts to be used as regular #GstGLContext's.
 *
 * Since: 1.6
 */
gboolean
gst_gl_context_fill_info (GstGLContext * context, GError ** error)
{
  GstGLFuncs *gl;
  GString *ext_g_str = NULL;
  const gchar *ext_const_c_str = NULL;
  GstGLAPI gl_api;
  gboolean ret;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
  g_return_val_if_fail (context->priv->active_thread == g_thread_self (),
      FALSE);

  gl = context->gl_vtable;
  gl_api = gst_gl_context_get_gl_api (context);

  gl->GetError = gst_gl_context_get_proc_address (context, "glGetError");
  gl->GetString = gst_gl_context_get_proc_address (context, "glGetString");
  gl->GetStringi = gst_gl_context_get_proc_address (context, "glGetStringi");
  gl->GetIntegerv = gst_gl_context_get_proc_address (context, "glGetIntegerv");

  if (!gl->GetError || !gl->GetString) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "could not GetProcAddress core opengl functions");
    goto failure;
  }

  /* gl api specific code */
  ret = _create_context_info (context, gl_api, &context->priv->gl_major,
      &context->priv->gl_minor, error);

  if (!ret) {
    g_assert (error == NULL || *error != NULL);
    goto failure;
  }

  /* GL core contexts and GLES3 */
  if (gl->GetIntegerv && gl->GetStringi && context->priv->gl_major >= 3)
    ext_g_str = _build_extension_string (context);

  if (ext_g_str && ext_g_str->len) {
    GST_DEBUG_OBJECT (context, "GL_EXTENSIONS: %s", ext_g_str->str);
    _gst_gl_feature_check_ext_functions (context, context->priv->gl_major,
        context->priv->gl_minor, ext_g_str->str);

    context->priv->gl_exts = g_string_free (ext_g_str, FALSE);
  } else {
    ext_const_c_str = (const gchar *) gl->GetString (GL_EXTENSIONS);
    if (!ext_const_c_str)
      ext_const_c_str = "";

    GST_DEBUG_OBJECT (context, "GL_EXTENSIONS: %s", ext_const_c_str);
    _gst_gl_feature_check_ext_functions (context, context->priv->gl_major,
        context->priv->gl_minor, ext_const_c_str);

    context->priv->gl_exts = g_strdup (ext_const_c_str);
  }

  if (gl_api & GST_GL_API_OPENGL3
      && !gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 4, 1)
      && !gst_gl_check_extension ("GL_ARB_ES2_compatibility",
          context->priv->gl_exts)) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "An opengl3 context created but the required ES2 compatibility was not found");
    goto failure;
  }

  /* Does not implement OES_vertex_array_object properly, see
   * https://bugzilla.gnome.org/show_bug.cgi?id=750185 */
  if (g_strcmp0 ((const gchar *) gl->GetString (GL_VENDOR),
          "Imagination Technologies") == 0
      && g_strcmp0 ((const gchar *) gl->GetString (GL_RENDERER),
          "PowerVR SGX 544MP") == 0) {
    gl->GenVertexArrays = NULL;
    gl->DeleteVertexArrays = NULL;
    gl->BindVertexArray = NULL;
    gl->IsVertexArray = NULL;
  }

  return TRUE;

failure:
  return FALSE;
}

/**
 * gst_gl_context_get_gl_context:
 * @context: a #GstGLContext:
 *
 * Gets the backing OpenGL context used by @context.
 *
 * Returns: The platform specific backing OpenGL context
 *
 * Since: 1.4
 */
guintptr
gst_gl_context_get_gl_context (GstGLContext * context)
{
  GstGLContextClass *context_class;
  guintptr result;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), 0);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_val_if_fail (context_class->get_gl_context != NULL, 0);

  result = context_class->get_gl_context (context);

  return result;
}

/**
 * gst_gl_context_get_gl_platform:
 * @context: a #GstGLContext:
 *
 * Gets the OpenGL platform that used by @context.
 *
 * Returns: The platform specific backing OpenGL context
 *
 * Since: 1.4
 */
GstGLPlatform
gst_gl_context_get_gl_platform (GstGLContext * context)
{
  GstGLContextClass *context_class;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), 0);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_val_if_fail (context_class->get_gl_platform != NULL, 0);

  return context_class->get_gl_platform (context);
}

/**
 * gst_gl_context_get_display:
 * @context: a #GstGLContext:
 *
 * Returns: (transfer full): the #GstGLDisplay associated with this @context
 *
 * Since: 1.4
 */
GstGLDisplay *
gst_gl_context_get_display (GstGLContext * context)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);

  return gst_object_ref (context->display);
}

typedef struct
{
  GstGLContext *context;
  GstGLContextThreadFunc func;
  gpointer data;
} RunGenericData;

static void
_gst_gl_context_thread_run_generic (RunGenericData * data)
{
  GST_TRACE_OBJECT (data->context, "running function:%p data:%p", data->func,
      data->data);

  data->func (data->context, data->data);
}

/**
 * gst_gl_context_thread_add:
 * @context: a #GstGLContext
 * @func: (scope call): a #GstGLContextThreadFunc
 * @data: (closure): user data to call @func with
 *
 * Execute @func in the OpenGL thread of @context with @data
 *
 * MT-safe
 *
 * Since: 1.4
 */
void
gst_gl_context_thread_add (GstGLContext * context,
    GstGLContextThreadFunc func, gpointer data)
{
  GstGLWindow *window;
  RunGenericData rdata;

  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  g_return_if_fail (func != NULL);

  if (GST_IS_GL_WRAPPED_CONTEXT (context))
    g_return_if_fail (context->priv->active_thread == g_thread_self ());

  if (context->priv->active_thread == g_thread_self ()) {
    func (context, data);
    return;
  }

  rdata.context = context;
  rdata.data = data;
  rdata.func = func;

  window = gst_gl_context_get_window (context);

  gst_gl_window_send_message (window,
      GST_GL_WINDOW_CB (_gst_gl_context_thread_run_generic), &rdata);

  gst_object_unref (window);
}

/**
 * gst_gl_context_get_gl_version:
 * @context: a #GstGLContext
 * @maj: (out): resulting major version
 * @min: (out): resulting minor version
 *
 * Returns the OpenGL version implemented by @context.  See
 * gst_gl_context_get_gl_api() for retreiving the OpenGL api implemented by
 * @context.
 *
 * Since: 1.4
 */
void
gst_gl_context_get_gl_version (GstGLContext * context, gint * maj, gint * min)
{
  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  g_return_if_fail (!(maj == NULL && min == NULL));

  if (maj)
    *maj = context->priv->gl_major;

  if (min)
    *min = context->priv->gl_minor;
}

/**
 * gst_gl_context_check_gl_version:
 * @context: a #GstGLContext
 * @api: api type required
 * @maj: major version required
 * @min: minor version required
 *
 * Returns: whether OpenGL context implements the required api and specified
 * version.
 *
 * Since: 1.4
 */
gboolean
gst_gl_context_check_gl_version (GstGLContext * context, GstGLAPI api,
    gint maj, gint min)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  if (maj > context->priv->gl_major)
    return FALSE;

  if ((gst_gl_context_get_gl_api (context) & api) == GST_GL_API_NONE)
    return FALSE;

  if (maj < context->priv->gl_major)
    return TRUE;

  if (min > context->priv->gl_minor)
    return FALSE;

  return TRUE;
}

/**
 * gst_gl_context_check_feature:
 * @context: a #GstGLContext
 * @feature: a platform specific feature
 *
 * Check for an OpenGL @feature being supported.
 *
 * Note: Most features require that the context be created before it is
 * possible to determine their existence and so will fail if that is not the
 * case.
 *
 * Returns: Whether @feature is supported by @context
 *
 * Since: 1.4
 */
gboolean
gst_gl_context_check_feature (GstGLContext * context, const gchar * feature)
{
  GstGLContextClass *context_class;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
  g_return_val_if_fail (feature != NULL, FALSE);

  context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (g_strstr_len (feature, 3, "GL_"))
    return gst_gl_check_extension (feature, context->priv->gl_exts);

  if (!context_class->check_feature)
    return FALSE;

  return context_class->check_feature (context, feature);
}

/**
 * gst_gl_context_get_current:
 *
 * See also gst_gl_context_activate().
 *
 * Returns: (transfer none): the #GstGLContext active in the current thread or %NULL
 *
 * Since: 1.6
 */
GstGLContext *
gst_gl_context_get_current (void)
{
  return g_private_get (&current_context_key);
}

/**
 * gst_gl_context_is_shared:
 * @context: a #GstGLContext
 *
 * Returns: Whether the #GstGLContext has been shared with another #GstGLContext
 *
 * Since: 1.8
 */
gboolean
gst_gl_context_is_shared (GstGLContext * context)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  if (!context->priv->sharegroup)
    return FALSE;

  if (GST_IS_GL_WRAPPED_CONTEXT (context))
    g_return_val_if_fail (context->priv->active_thread, FALSE);
  else
    g_return_val_if_fail (context->priv->alive, FALSE);

  return _context_share_group_is_shared (context->priv->sharegroup);
}

/**
 * gst_gl_context_set_shared_with:
 * @context: a wrapped #GstGLContext
 * @share: another #GstGLContext
 *
 * Will internally set @context as shared with @share
 *
 * Since: 1.8
 */
void
gst_gl_context_set_shared_with (GstGLContext * context, GstGLContext * share)
{
  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  g_return_if_fail (GST_IS_GL_CONTEXT (share));
  g_return_if_fail (!gst_gl_context_is_shared (context));
  /* XXX: may be a little too strict */
  g_return_if_fail (GST_IS_GL_WRAPPED_CONTEXT (context));

  if (context->priv->sharegroup)
    _context_share_group_unref (context->priv->sharegroup);
  context->priv->sharegroup =
      _context_share_group_ref (share->priv->sharegroup);
}

static void
gst_gl_context_default_get_gl_platform_version (GstGLContext * context,
    gint * major, gint * minor)
{
  if (major)
    *major = 0;
  if (minor)
    *minor = 0;
}

/**
 * gst_gl_context_get_gl_platform_version:
 * @context: a #GstGLContext
 * @major: (out): return for the major version
 * @minor: (out): return for the minor version
 *
 * Get the version of the OpenGL platform (GLX, EGL, etc) used.  Only valid
 * after a call to gst_gl_context_create_context().
 */
void
gst_gl_context_get_gl_platform_version (GstGLContext * context, gint * major,
    gint * minor)
{
  GstGLContextClass *context_class;

  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  g_return_if_fail (major != NULL);
  g_return_if_fail (minor != NULL);
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_if_fail (context_class->get_gl_platform_version != NULL);

  context_class->get_gl_platform_version (context, major, minor);
}

/**
 * gst_gl_context_swap_buffers:
 * @context: a #GstGLContext
 *
 * Swap the front and back buffers on the window attached to @context.
 * This will display the frame on the next refresh cycle.
 */
void
gst_gl_context_swap_buffers (GstGLContext * context)
{
  GstGLContextClass *context_class;

  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  context_class = GST_GL_CONTEXT_GET_CLASS (context);
  g_return_if_fail (context_class->swap_buffers != NULL);

  context_class->swap_buffers (context);
}

static GstGLAPI
gst_gl_wrapped_context_get_gl_api (GstGLContext * context)
{
  GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);

  return context_wrap->available_apis;
}

static guintptr
gst_gl_wrapped_context_get_gl_context (GstGLContext * context)
{
  GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);

  return context_wrap->handle;
}

static GstGLPlatform
gst_gl_wrapped_context_get_gl_platform (GstGLContext * context)
{
  GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);

  return context_wrap->platform;
}

static gboolean
gst_gl_wrapped_context_activate (GstGLContext * context, gboolean activate)
{
  if (activate) {
    GThread *old_thread = context->priv->gl_thread;
    context->priv->gl_thread = g_thread_ref (g_thread_self ());
    if (old_thread) {
      g_thread_unref (old_thread);
    }
  } else {
    if (context->priv->gl_thread) {
      g_thread_unref (context->priv->gl_thread);
      context->priv->gl_thread = NULL;
    }
  }

  return TRUE;
}

static void
gst_gl_wrapped_context_class_init (GstGLWrappedContextClass * klass)
{
  GstGLContextClass *context_class = (GstGLContextClass *) klass;

  context_class->get_gl_context =
      GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_context);
  context_class->get_gl_api =
      GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_api);
  context_class->get_gl_platform =
      GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_platform);
  context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_activate);
}

static void
gst_gl_wrapped_context_init (GstGLWrappedContext * context)
{
}
