示例#1
0
static gboolean
_check_collision (GstGLContext * context, GstGLContext * collision)
{
  GThread *thread, *collision_thread;
  gboolean ret = FALSE;

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

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

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

  if (collision == context) {
    ret = TRUE;
    goto out;
  }

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

  return ret;
}
示例#2
0
static void
_set_window_handle_cb (GstSetWindowHandleCb * data)
{
  GstGLContext *context = gst_gl_window_get_context (data->window);
  GstGLWindowClass *window_class = GST_GL_WINDOW_GET_CLASS (data->window);
  GThread *thread = NULL;

  /* deactivate if necessary */
  if (context) {
    thread = gst_gl_context_get_thread (context);
    if (thread) {
      /* This is only thread safe iff the context thread == g_thread_self() */
      g_assert (thread == g_thread_self ());
      gst_gl_context_activate (context, FALSE);
    }
  }

  window_class->set_window_handle (data->window, data->handle);

  /* reactivate */
  if (context && thread)
    gst_gl_context_activate (context, TRUE);

  if (context)
    gst_object_unref (context);
  if (thread)
    g_thread_unref (thread);
}
示例#3
0
static GstGLContext *
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
{
  GstGLContext *context = NULL;
  GList *prev = NULL, *l = display->priv->contexts;

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

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

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

    if (context_thread)
      g_thread_unref (context_thread);
    return context;
  }

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

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

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

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

    /* adding the same context is a no-op */
    if (context == collision) {
      ret = TRUE;
      goto out;
    }

    if (_check_collision (context, collision)) {
      ret = FALSE;
      goto out;
    }
  }

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

  display->priv->contexts = g_list_prepend (display->priv->contexts, ref);

out:
  if (collision)
    gst_object_unref (collision);

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

  return ret;
}