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 void do_destroy_objects_unlocked (GstVaapiWindowEGL * window) { egl_object_replace (&window->render_program, NULL); egl_object_replace (&window->egl_vtable, NULL); egl_object_replace (&window->egl_window, NULL); }
static void egl_context_set_surface (EglContext * ctx, EglSurface * surface) { g_return_if_fail (ctx != NULL); g_return_if_fail (surface != NULL); egl_object_replace (&ctx->read_surface, surface); egl_object_replace (&ctx->draw_surface, surface); }
static void egl_window_finalize (EglWindow * window) { if (window->context && window->base.handle.p) eglDestroySurface (window->context->display->base.handle.p, window->base.handle.p); egl_object_replace (&window->surface, NULL); egl_object_replace (&window->context, NULL); }
static void egl_context_finalize (EglContext * ctx) { if (ctx->base.handle.p && !ctx->base.is_wrapped) eglDestroyContext (ctx->display->base.handle.p, ctx->base.handle.p); egl_object_replace (&ctx->read_surface, NULL); egl_object_replace (&ctx->draw_surface, NULL); egl_object_replace (&ctx->config, NULL); egl_object_replace (&ctx->display, NULL); egl_object_replace (&ctx->vtable, NULL); }
static gboolean egl_context_init (EglContext * ctx, EglDisplay * display, EglConfig * config, EGLContext gl_parent_context) { egl_object_replace (&ctx->display, display); egl_object_replace (&ctx->config, config); if (config) eglBindAPI (config->gl_api); if (!ensure_vtable (ctx)) return FALSE; if (!ensure_context (ctx, gl_parent_context)) return FALSE; return TRUE; }
static void egl_surface_finalize (EglSurface * surface) { if (surface->base.handle.p != EGL_NO_SURFACE && !surface->base.is_wrapped) eglDestroySurface (surface->display->base.handle.p, surface->base.handle.p); egl_object_replace (&surface->display, NULL); }
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; }
static void gst_vaapi_display_egl_finalize (GObject * object) { GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (object); if (dpy->texture_map) gst_object_unref (dpy->texture_map); /* HACK to avoid to call twice vaTerminate() since this and the * proxied display share the same vaDisplay */ GST_VAAPI_DISPLAY_VADISPLAY (object) = NULL; egl_object_replace (&dpy->egl_display, NULL); egl_object_replace (&dpy->egl_context, NULL); gst_vaapi_display_replace (&dpy->display, NULL); G_OBJECT_CLASS (gst_vaapi_display_egl_parent_class)->finalize (object); }
static void egl_program_finalize (EglProgram * program) { EglVTable *const vtable = program->vtable; if (program->base.handle.u) vtable->glDeleteProgram (program->base.handle.u); if (program->frag_shader) vtable->glDeleteShader (program->frag_shader); if (program->vert_shader) vtable->glDeleteShader (program->vert_shader); egl_object_replace (&program->vtable, NULL); }
static gboolean ensure_shaders (GstVaapiWindowEGL * window) { EglVTable *const vtable = window->egl_vtable; EglProgram *program; GLuint prog_id; g_return_val_if_fail (window->texture != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_TEXTURE_FORMAT (window->texture) == GL_RGBA, FALSE); if (window->render_program) return TRUE; program = egl_program_new (window->egl_window->context, frag_shader_text_rgba, vert_shader_text); if (!program) return FALSE; prog_id = program->base.handle.u; vtable->glUseProgram (prog_id); program->uniforms[RENDER_PROGRAM_VAR_PROJ] = vtable->glGetUniformLocation (prog_id, "proj"); program->uniforms[RENDER_PROGRAM_VAR_TEX0] = vtable->glGetUniformLocation (prog_id, "tex0"); program->uniforms[RENDER_PROGRAM_VAR_TEX1] = vtable->glGetUniformLocation (prog_id, "tex1"); program->uniforms[RENDER_PROGRAM_VAR_TEX2] = vtable->glGetUniformLocation (prog_id, "tex2"); vtable->glUseProgram (0); egl_matrix_set_identity (window->render_projection); egl_object_replace (&window->render_program, program); egl_object_replace (&program, NULL); return TRUE; }
static void do_egl_context_new (CreateContextArgs * args) { EglContext *ctx; ctx = egl_object_new0 (egl_context_class ()); if (!ctx || !egl_context_init (ctx, args->display, args->config, args->gl_parent_context)) goto error; args->context = ctx; return; /* ERRORS */ error: { egl_object_replace (&ctx, NULL); args->context = NULL; } }
EglConfig * egl_config_new_with_attribs (EglDisplay * display, const EGLint * attribs) { EglConfig *config; g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (attribs != NULL, NULL); config = egl_object_new0 (egl_config_class ()); if (!config || !egl_config_init (config, display, attribs)) goto error; return config; /* ERRORS */ error: { egl_object_replace (&config, NULL); return NULL; } }
static EglVTable * egl_vtable_new (EglDisplay * display, guint gles_version) { EglVTable *vtable; g_return_val_if_fail (display != NULL, NULL); vtable = egl_object_new0 (egl_vtable_class ()); if (!vtable || !egl_vtable_init (vtable, display->base.handle.p, gles_version)) goto error; return vtable; /* ERRORS */ error: { egl_object_replace (&vtable, NULL); return NULL; } }
EglWindow * egl_window_new (EglContext * ctx, gpointer native_window) { EglWindow *window; g_return_val_if_fail (ctx != NULL, NULL); g_return_val_if_fail (native_window != NULL, NULL); window = egl_object_new0 (egl_window_class ()); if (!window || !egl_window_init (window, ctx, native_window)) goto error; return window; /* ERRORS */ error: { egl_object_replace (&window, NULL); return NULL; } }
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; }
EglProgram * egl_program_new (EglContext * ctx, const gchar * frag_shader_text, const gchar * vert_shader_text) { EglProgram *program; g_return_val_if_fail (ctx != NULL, NULL); g_return_val_if_fail (frag_shader_text != NULL, NULL); g_return_val_if_fail (vert_shader_text != NULL, NULL); program = egl_object_new0 (egl_program_class ()); if (!program || !egl_program_init (program, ctx, frag_shader_text, vert_shader_text)) goto error; return program; /* ERRORS */ error: { egl_object_replace (&program, NULL); return NULL; } }
static gboolean egl_config_init (EglConfig * config, EglDisplay * display, const EGLint * attribs) { EGLDisplay const gl_display = display->base.handle.p; const GlVersionInfo *vinfo; EGLConfig gl_config; EGLint v, gl_apis, num_configs; egl_object_replace (&config->display, display); if (!eglChooseConfig (gl_display, attribs, &gl_config, 1, &num_configs)) return FALSE; if (num_configs != 1) return FALSE; config->base.handle.p = gl_config; if (!eglGetConfigAttrib (gl_display, gl_config, EGL_CONFIG_ID, &v)) return FALSE; config->config_id = v; if (!eglGetConfigAttrib (gl_display, gl_config, EGL_NATIVE_VISUAL_ID, &v)) return FALSE; config->visual_id = v; if (!eglGetConfigAttrib (gl_display, gl_config, EGL_RENDERABLE_TYPE, &v)) return FALSE; if (!egl_find_attrib_value (attribs, EGL_RENDERABLE_TYPE, &gl_apis)) return FALSE; vinfo = gl_version_info_lookup_by_api (v & gl_apis); if (!vinfo) return FALSE; config->gles_version = vinfo->gles_version; config->gl_api = vinfo->gles_version > 0 ? EGL_OPENGL_ES_API : EGL_OPENGL_API; return TRUE; }
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 void egl_config_finalize (EglConfig * config) { egl_object_replace (&config->display, NULL); }