/*
 * 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.
 */

#if 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 <gmodule.h>
#include <string.h>
#include <stdio.h>

#include "gl.h"
#include "gstglcontext.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;
}

#if GST_GL_HAVE_GLES3
#error "Add module loading support for GLES3"
#endif

/* 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_GL_TYPE_CONTEXT, GstGLContextPrivate))

static void _init_debug (void);

static gpointer gst_gl_context_create_thread (GstGLContext * context);
static void gst_gl_context_finalize (GObject * object);

struct _GstGLContextPrivate
{
  GThread *gl_thread;
  GThread *active_thread;

  /* conditions */
  GMutex render_lock;
  GCond create_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_GL_TYPE_WRAPPED_CONTEXT (gst_gl_wrapped_context_get_type())
GType gst_gl_wrapped_context_get_type (void);
G_DEFINE_TYPE (GstGLWrappedContext, gst_gl_wrapped_context,
    GST_GL_TYPE_CONTEXT);

#define GST_GL_WRAPPED_CONTEXT(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WRAPPED_CONTEXT, GstGLWrappedContext))
#define GST_GL_WRAPPED_CONTEXT_CLASS(k)     (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT, GstGLContextClass))
#define GST_IS_GL_WRAPPED_CONTEXT(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WRAPPED_CONTEXT))
#define GST_IS_GL_WRAPPED_CONTEXT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WRAPPED_CONTEXT))
#define GST_GL_WRAPPED_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_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_window_new (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);
  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);

  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.  
 *
 * Returns: 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_GL_TYPE_WRAPPED_CONTEXT, NULL);

  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;
}

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 aren't 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 *(*GetString) (GLenum name);
#if GST_GL_HAVE_OPENGL
  void (*GetIntegerv) (GLenum name, GLuint * n);
#endif
  const gchar *version;
  gint maj, min, n;
  GstGLAPI ret = (1 << 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);

    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");
      g_thread_join (context->priv->gl_thread);
      GST_INFO_OBJECT (context, "gl thread joined");
      context->priv->gl_thread = NULL;
    }

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

  if (context->priv->sharegroup)
    _context_share_group_unref (context->priv->sharegroup);

  gst_object_unref (context->display);

  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_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) {
    context->priv->active_thread = g_thread_self ();
    g_private_set (&current_context_key, context);
  } else {
    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.
 *
 * 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;
}

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) {
    if (gst_gl_window_is_running (window))
      return FALSE;

    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: 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 in the current thread with the specified
 * @other_context as a context to share shareable OpenGL objects with.  See the
 * OpenGL specification for what is shared between 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_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:
 *
 * 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: 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: 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
 *
 * Some 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: 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 (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 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)
    context->priv->gl_thread = g_thread_self ();
  else
    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)
{
}
