GstGLAPI
gst_gl_context_wgl_get_gl_api (GstGLContext * context)
{
  GstGLContextWGL *context_wgl = GST_GL_CONTEXT_WGL (context);

  return context_wgl->priv->context_api;
}
static gboolean
gst_gl_context_wgl_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
{
  GstGLWindow *window;
  GstGLContextWGL *context_wgl;
  GstGLContextWGL *other_wgl = NULL;
  HDC device;

  context_wgl = GST_GL_CONTEXT_WGL (context);
  window = gst_gl_context_get_window (context);
  device = (HDC) gst_gl_window_get_display (window);

  if (other_context) {
    if (!GST_GL_IS_CONTEXT_WGL (other_context)) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
          "Cannot share context with a non-WGL context");
      goto failure;
    }
    other_wgl = (GstGLContextWGL *) other_context;
  }

  context_wgl->wgl_context = wglCreateContext (device);
  if (context_wgl->wgl_context)
    GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
        (guintptr) context_wgl->wgl_context);
  else {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to create glcontext:0x%x",
        (unsigned int) GetLastError ());
    goto failure;
  }
  g_assert (context_wgl->wgl_context);

  GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
      (guintptr) context_wgl->wgl_context);

  if (other_wgl) {
    if (!wglShareLists (other_wgl->wgl_context, context_wgl->wgl_context)) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to share contexts 0x%x",
          (unsigned int) GetLastError ());
      goto failure;
    }
  }

  gst_object_unref (window);

  return TRUE;

failure:
  gst_object_unref (window);

  return FALSE;
}
static void
gst_gl_context_wgl_destroy_context (GstGLContext * context)
{
  GstGLContextWGL *context_wgl;

  context_wgl = GST_GL_CONTEXT_WGL (context);

  if (context_wgl->wgl_context)
    wglDeleteContext (context_wgl->wgl_context);
  context_wgl->wgl_context = NULL;
}
static gboolean
gst_gl_context_wgl_activate (GstGLContext * context, gboolean activate)
{
  GstGLWindow *window;
  GstGLContextWGL *context_wgl;
  HDC device;
  gboolean result;

  window = gst_gl_context_get_window (context);
  context_wgl = GST_GL_CONTEXT_WGL (context);
  device = (HDC) gst_gl_window_get_display (window);

  if (activate) {
    result = wglMakeCurrent (device, context_wgl->wgl_context);
  } else {
    result = wglMakeCurrent (NULL, NULL);
  }

  gst_object_unref (window);

  return result;
}
static guintptr
gst_gl_context_wgl_get_gl_context (GstGLContext * context)
{
  return (guintptr) GST_GL_CONTEXT_WGL (context)->wgl_context;
}
static gboolean
gst_gl_context_wgl_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
{
  GstGLWindow *window;
  GstGLContextWGL *context_wgl;
  HGLRC external_gl_context = NULL;
  HGLRC trampoline;
  HDC device;

  context_wgl = GST_GL_CONTEXT_WGL (context);
  window = gst_gl_context_get_window (context);
  device = (HDC) gst_gl_window_get_display (window);

  if (other_context) {
    if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_WGL) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
          "Cannot share context with a non-WGL context");
      goto failure;
    }
    external_gl_context = (HGLRC) gst_gl_context_get_gl_context (other_context);
  }

  trampoline = wglCreateContext (device);
  if (trampoline)
    GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
        (guintptr) trampoline);
  else {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to create glcontext:0x%x",
        (unsigned int) GetLastError ());
    goto failure;
  }
  g_assert (trampoline);

  /* get extension functions */
  wglMakeCurrent (device, trampoline);

  context_wgl->priv->wglCreateContextAttribsARB =
      (PFNWGLCREATECONTEXTATTRIBSARBPROC)
      wglGetProcAddress ("wglCreateContextAttribsARB");

  wglMakeCurrent (device, 0);
  wglDeleteContext (trampoline);
  trampoline = NULL;

  if (context_wgl->priv->wglCreateContextAttribsARB != NULL
      && gl_api & GST_GL_API_OPENGL3) {
    gint i;

    for (i = 0; i < G_N_ELEMENTS (opengl_versions); i++) {
      gint profileMask = 0;
      gint contextFlags = 0;

      if ((opengl_versions[i].major > 3
              || (opengl_versions[i].major == 3
                  && opengl_versions[i].minor >= 2))) {
        profileMask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
        contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB;
      } else {
        break;
      }

      GST_DEBUG_OBJECT (context, "trying to create a GL %d.%d context",
          opengl_versions[i].major, opengl_versions[i].minor);

      context_wgl->wgl_context = _create_context_with_flags (context_wgl,
          device, external_gl_context, opengl_versions[i].major,
          opengl_versions[i].minor, contextFlags, profileMask);

      if (context_wgl->wgl_context) {
        context_wgl->priv->context_api = GST_GL_API_OPENGL3;
        break;
      }
    }
  }

  if (!context_wgl->wgl_context) {

    if (context_wgl->priv->wglCreateContextAttribsARB && external_gl_context) {
      context_wgl->wgl_context =
          context_wgl->priv->wglCreateContextAttribsARB (device,
          external_gl_context, 0);
    }


    if (!context_wgl->wgl_context) {

      context_wgl->wgl_context = wglCreateContext (device);

      if (!context_wgl->wgl_context) {
        g_set_error (error, GST_GL_CONTEXT_ERROR,
            GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
            "Failed to create WGL context 0x%x",
            (unsigned int) GetLastError ());
        goto failure;
      }

      if (external_gl_context) {
        if (!wglShareLists (external_gl_context, context_wgl->wgl_context)) {
          g_set_error (error, GST_GL_CONTEXT_ERROR,
              GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
              "failed to share contexts through wglShareLists 0x%x",
              (unsigned int) GetLastError ());
          goto failure;
        }
      }
    }

    context_wgl->priv->context_api = GST_GL_API_OPENGL;
  }

  GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
      (guintptr) context_wgl->wgl_context);

  gst_object_unref (window);

  return TRUE;

failure:
  gst_object_unref (window);

  return FALSE;
}