From a8d5b210138bac59843a9e70c32a1326932f662b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 3 Jul 2013 09:12:39 +0200 Subject: [PATCH] [727/906] egl: Refactor EGL logic into a helper object --- gst-libs/gst/gl/Makefile.am | 18 ++ gst-libs/gst/gl/gstglegl.c | 279 ++++++++++++++++++++++ gst-libs/gst/gl/gstglegl.h | 55 +++++ gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c | 234 +++--------------- gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h | 8 +- gst-libs/gst/gl/x11/gstglwindow_x11_egl.c | 203 ++-------------- gst-libs/gst/gl/x11/gstglwindow_x11_egl.h | 8 +- 7 files changed, 403 insertions(+), 402 deletions(-) create mode 100644 gst-libs/gst/gl/gstglegl.c create mode 100644 gst-libs/gst/gl/gstglegl.h diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am index 1f8d211..a1feb3f 100644 --- a/gst-libs/gst/gl/Makefile.am +++ b/gst-libs/gst/gl/Makefile.am @@ -3,6 +3,8 @@ lib_LTLIBRARIES = libgstgl-@GST_API_VERSION@.la SUBDIRS = +noinst_HEADERS = + libgstgl_@GST_API_VERSION@_la_SOURCES = \ gstgldisplay.c \ gstglmemory.c \ @@ -46,6 +48,22 @@ SUBDIRS += wayland libgstgl_@GST_API_VERSION@_la_LIBADD += wayland/libgstgl-wayland.la endif +if USE_EGL + +if HAVE_WINDOW_WAYLAND +libgstgl_@GST_API_VERSION@_la_SOURCES += gstglegl.c +noinst_HEADERS += gstglegl.h +endif + +if !HAVE_WINDOW_WAYLAND +if HAVE_WINDOW_X11 +libgstgl_@GST_API_VERSION@_la_SOURCES += gstglegl.c +noinst_HEADERS += gstglegl.h +endif +endif + +endif + libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl libgstgl_@GST_API_VERSION@include_HEADERS = \ gstglwindow.h \ diff --git a/gst-libs/gst/gl/gstglegl.c b/gst-libs/gst/gl/gstglegl.c new file mode 100644 index 0000000..f41092c --- /dev/null +++ b/gst-libs/gst/gl/gstglegl.c @@ -0,0 +1,279 @@ +/* + * GStreamer + * Copyright (C) 2013 Sebastian Dröge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstglegl.h" + +static const gchar * +gst_gl_egl_get_error_string (void) +{ + EGLint nErr = eglGetError (); + + switch (nErr) { + case EGL_SUCCESS: + return "EGL_SUCCESS"; + case EGL_BAD_DISPLAY: + return "EGL_BAD_DISPLAY"; + case EGL_NOT_INITIALIZED: + return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: + return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: + return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: + return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONFIG: + return "EGL_BAD_CONFIG"; + case EGL_BAD_CONTEXT: + return "EGL_BAD_CONTEXT"; + case EGL_BAD_CURRENT_SURFACE: + return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_MATCH: + return "EGL_BAD_MATCH"; + case EGL_BAD_NATIVE_PIXMAP: + return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: + return "EGL_BAD_NATIVE_WINDOW"; + case EGL_BAD_PARAMETER: + return "EGL_BAD_PARAMETER"; + case EGL_BAD_SURFACE: + return "EGL_BAD_SURFACE"; + default: + return "unknown"; + } +} + +static gboolean +gst_gl_egl_choose_config (GstGLEGL * egl, GError ** error) +{ + EGLint numConfigs; + gint i = 0; + EGLint config_attrib[20]; + + config_attrib[i++] = EGL_SURFACE_TYPE; + config_attrib[i++] = EGL_WINDOW_BIT; + config_attrib[i++] = EGL_RENDERABLE_TYPE; + if (egl->gl_api & GST_GL_API_GLES2) + config_attrib[i++] = EGL_OPENGL_ES2_BIT; + else + config_attrib[i++] = EGL_OPENGL_BIT; + config_attrib[i++] = EGL_DEPTH_SIZE; + config_attrib[i++] = 16; + config_attrib[i++] = EGL_NONE; + + if (eglChooseConfig (egl->egl_display, config_attrib, + &egl->egl_config, 1, &numConfigs)) { + GST_INFO ("config set: %ld, %ld", (gulong) egl->egl_config, + (gulong) numConfigs); + } else { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG, + "Failed to set window configuration: %s", + gst_gl_egl_get_error_string ()); + goto failure; + } + + return TRUE; + +failure: + return FALSE; +} + +GstGLEGL * +gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window, + GstGLAPI gl_api, guintptr external_gl_context, GError ** error) +{ + GstGLEGL *egl; + gint i = 0; + EGLint context_attrib[3]; + EGLint majorVersion; + EGLint minorVersion; + + egl = g_slice_new0 (GstGLEGL); + + if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE && + (gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API, + "xEGL supports opengl or gles2"); + goto failure; + } + + egl->egl_display = display; + + if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) { + GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion); + } else { + g_set_error (error, GST_GL_WINDOW_ERROR, + GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, + "Failed to initialize egl: %s", gst_gl_egl_get_error_string ()); + goto failure; + } + + if (gl_api & GST_GL_API_OPENGL) { + /* egl + opengl only available with EGL 1.4+ */ + if (majorVersion == 1 && minorVersion <= 3) { + if ((gl_api & ~GST_GL_API_OPENGL) == GST_GL_API_NONE) { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS, + "EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", + majorVersion, minorVersion); + goto failure; + } else { + GST_WARNING + ("EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", + majorVersion, minorVersion); + if (gl_api & GST_GL_API_GLES2) { + goto try_gles2; + } else { + g_set_error (error, GST_GL_WINDOW_ERROR, + GST_GL_WINDOW_ERROR_WRONG_CONFIG, + "Failed to choose a suitable OpenGL API"); + goto failure; + } + } + } + + if (!eglBindAPI (EGL_OPENGL_API)) { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, + "Failed to bind OpenGL|ES API: %s", gst_gl_egl_get_error_string ()); + goto failure; + } + + egl->gl_api = GST_GL_API_OPENGL; + } else if (gl_api & GST_GL_API_GLES2) { + try_gles2: + if (!eglBindAPI (EGL_OPENGL_ES_API)) { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, + "Failed to bind OpenGL|ES API: %s", gst_gl_egl_get_error_string ()); + goto failure; + } + + egl->gl_api = GST_GL_API_GLES2; + } + + if (!gst_gl_egl_choose_config (egl, error)) { + g_assert (error == NULL || *error != NULL); + goto failure; + } + + GST_DEBUG ("about to create gl context\n"); + + if (egl->gl_api & GST_GL_API_GLES2) { + context_attrib[i++] = EGL_CONTEXT_CLIENT_VERSION; + context_attrib[i++] = 2; + } + context_attrib[i++] = EGL_NONE; + + egl->egl_context = + eglCreateContext (egl->egl_display, egl->egl_config, + (EGLContext) external_gl_context, context_attrib); + + if (egl->egl_context != EGL_NO_CONTEXT) { + GST_INFO ("gl context created: %ld", (gulong) egl->egl_context); + } else { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT, + "Failed to create a OpenGL context: %s", + gst_gl_egl_get_error_string ()); + goto failure; + } + + egl->egl_surface = + eglCreateWindowSurface (egl->egl_display, egl->egl_config, window, NULL); + + if (egl->egl_surface != EGL_NO_SURFACE) { + GST_INFO ("surface created"); + } else { + g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, + "Failed to create window surface: %s", gst_gl_egl_get_error_string ()); + goto failure; + } + + gst_gl_egl_activate (egl, TRUE); + + return egl; + +failure: + gst_gl_egl_destroy_context (egl); + + return NULL; +} + +void +gst_gl_egl_destroy_context (GstGLEGL * egl) +{ + gst_gl_egl_activate (egl, FALSE); + + if (egl->egl_surface) + eglDestroySurface (egl->egl_surface, egl->egl_display); + + if (egl->egl_context) + eglDestroyContext (egl->egl_display, egl->egl_context); + + if (egl->egl_display) { + eglTerminate (egl->egl_display); + eglReleaseThread (); + } + + g_slice_free (GstGLEGL, egl); +} + +gboolean +gst_gl_egl_activate (GstGLEGL * egl, gboolean activate) +{ + gboolean result; + + if (activate) + result = eglMakeCurrent (egl->egl_display, egl->egl_surface, + egl->egl_surface, egl->egl_context); + else + result = eglMakeCurrent (egl->egl_display, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); + + return result; +} + +guintptr +gst_gl_egl_get_gl_context (GstGLEGL * egl) +{ + return (guintptr) egl->egl_context; +} + +void +gst_gl_egl_swap_buffers (GstGLEGL * egl) +{ + eglSwapBuffers (egl->egl_display, egl->egl_surface); +} + +GstGLAPI +gst_gl_egl_get_gl_api (GstGLEGL * egl) +{ + return egl->gl_api; +} + +gpointer +gst_gl_egl_get_proc_address (GstGLEGL * egl, const gchar * name) +{ + gpointer result; + + result = eglGetProcAddress (name); + + return result; +} diff --git a/gst-libs/gst/gl/gstglegl.h b/gst-libs/gst/gl/gstglegl.h new file mode 100644 index 0000000..426182f --- /dev/null +++ b/gst-libs/gst/gl/gstglegl.h @@ -0,0 +1,55 @@ +/* + * GStreamer + * Copyright (C) 2013 Sebastian Dröge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_GL_EGL_H__ +#define __GST_GL_EGL_H__ + +#include +#include + +#include "gstglwindow.h" + +G_BEGIN_DECLS + +typedef struct _GstGLEGL GstGLEGL; + +struct _GstGLEGL { + EGLContext egl_context; + EGLDisplay egl_display; + EGLSurface egl_surface; + EGLConfig egl_config; + + GstGLAPI gl_api; +}; + +GstGLEGL * gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window, GstGLAPI gl_api, guintptr external_gl_context, GError ** error); +void gst_gl_egl_destroy_context (GstGLEGL *egl); + +gboolean gst_gl_egl_activate (GstGLEGL *egl, gboolean activate); +void gst_gl_egl_swap_buffers (GstGLEGL *egl); + +guintptr gst_gl_egl_get_gl_context (GstGLEGL *egl); +GstGLAPI gst_gl_egl_get_gl_api (GstGLEGL *egl); + +gpointer gst_gl_egl_get_proc_address (GstGLEGL *egl, const gchar * name); + +G_END_DECLS + +#endif /* __GST_GL_EGL_H__ */ diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c index 7fe27d3..1dd8112 100644 --- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c +++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c @@ -172,8 +172,6 @@ static const struct wl_shell_surface_listener shell_surface_listener = { static gboolean create_surface (GstGLWindowWaylandEGL * window_egl) { - EGLBoolean ret; - window_egl->window.surface = wl_compositor_create_surface (window_egl->display.compositor); window_egl->window.shell_surface = @@ -191,23 +189,16 @@ create_surface (GstGLWindowWaylandEGL * window_egl) window_egl->window.native = wl_egl_window_create (window_egl->window.surface, window_egl->window.window_width, window_egl->window.window_height); - window_egl->egl_surface = - eglCreateWindowSurface (window_egl->egl_display, window_egl->egl_config, - window_egl->window.native, NULL); wl_shell_surface_set_title (window_egl->window.shell_surface, "OpenGL Renderer"); - ret = - eglMakeCurrent (window_egl->egl_display, window_egl->egl_surface, - window_egl->egl_surface, window_egl->egl_context); - wl_shell_surface_set_toplevel (window_egl->window.shell_surface); wl_shell_surface_set_fullscreen (window_egl->window.shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL); - return ret == EGL_TRUE; + return TRUE; } static void @@ -282,7 +273,6 @@ gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass) static void gst_gl_window_wayland_egl_init (GstGLWindowWaylandEGL * window) { - window->gl_api = GST_GL_API_NONE; } /* Must be called in the gl thread */ @@ -363,148 +353,20 @@ error: return FALSE; } - -static gboolean -_gst_gl_window_wayland_egl_choose_config (GstGLWindowWaylandEGL * window_egl, - GError ** error) -{ - EGLint numConfigs; - gint i = 0; - EGLint config_attrib[20]; - - config_attrib[i++] = EGL_SURFACE_TYPE; - config_attrib[i++] = EGL_WINDOW_BIT; - config_attrib[i++] = EGL_RENDERABLE_TYPE; - if (window_egl->gl_api & GST_GL_API_GLES2) - config_attrib[i++] = EGL_OPENGL_ES2_BIT; - else - config_attrib[i++] = EGL_OPENGL_BIT; - config_attrib[i++] = EGL_DEPTH_SIZE; - config_attrib[i++] = 16; - config_attrib[i++] = EGL_NONE; - - if (eglChooseConfig (window_egl->egl_display, config_attrib, - &window_egl->egl_config, 1, &numConfigs)) - GST_INFO ("config set: %ld, %ld", (gulong) window_egl->egl_config, - (gulong) numConfigs); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG, - "Failed to set window configuration: %s", WlEGLErrorString ()); - goto failure; - } - - return TRUE; - -failure: - return FALSE; -} - gboolean gst_gl_window_wayland_egl_create_context (GstGLWindow * window, GstGLAPI gl_api, guintptr external_gl_context, GError ** error) { GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); - - EGLint context_attrib[3]; - gint i = 0; - - EGLint majorVersion; - EGLint minorVersion; - if (!_setup_wayland (window_egl, error)) return FALSE; - window_egl->egl_display = - eglGetDisplay ((EGLNativeDisplayType) window_egl->display.display); - - if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion)) - GST_DEBUG ("egl initialized: %d.%d", majorVersion, minorVersion); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, - GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, - "Failed to initialize egl: %s", WlEGLErrorString ()); - goto failure; - } - - if (gl_api & GST_GL_API_OPENGL) { - /* egl + opengl only available with EGL 1.4+ */ - if (majorVersion == 1 && minorVersion <= 3) { - if ((gl_api & ~GST_GL_API_OPENGL) == GST_GL_API_NONE) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS, - "EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", - majorVersion, minorVersion); - goto failure; - } else { - GST_WARNING - ("EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", - majorVersion, minorVersion); - if (gl_api & GST_GL_API_GLES2) { - goto try_gles2; - } else { - g_set_error (error, GST_GL_WINDOW_ERROR, - GST_GL_WINDOW_ERROR_WRONG_CONFIG, - "Failed to choose a suitable OpenGL API"); - goto failure; - } - } - } - - if (!eglBindAPI (EGL_OPENGL_API)) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, - "Failed to bind OpenGL|ES API: %s", WlEGLErrorString ()); - goto failure; - } - - window_egl->gl_api = GST_GL_API_OPENGL; - } else if (gl_api & GST_GL_API_GLES2) { - try_gles2: - if (!eglBindAPI (EGL_OPENGL_ES_API)) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, - "Failed to bind OpenGL|ES API: %s", WlEGLErrorString ()); - goto failure; - } - - window_egl->gl_api = GST_GL_API_GLES2; - } - - if (!_gst_gl_window_wayland_egl_choose_config (window_egl, error)) { - g_assert (error == NULL || *error != NULL); + window_egl->egl = + gst_gl_egl_create_context (eglGetDisplay ((EGLNativeDisplayType) + window_egl->display.display), window_egl->window.native, gl_api, + external_gl_context, error); + if (!window_egl->egl) goto failure; - } - - GST_DEBUG ("about to create gl context"); - - if (window_egl->gl_api & GST_GL_API_GLES2) { - context_attrib[i++] = EGL_CONTEXT_CLIENT_VERSION; - context_attrib[i++] = 2; - } - context_attrib[i++] = EGL_NONE; - - window_egl->egl_context = - eglCreateContext (window_egl->egl_display, window_egl->egl_config, - (EGLContext) external_gl_context, context_attrib); - - if (window_egl->egl_context != EGL_NO_CONTEXT) - GST_DEBUG ("gl context created: %ld", (gulong) window_egl->egl_context); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT, - "Failed to create a OpenGL context: %s", WlEGLErrorString ()); - goto failure; - } - - create_surface (window_egl); -/* window_egl->egl_surface = - eglCreateWindowSurface (window_egl->egl_display, window_egl->config, - (EGLNativeWindowType) window_wayland_egl->internal_win_id, NULL); - if (window_egl->egl_surface != EGL_NO_SURFACE) - GST_DEBUG ("surface created: %ld", (gulong) window_egl->egl_surface); - else { - GST_DEBUG ("failed to create surface %ld, %ld, %ld, %s", - (gulong) window_egl->egl_display, (gulong) window_egl->egl_surface, - (gulong) window_egl->egl_display, WlEGLErrorString ()); - goto failure; - } -*/ return TRUE; @@ -515,49 +377,44 @@ failure: static void gst_gl_window_wayland_egl_destroy_context (GstGLWindowWaylandEGL * window_egl) { - gst_gl_window_wayland_egl_activate (GST_GL_WINDOW (window_egl), FALSE); + gst_gl_egl_activate (window_egl->egl, FALSE); destroy_surface (window_egl); - - if (window_egl->egl_context) - eglDestroyContext (window_egl->egl_display, window_egl->egl_context); - - if (window_egl->egl_display) { - eglTerminate (window_egl->egl_display); - eglReleaseThread (); - } + /* + gst_gl_egl_destroy_surface (window_egl->egl); + */ + gst_gl_egl_destroy_context (window_egl->egl); + window_egl->egl = NULL; } static gboolean gst_gl_window_wayland_egl_activate (GstGLWindow * window, gboolean activate) { - gboolean result; GstGLWindowWaylandEGL *window_egl; window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); - GST_DEBUG ("activate:%s", activate ? "TRUE" : "FALSE"); - - if (activate) - result = eglMakeCurrent (window_egl->egl_display, window_egl->egl_surface, - window_egl->egl_surface, window_egl->egl_context); - else - result = eglMakeCurrent (window_egl->egl_display, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); - - return result; + return gst_gl_egl_activate (window_egl->egl, activate); } static guintptr gst_gl_window_wayland_egl_get_gl_context (GstGLWindow * window) { - return (guintptr) GST_GL_WINDOW_WAYLAND_EGL (window)->egl_context; + GstGLWindowWaylandEGL *window_egl; + + window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); + + return gst_gl_egl_get_gl_context (window_egl->egl); } static GstGLAPI gst_gl_window_wayland_egl_get_gl_api (GstGLWindow * window) { - return GST_GL_WINDOW_WAYLAND_EGL (window)->gl_api; + GstGLWindowWaylandEGL *window_egl; + + window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); + + return gst_gl_egl_get_gl_api (window_egl->egl); } static void @@ -565,7 +422,7 @@ gst_gl_window_wayland_egl_swap_buffers (GstGLWindow * window) { GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); - eglSwapBuffers (window_egl->egl_display, window_egl->egl_surface); + gst_gl_egl_swap_buffers (window_egl->egl); } static void @@ -716,49 +573,14 @@ static gpointer gst_gl_window_wayland_egl_get_proc_address (GstGLWindow * window, const gchar * name) { + GstGLWindowWaylandEGL *window_egl; gpointer result; - if (!(result = eglGetProcAddress (name))) { + window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); + + if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) { result = gst_gl_window_default_get_proc_address (window, name); } return result; } - -const gchar * -WlEGLErrorString () -{ - EGLint nErr = eglGetError (); - switch (nErr) { - case EGL_SUCCESS: - return "EGL_SUCCESS"; - case EGL_BAD_DISPLAY: - return "EGL_BAD_DISPLAY"; - case EGL_NOT_INITIALIZED: - return "EGL_NOT_INITIALIZED"; - case EGL_BAD_ACCESS: - return "EGL_BAD_ACCESS"; - case EGL_BAD_ALLOC: - return "EGL_BAD_ALLOC"; - case EGL_BAD_ATTRIBUTE: - return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_CONFIG: - return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: - return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: - return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_MATCH: - return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: - return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: - return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: - return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: - return "EGL_BAD_SURFACE"; - default: - return "unknown"; - } -} diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h index d7a3105..26c920f 100644 --- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h +++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h @@ -28,6 +28,7 @@ #include #include "gstglwindow.h" +#include "gstglegl.h" G_BEGIN_DECLS @@ -74,10 +75,7 @@ struct _GstGLWindowWaylandEGL { /*< private >*/ GstGLWindow parent; - EGLContext egl_context; - EGLDisplay egl_display; - EGLSurface egl_surface; - EGLConfig egl_config; + GstGLEGL *egl; struct display display; struct window window; @@ -86,8 +84,6 @@ struct _GstGLWindowWaylandEGL { GMainContext *main_context; GMainLoop *loop; - GstGLAPI gl_api; - gpointer _reserved[GST_PADDING]; }; diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11_egl.c b/gst-libs/gst/gl/x11/gstglwindow_x11_egl.c index e21158a..7ff1347 100644 --- a/gst-libs/gst/gl/x11/gstglwindow_x11_egl.c +++ b/gst-libs/gst/gl/x11/gstglwindow_x11_egl.c @@ -108,51 +108,11 @@ gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * window_x11, } static gboolean -_gst_gl_window_x11_egl_choose_config (GstGLWindowX11EGL * window_egl, - GError ** error) -{ - EGLint numConfigs; - gint i = 0; - EGLint config_attrib[20]; - - config_attrib[i++] = EGL_SURFACE_TYPE; - config_attrib[i++] = EGL_WINDOW_BIT; - config_attrib[i++] = EGL_RENDERABLE_TYPE; - if (window_egl->gl_api & GST_GL_API_GLES2) - config_attrib[i++] = EGL_OPENGL_ES2_BIT; - else - config_attrib[i++] = EGL_OPENGL_BIT; - config_attrib[i++] = EGL_DEPTH_SIZE; - config_attrib[i++] = 16; - config_attrib[i++] = EGL_NONE; - - if (eglChooseConfig (window_egl->egl_display, config_attrib, - &window_egl->egl_config, 1, &numConfigs)) - GST_INFO ("config set: %ld, %ld", (gulong) window_egl->egl_config, - (gulong) numConfigs); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG, - "Failed to set window configuration: %s", X11EGLErrorString ()); - goto failure; - } - - return TRUE; - -failure: - return FALSE; -} - -static gboolean gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11, GstGLAPI gl_api, guintptr external_gl_context, GError ** error) { GstGLWindowX11EGL *window_egl; - gint i = 0; - EGLint context_attrib[3]; - EGLint majorVersion; - EGLint minorVersion; - if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE && (gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) { g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API, @@ -162,94 +122,13 @@ gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11, window_egl = GST_GL_WINDOW_X11_EGL (window_x11); - window_egl->egl_display = - eglGetDisplay ((EGLNativeDisplayType) window_x11->device); - - if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion)) - GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, - GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, - "Failed to initialize egl: %s", X11EGLErrorString ()); + window_egl->egl = + gst_gl_egl_create_context (eglGetDisplay ((EGLNativeDisplayType) + window_x11->device), + (EGLNativeWindowType) window_x11->internal_win_id, gl_api, + external_gl_context, error); + if (!window_egl->egl) goto failure; - } - - if (gl_api & GST_GL_API_OPENGL) { - /* egl + opengl only available with EGL 1.4+ */ - if (majorVersion == 1 && minorVersion <= 3) { - if ((gl_api & ~GST_GL_API_OPENGL) == GST_GL_API_NONE) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS, - "EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", - majorVersion, minorVersion); - goto failure; - } else { - GST_WARNING - ("EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", - majorVersion, minorVersion); - if (gl_api & GST_GL_API_GLES2) { - goto try_gles2; - } else { - g_set_error (error, GST_GL_WINDOW_ERROR, - GST_GL_WINDOW_ERROR_WRONG_CONFIG, - "Failed to choose a suitable OpenGL API"); - goto failure; - } - } - } - - if (!eglBindAPI (EGL_OPENGL_API)) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, - "Failed to bind OpenGL|ES API: %s", X11EGLErrorString ()); - goto failure; - } - - window_egl->gl_api = GST_GL_API_OPENGL; - } else if (gl_api & GST_GL_API_GLES2) { - try_gles2: - if (!eglBindAPI (EGL_OPENGL_ES_API)) { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, - "Failed to bind OpenGL|ES API: %s", X11EGLErrorString ()); - goto failure; - } - - window_egl->gl_api = GST_GL_API_GLES2; - } - - if (!_gst_gl_window_x11_egl_choose_config (window_egl, error)) { - g_assert (error == NULL || *error != NULL); - goto failure; - } - - window_egl->egl_surface = - eglCreateWindowSurface (window_egl->egl_display, window_egl->egl_config, - (EGLNativeWindowType) window_x11->internal_win_id, NULL); - if (window_egl->egl_surface != EGL_NO_SURFACE) - GST_INFO ("surface created"); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED, - "Failed to create window surface: %s", X11EGLErrorString ()); - goto failure; - } - - GST_DEBUG ("about to create gl context\n"); - - if (window_egl->gl_api & GST_GL_API_GLES2) { - context_attrib[i++] = EGL_CONTEXT_CLIENT_VERSION; - context_attrib[i++] = 2; - } - context_attrib[i++] = EGL_NONE; - - window_egl->egl_context = - eglCreateContext (window_egl->egl_display, window_egl->egl_config, - (EGLContext) external_gl_context, context_attrib); - - if (window_egl->egl_context != EGL_NO_CONTEXT) - GST_INFO ("gl context created: %ld", (gulong) window_egl->egl_context); - else { - g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT, - "Failed to create a OpenGL context: %s", X11EGLErrorString ()); - goto failure; - } return TRUE; @@ -264,35 +143,28 @@ gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11) window_egl = GST_GL_WINDOW_X11_EGL (window_x11); - if (window_egl->egl_context) - eglDestroyContext (window_x11->device, window_egl->egl_context); - - if (window_x11->device) - eglTerminate (window_x11->device); + gst_gl_egl_destroy_context (window_egl->egl); + window_egl->egl = NULL; } static gboolean gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11, gboolean activate) { - gboolean result; GstGLWindowX11EGL *window_egl; window_egl = GST_GL_WINDOW_X11_EGL (window_x11); - if (activate) - result = eglMakeCurrent (window_egl->egl_display, window_egl->egl_surface, - window_egl->egl_surface, window_egl->egl_context); - else - result = eglMakeCurrent (window_egl->egl_display, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); - - return result; + return gst_gl_egl_activate (window_egl->egl, activate); } static guintptr gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 * window_x11) { - return (guintptr) GST_GL_WINDOW_X11_EGL (window_x11)->egl_context; + GstGLWindowX11EGL *window_egl; + + window_egl = GST_GL_WINDOW_X11_EGL (window_x11); + + return gst_gl_egl_get_gl_context (window_egl->egl); } static void @@ -300,7 +172,7 @@ gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11) { GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window_x11); - eglSwapBuffers (window_egl->egl_display, window_egl->egl_surface); + gst_gl_egl_swap_buffers (window_egl->egl); } GstGLAPI @@ -308,57 +180,20 @@ gst_gl_window_x11_egl_get_gl_api (GstGLWindow * window) { GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window); - return window_egl->gl_api ? window_egl-> - gl_api : GST_GL_API_GLES2 | GST_GL_API_OPENGL; + return window_egl->egl ? gst_gl_egl_get_gl_api (window_egl-> + egl) : GST_GL_API_GLES2 | GST_GL_API_OPENGL; } static gpointer gst_gl_window_x11_egl_get_proc_address (GstGLWindow * window, const gchar * name) { + GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window); gpointer result; - if (!(result = eglGetProcAddress (name))) { + if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) { result = gst_gl_window_default_get_proc_address (window, name); } return result; } - -const gchar * -X11EGLErrorString () -{ - EGLint nErr = eglGetError (); - switch (nErr) { - case EGL_SUCCESS: - return "EGL_SUCCESS"; - case EGL_BAD_DISPLAY: - return "EGL_BAD_DISPLAY"; - case EGL_NOT_INITIALIZED: - return "EGL_NOT_INITIALIZED"; - case EGL_BAD_ACCESS: - return "EGL_BAD_ACCESS"; - case EGL_BAD_ALLOC: - return "EGL_BAD_ALLOC"; - case EGL_BAD_ATTRIBUTE: - return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_CONFIG: - return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: - return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: - return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_MATCH: - return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: - return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: - return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: - return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: - return "EGL_BAD_SURFACE"; - default: - return "unknown"; - } -} diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11_egl.h b/gst-libs/gst/gl/x11/gstglwindow_x11_egl.h index 901558e..9f9fce5 100644 --- a/gst-libs/gst/gl/x11/gstglwindow_x11_egl.h +++ b/gst-libs/gst/gl/x11/gstglwindow_x11_egl.h @@ -22,6 +22,7 @@ #define __GST_GL_WINDOW_X11_EGL_H__ #include "gstglwindow_x11.h" +#include "gstglegl.h" #include @@ -41,12 +42,7 @@ struct _GstGLWindowX11EGL { /*< private >*/ GstGLWindowX11 parent; - EGLContext egl_context; - EGLDisplay egl_display; - EGLSurface egl_surface; - EGLConfig egl_config; - - GstGLAPI gl_api; + GstGLEGL *egl; gpointer _reserved[GST_PADDING]; }; -- 2.7.4