GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display) { g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE); return display->priv->gl_api; }
/** * gst_gl_display_get_handle_type: * @display: a #GstGLDisplay * * Returns: the #GstGLDisplayType of @display * * Since: 1.4 */ GstGLDisplayType gst_gl_display_get_handle_type (GstGLDisplay * display) { g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_DISPLAY_TYPE_NONE); return display->type; }
guintptr gst_gl_display_get_handle (GstGLDisplay * display) { GstGLDisplayClass *klass; g_return_val_if_fail (GST_IS_GL_DISPLAY (display), 0); klass = GST_GL_DISPLAY_GET_CLASS (display); g_return_val_if_fail (klass->get_handle != NULL, 0); return klass->get_handle (display); }
/** * gst_gl_display_get_gl_api: * @display: a #GstGLDisplay * * see gst_gl_display_filter_gl_api() for what the returned value represents * * Returns: the #GstGLAPI configured for @display */ GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display) { GstGLAPI ret; g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE); GST_OBJECT_LOCK (display); ret = display->priv->gl_api; GST_OBJECT_UNLOCK (display); return ret; }
/** * gst_gl_display_get_gl_context_for_thread: * @display: a #GstGLDisplay * @thread: a #GThread * * Returns: (transfer full): the #GstGLContext current on @thread or %NULL * * Must be called with the object lock held. * * Since: 1.6 */ GstGLContext * gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display, GThread * thread) { GstGLContext *context; g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL); context = _get_gl_context_for_thread_unlocked (display, thread); GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread " "%p", context, thread); return context; }
/** * gst_gl_display_egl_from_gl_display: * @display: an existing #GstGLDisplay * * Creates a EGL display connection from a native Display. * * This function will return the same value for multiple calls with the same * @display. * * Returns: (transfer full): a new #GstGLDisplayEGL * * Since: 1.12 */ GstGLDisplayEGL * gst_gl_display_egl_from_gl_display (GstGLDisplay * display) { GstGLDisplayEGL *ret; GstGLDisplayType display_type; guintptr native_display; g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL); GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay"); if (GST_IS_GL_DISPLAY_EGL (display)) { GST_LOG_OBJECT (display, "display %" GST_PTR_FORMAT "is already a " "GstGLDisplayEGL", display); return gst_object_ref (display); } /* try to get a previously set GstGLDisplayEGL */ ret = g_object_dup_data (G_OBJECT (display), GST_GL_DISPLAY_EGL_NAME, (GDuplicateFunc) _ref_if_set, NULL); if (ret && GST_IS_GL_DISPLAY_EGL (ret)) { GST_LOG_OBJECT (display, "display %" GST_PTR_FORMAT "already has a " "GstGLDisplayEGL %" GST_PTR_FORMAT, display, ret); return ret; } if (ret) gst_object_unref (ret); display_type = gst_gl_display_get_handle_type (display); native_display = gst_gl_display_get_handle (display); g_return_val_if_fail (native_display != 0, NULL); g_return_val_if_fail (display_type != GST_GL_DISPLAY_TYPE_NONE, NULL); ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL, NULL); ret->display = gst_gl_display_egl_get_from_native (display_type, native_display); if (!ret->display) { GST_WARNING_OBJECT (ret, "failed to get EGLDisplay from native display"); gst_object_unref (ret); return NULL; } g_object_set_data_full (G_OBJECT (display), GST_GL_DISPLAY_EGL_NAME, gst_object_ref (ret), (GDestroyNotify) gst_object_unref); return ret; }
/** * gst_gl_display_filter_gl_api: * @display: a #GstGLDisplay * @gl_api: a #GstGLAPI to filter with * * limit the use of OpenGL to the requested @gl_api. This is intended to allow * application and elements to request a specific set of OpenGL API's based on * what they support. See gst_gl_context_get_gl_api() for the retreiving the * API supported by a #GstGLContext. */ void gst_gl_display_filter_gl_api (GstGLDisplay * display, GstGLAPI gl_api) { gchar *gl_api_s; g_return_if_fail (GST_IS_GL_DISPLAY (display)); gl_api_s = gst_gl_api_to_string (gl_api); GST_TRACE_OBJECT (display, "filtering with api %s", gl_api_s); g_free (gl_api_s); GST_OBJECT_LOCK (display); display->priv->gl_api &= gl_api; GST_OBJECT_UNLOCK (display); }
/** * 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; }
/** * gst_gl_handle_context_query: * @element: a #GstElement * @query: a #GstQuery of type %GST_QUERY_CONTEXT * @display: (transfer none) (nullable): a #GstGLDisplay * @context: (transfer none) (nullable): a #GstGLContext * @other_context: (transfer none) (nullable): application provided #GstGLContext * * Returns: Whether the @query was successfully responded to from the passed * @display, @context, and @other_context. */ gboolean gst_gl_handle_context_query (GstElement * element, GstQuery * query, GstGLDisplay * display, GstGLContext * gl_context, GstGLContext * other_context) { const gchar *context_type; GstContext *context, *old_context; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); g_return_val_if_fail (GST_IS_QUERY (query), FALSE); g_return_val_if_fail (display == NULL || GST_IS_GL_DISPLAY (display), FALSE); g_return_val_if_fail (gl_context == NULL || GST_IS_GL_CONTEXT (gl_context), FALSE); g_return_val_if_fail (other_context == NULL || GST_IS_GL_CONTEXT (other_context), FALSE); GST_LOG_OBJECT (element, "handle context query %" GST_PTR_FORMAT, query); gst_query_parse_context_type (query, &context_type); if (display && g_strcmp0 (context_type, GST_GL_DISPLAY_CONTEXT_TYPE) == 0) { gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new (GST_GL_DISPLAY_CONTEXT_TYPE, TRUE); gst_context_set_gl_display (context, display); gst_query_set_context (query, context); gst_context_unref (context); GST_DEBUG_OBJECT (element, "successfully set %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, display, query); return TRUE; } #if GST_GL_HAVE_WINDOW_X11 else if (display && g_strcmp0 (context_type, "gst.x11.display.handle") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("gst.x11.display.handle", TRUE); if (gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_X11) { Display *x11_display = (Display *) gst_gl_display_get_handle (display); if (x11_display) { s = gst_context_writable_structure (context); gst_structure_set (s, "display", G_TYPE_POINTER, x11_display, NULL); gst_query_set_context (query, context); gst_context_unref (context); GST_DEBUG_OBJECT (element, "successfully set x11 display %p (from %" GST_PTR_FORMAT ") on %" GST_PTR_FORMAT, x11_display, display, query); return TRUE; } } } #endif #if GST_GL_HAVE_WINDOW_WAYLAND else if (display && g_strcmp0 (context_type, "GstWaylandDisplayHandleContextType") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("GstWaylandDisplayHandleContextType", TRUE); if (gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_WAYLAND) { struct wl_display *wayland_display = (struct wl_display *) gst_gl_display_get_handle (display); if (wayland_display) { s = gst_context_writable_structure (context); gst_structure_set (s, "display", G_TYPE_POINTER, wayland_display, NULL); gst_query_set_context (query, context); gst_context_unref (context); GST_DEBUG_OBJECT (element, "successfully set wayland display %p (from %" GST_PTR_FORMAT ") on %" GST_PTR_FORMAT, wayland_display, display, query); return TRUE; } } } #endif else if (other_context && g_strcmp0 (context_type, "gst.gl.app_context") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("gst.gl.app_context", TRUE); s = gst_context_writable_structure (context); gst_structure_set (s, "context", GST_TYPE_GL_CONTEXT, other_context, NULL); gst_query_set_context (query, context); gst_context_unref (context); GST_DEBUG_OBJECT (element, "successfully set application GL context %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, other_context, query); return TRUE; } else if (gl_context && g_strcmp0 (context_type, "gst.gl.local_context") == 0) { GstStructure *s; gst_query_parse_context (query, &old_context); if (old_context) context = gst_context_copy (old_context); else context = gst_context_new ("gst.gl.local_context", TRUE); s = gst_context_writable_structure (context); gst_structure_set (s, "context", GST_TYPE_GL_CONTEXT, gl_context, NULL); gst_query_set_context (query, context); gst_context_unref (context); GST_DEBUG_OBJECT (element, "successfully set GL context %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, gl_context, query); return TRUE; } return FALSE; }