static gboolean reset_context (GstVaapiDisplayEGL * display, EGLContext gl_context) { EglConfig *config; EglContext *ctx; egl_object_replace (&display->egl_context, NULL); if (gl_context != EGL_NO_CONTEXT) ctx = egl_context_new_wrapped (display->egl_display, gl_context); else { config = egl_config_new (display->egl_display, display->gles_version, GST_VIDEO_FORMAT_RGB); if (!config) return FALSE; ctx = egl_context_new (display->egl_display, config, NULL); egl_object_unref (config); } if (!ctx) return FALSE; egl_object_replace (&display->egl_context, ctx); egl_object_unref (ctx); return TRUE; }
static gboolean egl_display_run (EglDisplay * display, EglContextRunFunc func, gpointer args) { EglMessage *msg; if (display->gl_thread == g_thread_self ()) { func (args); return TRUE; } msg = egl_object_new0 (egl_message_class ()); if (!msg) return FALSE; msg->base.is_valid = TRUE; msg->func = func; msg->args = args; g_async_queue_push (display->gl_queue, egl_object_ref (msg)); g_mutex_lock (&display->mutex); while (msg->base.is_valid) g_cond_wait (&display->gl_thread_ready, &display->mutex); g_mutex_unlock (&display->mutex); egl_object_unref (msg); return TRUE; }
static gboolean gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, gpointer native_params) { GstVaapiDisplay *native_display = NULL; GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display); EglDisplay *egl_display; const InitParams *params = (InitParams *) native_params; if (params->display) { native_display = params->display; } else { #if USE_X11 native_display = gst_vaapi_display_x11_new (NULL); #endif #if USE_WAYLAND if (!native_display) native_display = gst_vaapi_display_wayland_new (NULL); #endif } if (!native_display) return FALSE; gst_vaapi_display_replace (&display->display, native_display); egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display)); if (!egl_display) return FALSE; egl_object_replace (&display->egl_display, egl_display); egl_object_unref (egl_display); display->gles_version = params->gles_version; return TRUE; }
gboolean gst_vaapi_display_egl_set_current_display (GstVaapiDisplayEGL * display) { EglDisplay *egl_display; g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), FALSE); if (G_UNLIKELY (eglGetCurrentDisplay () == EGL_NO_DISPLAY)) return TRUE; if (G_LIKELY (display->egl_display->base.handle.p == eglGetCurrentDisplay ())) return TRUE; egl_display = egl_display_new_wrapped (eglGetCurrentDisplay ()); if (!egl_display) return FALSE; egl_object_replace (&display->egl_display, egl_display); egl_object_unref (egl_display); if (!gst_vaapi_display_egl_set_gl_context (display, eglGetCurrentContext ())) return FALSE; return TRUE; }
static EglDisplay * egl_display_new_full (gpointer handle, gboolean is_wrapped) { EglDisplay *display; display = egl_object_new0 (egl_display_class ()); if (!display) return NULL; display->base.handle.p = handle; display->base.is_wrapped = is_wrapped; if (!egl_display_init (display)) goto error; return display; /* ERRORS */ error: { egl_object_unref (display); return NULL; } }
EglContext * egl_context_new_wrapped (EglDisplay * display, EGLContext gl_context) { CreateContextArgs args; EglConfig *config; gboolean success; g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (gl_context != EGL_NO_CONTEXT, NULL); config = egl_config_new_from_gl_context (display, gl_context); if (!config) return NULL; args.display = display; args.config = config; args.gl_parent_context = gl_context; success = egl_display_run (display, (EglContextRunFunc) do_egl_context_new, &args); egl_object_unref (config); if (!success) return NULL; return args.context; }
static gboolean gst_vaapi_display_egl_bind_display (GstVaapiDisplay * base_display, gpointer native_params) { GstVaapiDisplay *native_vaapi_display; GstVaapiDisplayEGL *display = GST_VAAPI_DISPLAY_EGL (base_display); EglDisplay *egl_display; EGLDisplay *native_egl_display; guint gl_platform = EGL_PLATFORM_UNKNOWN; const InitParams *params = (InitParams *) native_params; GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display); native_vaapi_display = params->display; native_egl_display = params->gl_display; if (!native_vaapi_display) { #if USE_X11 if (params->display_type == GST_VAAPI_DISPLAY_TYPE_ANY || params->display_type == GST_VAAPI_DISPLAY_TYPE_X11 || params->display_type == GST_VAAPI_DISPLAY_TYPE_EGL) native_vaapi_display = gst_vaapi_display_x11_new (NULL); #endif #if USE_WAYLAND if (!native_vaapi_display) native_vaapi_display = gst_vaapi_display_wayland_new (NULL); #endif } else { /* thus it could be assigned to parent */ gst_object_ref (native_vaapi_display); } if (!native_vaapi_display) return FALSE; gst_vaapi_display_replace (&display->display, native_vaapi_display); priv->parent = native_vaapi_display; switch (GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display->display)) { case GST_VAAPI_DISPLAY_TYPE_X11: gl_platform = EGL_PLATFORM_X11; break; case GST_VAAPI_DISPLAY_TYPE_WAYLAND: gl_platform = EGL_PLATFORM_WAYLAND; break; default: break; } if (native_egl_display) { egl_display = egl_display_new_wrapped (native_egl_display); } else { egl_display = egl_display_new (GST_VAAPI_DISPLAY_NATIVE (display->display), gl_platform); } if (!egl_display) return FALSE; egl_object_replace (&display->egl_display, egl_display); egl_object_unref (egl_display); display->gles_version = params->gles_version; return TRUE; }
static gpointer egl_display_thread (gpointer data) { EglDisplay *const display = data; EGLDisplay gl_display = display->base.handle.p; EGLint major_version, minor_version; gchar **gl_apis, **gl_api; if (!display->base.is_wrapped) { gl_display = display->base.handle.p = eglGetDisplay (gl_display); if (!gl_display) goto error; if (!eglInitialize (gl_display, &major_version, &minor_version)) goto error; } display->gl_vendor_string = g_strdup (eglQueryString (gl_display, EGL_VENDOR)); display->gl_version_string = g_strdup (eglQueryString (gl_display, EGL_VERSION)); display->gl_apis_string = g_strdup (eglQueryString (gl_display, EGL_CLIENT_APIS)); GST_INFO ("EGL vendor: %s", display->gl_vendor_string); GST_INFO ("EGL version: %s", display->gl_version_string); GST_INFO ("EGL client APIs: %s", display->gl_apis_string); gl_apis = g_strsplit (display->gl_apis_string, " ", 0); if (!gl_apis) goto error; for (gl_api = gl_apis; *gl_api != NULL; gl_api++) { const GlVersionInfo *const vinfo = gl_version_info_lookup_by_api_name (*gl_api); if (vinfo) display->gl_apis |= vinfo->gl_api_bit; } g_strfreev (gl_apis); if (!display->gl_apis) goto error; display->base.is_valid = TRUE; g_cond_broadcast (&display->gl_thread_ready); while (!display->gl_thread_cancel) { EglMessage *const msg = g_async_queue_timeout_pop (display->gl_queue, 100000); if (msg) { if (msg->base.is_valid) { msg->func (msg->args); msg->base.is_valid = FALSE; g_cond_broadcast (&display->gl_thread_ready); } egl_object_unref (msg); } } done: if (gl_display != EGL_NO_DISPLAY && !display->base.is_wrapped) eglTerminate (gl_display); display->base.handle.p = NULL; g_cond_broadcast (&display->gl_thread_ready); return NULL; /* ERRORS */ error: { display->base.is_valid = FALSE; goto done; } }