[629/906] window: add GError for error handling of context creation

This commit is contained in:
Matthew Waters 2012-12-09 09:30:48 +11:00 committed by Tim-Philipp Müller
parent 6c0e32864a
commit c3526080aa
19 changed files with 249 additions and 198 deletions

View file

@ -23,7 +23,6 @@
#include <gst/gst.h> #include <gst/gst.h>
#include "gstglapi.h"
#include "gstglwindow.h" #include "gstglwindow.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -60,7 +59,8 @@ struct _GstGLWindowCocoaClass {
GType gst_gl_window_cocoa_get_type (void); GType gst_gl_window_cocoa_get_type (void);
GstGLWindowCocoa * gst_gl_window_cocoa_new (GstGLAPI gl_api, GstGLWindowCocoa * gst_gl_window_cocoa_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -197,7 +197,7 @@ gst_gl_window_cocoa_init (GstGLWindowCocoa * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowCocoa * GstGLWindowCocoa *
gst_gl_window_cocoa_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_cocoa_new (GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowCocoa *window = g_object_new (GST_GL_TYPE_WINDOW_COCOA, NULL); GstGLWindowCocoa *window = g_object_new (GST_GL_TYPE_WINDOW_COCOA, NULL);
GstGLWindowCocoaPrivate *priv = window->priv; GstGLWindowCocoaPrivate *priv = window->priv;

View file

@ -42,22 +42,6 @@
# endif # endif
#endif #endif
#if HAVE_GLX
# include <GL/glx.h>
#endif
#if HAVE_EGL
# undef UNICODE
# include <EGL/egl.h>
# define UNICODE
#endif
#if HAVE_WGL
# undef UNICODE
# include <windows.h>
# define UNICODE
#endif
#include <gst/gst.h> #include <gst/gst.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View file

@ -43,6 +43,12 @@ GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
#define gst_gl_window_parent_class parent_class #define gst_gl_window_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT); G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
GQuark
gst_gl_window_error_quark (void)
{
return g_quark_from_static_string ("gst-gl-window-error-quark");
}
static void static void
gst_gl_window_init (GstGLWindow * window) gst_gl_window_init (GstGLWindow * window)
{ {
@ -56,12 +62,14 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
} }
GstGLWindow * GstGLWindow *
gst_gl_window_new (GstGLAPI api, guintptr external_gl_context) gst_gl_window_new (GstGLAPI api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindow *window = NULL; GstGLWindow *window = NULL;
const gchar *user_choice; const gchar *user_choice;
static volatile gsize _init = 0; static volatile gsize _init = 0;
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (g_once_init_enter (&_init)) { if (g_once_init_enter (&_init)) {
GST_DEBUG_CATEGORY_INIT (gst_gl_window_debug, "glwindow", 0, GST_DEBUG_CATEGORY_INIT (gst_gl_window_debug, "glwindow", 0,
"glwindow element"); "glwindow element");
@ -73,25 +81,39 @@ gst_gl_window_new (GstGLAPI api, guintptr external_gl_context)
#ifdef HAVE_WINDOW_X11 #ifdef HAVE_WINDOW_X11
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "x11"))) if (!window && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
window = GST_GL_WINDOW (gst_gl_window_x11_new (api, external_gl_context)); window =
GST_GL_WINDOW (gst_gl_window_x11_new (api, external_gl_context, error));
#endif #endif
#ifdef HAVE_WINDOW_WIN32 #ifdef HAVE_WINDOW_WIN32
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "win32"))) if (!window && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
window = GST_GL_WINDOW (gst_gl_window_win32_new (api, external_gl_context)); window =
GST_GL_WINDOW (gst_gl_window_win32_new (api, external_gl_context,
error));
#endif #endif
#ifdef HAVE_WINDOW_COCOA #ifdef HAVE_WINDOW_COCOA
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa")))
window = GST_GL_WINDOW (gst_gl_window_cocoa_new (api, external_gl_context)); window =
GST_GL_WINDOW (gst_gl_window_cocoa_new (api, external_gl_context,
error));
#endif #endif
#ifdef HAVE_WINDOW_WAYLAND #ifdef HAVE_WINDOW_WAYLAND
if (!window && (!user_choice || g_strstr_len (user_choice, 7, "wayland"))) if (!window && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
window = window =
GST_GL_WINDOW (gst_gl_window_wayland_egl_new (api, GST_GL_WINDOW (gst_gl_window_wayland_egl_new (api,
external_gl_context)); external_gl_context, error));
#endif #endif
if (!window) { if (!window) {
GST_WARNING ("could not create a window, user choice:%s", user_choice); if (error && !*error) {
/* FIXME: set and return a GError */ if (user_choice) {
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
"Could not create %s window", user_choice);
} else {
/* subclass did not set an error yet returned a NULL window */
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
"Could not create %s window, Unknown Error",
user_choice ? user_choice : "");
}
}
return NULL; return NULL;
} }

View file

@ -51,6 +51,14 @@ G_BEGIN_DECLS
#define GST_GL_WINDOW_ERROR (gst_gl_window_error_quark ()) #define GST_GL_WINDOW_ERROR (gst_gl_window_error_quark ())
typedef enum
{
GST_GL_WINDOW_ERROR_FAILED,
GST_GL_WINDOW_ERROR_WRONG_CONFIG,
GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
} GstGLWindowError;
typedef void (*GstGLWindowCB) (gpointer data); typedef void (*GstGLWindowCB) (gpointer data);
typedef void (*GstGLWindowResizeCB) (gpointer data, guint width, guint height); typedef void (*GstGLWindowResizeCB) (gpointer data, guint width, guint height);
@ -106,7 +114,7 @@ struct _GstGLWindowClass {
GQuark gst_gl_window_error_quark (void); GQuark gst_gl_window_error_quark (void);
GType gst_gl_window_get_type (void); GType gst_gl_window_get_type (void);
GstGLWindow * gst_gl_window_new (GstGLAPI gl_api, guintptr external_gl_context); GstGLWindow * gst_gl_window_new (GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data); void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowResizeCB callback, gpointer data); void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowResizeCB callback, gpointer data);

View file

@ -52,7 +52,8 @@ static void gst_gl_window_wayland_egl_send_message (GstGLWindow * window,
static void gst_gl_window_wayland_egl_destroy_context (GstGLWindowWaylandEGL * static void gst_gl_window_wayland_egl_destroy_context (GstGLWindowWaylandEGL *
window_egl); window_egl);
static gboolean gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL static gboolean gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL
* window_egl, GstGLAPI gl_api, guintptr external_gl_context); * window_egl, GstGLAPI gl_api, guintptr external_gl_context,
GError ** error);
GstGLAPI gst_gl_window_wayland_egl_get_gl_api (GstGLWindow * window); GstGLAPI gst_gl_window_wayland_egl_get_gl_api (GstGLWindow * window);
static void gst_gl_window_wayland_egl_finalize (GObject * object); static void gst_gl_window_wayland_egl_finalize (GObject * object);
@ -285,7 +286,8 @@ gst_gl_window_wayland_egl_init (GstGLWindowWaylandEGL * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowWaylandEGL * GstGLWindowWaylandEGL *
gst_gl_window_wayland_egl_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_wayland_egl_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowWaylandEGL *window; GstGLWindowWaylandEGL *window;
@ -296,7 +298,12 @@ gst_gl_window_wayland_egl_new (GstGLAPI gl_api, guintptr external_gl_context)
gst_gl_window_set_need_lock (GST_GL_WINDOW (window), FALSE); gst_gl_window_set_need_lock (GST_GL_WINDOW (window), FALSE);
window->display.display = wl_display_connect (NULL); window->display.display = wl_display_connect (NULL);
g_assert (window->display.display); if (!window->display.display) {
g_set_error (error, GST_GL_WINDOW_ERROR,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"Failed to connect to Wayland display server");
goto error;
}
window->display.registry = wl_display_get_registry (window->display.display); window->display.registry = wl_display_get_registry (window->display.display);
wl_registry_add_listener (window->display.registry, &registry_listener, wl_registry_add_listener (window->display.registry, &registry_listener,
@ -316,9 +323,16 @@ gst_gl_window_wayland_egl_new (GstGLAPI gl_api, guintptr external_gl_context)
g_source_attach (window->wl_source, window->main_context); g_source_attach (window->wl_source, window->main_context);
gst_gl_window_wayland_egl_create_context (window, gl_api, gst_gl_window_wayland_egl_create_context (window, gl_api,
external_gl_context); external_gl_context, error);
return window; return window;
error:
{
if (window)
g_object_unref (window);
return NULL;
}
} }
static void static void
@ -330,7 +344,9 @@ gst_gl_window_wayland_egl_finalize (GObject * object)
gst_gl_window_wayland_egl_destroy_context (window_egl); gst_gl_window_wayland_egl_destroy_context (window_egl);
if (window_egl->display.cursor_surface)
wl_surface_destroy (window_egl->display.cursor_surface); wl_surface_destroy (window_egl->display.cursor_surface);
if (window_egl->display.cursor_theme) if (window_egl->display.cursor_theme)
wl_cursor_theme_destroy (window_egl->display.cursor_theme); wl_cursor_theme_destroy (window_egl->display.cursor_theme);
@ -340,15 +356,17 @@ gst_gl_window_wayland_egl_finalize (GObject * object)
if (window_egl->display.compositor) if (window_egl->display.compositor)
wl_compositor_destroy (window_egl->display.compositor); wl_compositor_destroy (window_egl->display.compositor);
if (window_egl->display.display) {
wl_display_flush (window_egl->display.display); wl_display_flush (window_egl->display.display);
wl_display_disconnect (window_egl->display.display); wl_display_disconnect (window_egl->display.display);
}
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
static gboolean static gboolean
gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL * window_egl, gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL * window_egl,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
EGLint config_attrib[] = { EGLint config_attrib[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -376,13 +394,15 @@ gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL * window_egl,
if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion)) if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion))
GST_DEBUG ("egl initialized: %d.%d", majorVersion, minorVersion); GST_DEBUG ("egl initialized: %d.%d", majorVersion, minorVersion);
else { else {
GST_DEBUG ("failed to initialize egl %ld, %s", g_set_error (error, GST_GL_WINDOW_ERROR,
(gulong) window_egl->egl_display, WlEGLErrorString ()); GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"Failed to initialize egl: %s", WlEGLErrorString ());
goto failure; goto failure;
} }
if (!eglBindAPI (EGL_OPENGL_ES_API)) { if (!eglBindAPI (EGL_OPENGL_ES_API)) {
GST_WARNING ("failed to bind 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; goto failure;
} }
@ -391,8 +411,8 @@ gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL * window_egl,
GST_DEBUG ("config set: %ld, %ld", (gulong) window_egl->egl_config, GST_DEBUG ("config set: %ld, %ld", (gulong) window_egl->egl_config,
(gulong) numConfigs); (gulong) numConfigs);
else { else {
GST_DEBUG ("failed to set config %ld, %s", (gulong) window_egl->egl_display, g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
WlEGLErrorString ()); "Failed to set window configuration: %s", WlEGLErrorString ());
goto failure; goto failure;
} }
@ -405,9 +425,8 @@ gst_gl_window_wayland_egl_create_context (GstGLWindowWaylandEGL * window_egl,
if (window_egl->egl_context != EGL_NO_CONTEXT) if (window_egl->egl_context != EGL_NO_CONTEXT)
GST_DEBUG ("gl context created: %ld", (gulong) window_egl->egl_context); GST_DEBUG ("gl context created: %ld", (gulong) window_egl->egl_context);
else { else {
GST_DEBUG ("failed to create glcontext %ld, %ld, %s", g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
(gulong) window_egl->egl_context, (gulong) window_egl->egl_display, "Failed to create a OpenGL context: %s", WlEGLErrorString ());
WlEGLErrorString ());
goto failure; goto failure;
} }

View file

@ -25,7 +25,8 @@
#include <wayland-egl.h> #include <wayland-egl.h>
#include <wayland-cursor.h> #include <wayland-cursor.h>
#include "gstglapi.h" #include <EGL/egl.h>
#include "gstglwindow.h" #include "gstglwindow.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -99,7 +100,8 @@ struct _GstGLWindowWaylandEGLClass {
GType gst_gl_window_wayland_egl_get_type (void); GType gst_gl_window_wayland_egl_get_type (void);
GstGLWindowWaylandEGL * gst_gl_window_wayland_egl_new (GstGLAPI gl_api, GstGLWindowWaylandEGL * gst_gl_window_wayland_egl_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -53,6 +53,7 @@ struct _GstGLWindowWin32Private
{ {
GstGLAPI gl_api; GstGLAPI gl_api;
guintptr external_gl_context; guintptr external_gl_context;
GError **error;
gboolean activate; gboolean activate;
gboolean activate_result; gboolean activate_result;
}; };
@ -138,7 +139,8 @@ gst_gl_window_win32_init (GstGLWindowWin32 * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowWin32 * GstGLWindowWin32 *
gst_gl_window_win32_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_win32_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowWin32 *window = NULL; GstGLWindowWin32 *window = NULL;
const gchar *user_choice; const gchar *user_choice;
@ -149,28 +151,30 @@ gst_gl_window_win32_new (GstGLAPI gl_api, guintptr external_gl_context)
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "wgl"))) if (!window && (!user_choice || g_strstr_len (user_choice, 3, "wgl")))
window = window =
GST_GL_WINDOW_WIN32 (gst_gl_window_win32_wgl_new (gl_api, GST_GL_WINDOW_WIN32 (gst_gl_window_win32_wgl_new (gl_api,
external_gl_context)); external_gl_context, error));
#endif #endif
#if HAVE_EGL #if HAVE_EGL
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl"))) if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl")))
window = window =
GST_GL_WINDOW_WIN32 (gst_gl_window_win32_egl_new (gl_api, GST_GL_WINDOW_WIN32 (gst_gl_window_win32_egl_new (gl_api,
external_gl_context)); external_gl_context, error));
#endif #endif
if (!window) { if (!window) {
GST_WARNING ("Failed to create x11 window, user_choice:%s", GST_WARNING ("Failed to create win32 window, user_choice:%s",
user_choice ? user_choice : "NULL"); user_choice ? user_choice : "NULL");
return NULL; return NULL;
} }
window->priv->gl_api = gl_api; window->priv->gl_api = gl_api;
window->priv->external_gl_context = external_gl_context; window->priv->external_gl_context = external_gl_context;
window->priv->error = error;
return window; return window;
} }
gboolean gboolean
gst_gl_window_win32_open_device (GstGLWindowWin32 * window_win32) gst_gl_window_win32_open_device (GstGLWindowWin32 * window_win32,
GError ** error)
{ {
HINSTANCE hinstance = GetModuleHandle (NULL); HINSTANCE hinstance = GetModuleHandle (NULL);
@ -261,7 +265,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
window_win32 = GST_GL_WINDOW_WIN32 (window); window_win32 = GST_GL_WINDOW_WIN32 (window);
//retrieve parent if previously set /* retrieve parent if previously set */
parent_id = GetProp (window_win32->internal_win_id, "gl_window_parent_id"); parent_id = GetProp (window_win32->internal_win_id, "gl_window_parent_id");
if (window_win32->visible) { if (window_win32->visible) {
@ -299,7 +303,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
WS_CHILD | WS_MAXIMIZE); WS_CHILD | WS_MAXIMIZE);
SetParent (window_win32->internal_win_id, (HWND) id); SetParent (window_win32->internal_win_id, (HWND) id);
//take changes into account: SWP_FRAMECHANGED /* take changes into account: SWP_FRAMECHANGED */
GetClientRect ((HWND) id, &rect); GetClientRect ((HWND) id, &rect);
SetWindowPos (window_win32->internal_win_id, HWND_TOP, rect.left, rect.top, SetWindowPos (window_win32->internal_win_id, HWND_TOP, rect.left, rect.top,
rect.right, rect.bottom, rect.right, rect.bottom,
@ -308,7 +312,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
MoveWindow (window_win32->internal_win_id, rect.left, rect.top, rect.right, MoveWindow (window_win32->internal_win_id, rect.left, rect.top, rect.right,
rect.bottom, FALSE); rect.bottom, FALSE);
} else { } else {
//no parent so the internal window needs borders and system menu /* no parent so the internal window needs borders and system menu */
SetWindowLongPtr (window_win32->internal_win_id, GWL_STYLE, SetWindowLongPtr (window_win32->internal_win_id, GWL_STYLE,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW); WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW);
} }
@ -427,7 +431,7 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
window_class->choose_format (window_win32); window_class->choose_format (window_win32);
window_class->create_context (window_win32, priv->gl_api, window_class->create_context (window_win32, priv->gl_api,
priv->external_gl_context); priv->external_gl_context, priv->error);
/* priv->gl_context = wglCreateContext (priv->device); /* priv->gl_context = wglCreateContext (priv->device);
if (priv->gl_context) if (priv->gl_context)

View file

@ -21,7 +21,6 @@
#ifndef __GST_GL_WINDOW_WIN32_H__ #ifndef __GST_GL_WINDOW_WIN32_H__
#define __GST_GL_WINDOW_WIN32_H__ #define __GST_GL_WINDOW_WIN32_H__
#include "gstglapi.h"
#include "gstglwindow.h" #include "gstglwindow.h"
#undef UNICODE #undef UNICODE
@ -61,8 +60,8 @@ struct _GstGLWindowWin32Class {
GstGLWindowClass parent_class; GstGLWindowClass parent_class;
gboolean (*choose_format) (GstGLWindowWin32 *window); gboolean (*choose_format) (GstGLWindowWin32 *window);
gboolean (*create_context) (GstGLWindowWin32 *window, GstGLRendererAPI render_api, gboolean (*create_context) (GstGLWindowWin32 *window, GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context, GError ** error);
gboolean (*share_context) (GstGLWindowWin32 *window, guintptr external_gl_context); gboolean (*share_context) (GstGLWindowWin32 *window, guintptr external_gl_context);
void (*swap_buffers) (GstGLWindowWin32 *window); void (*swap_buffers) (GstGLWindowWin32 *window);
gboolean (*activate) (GstGLWindowWin32 *window, gboolean activate); gboolean (*activate) (GstGLWindowWin32 *window, gboolean activate);
@ -76,8 +75,8 @@ struct _GstGLWindowWin32Class {
GType gst_gl_window_win32_get_type (void); GType gst_gl_window_win32_get_type (void);
GstGLWindowWin32 * gst_gl_window_win32_new (GstGLAPI gl_api, GstGLWindowWin32 * gst_gl_window_win32_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context, GError ** error);
gboolean gst_gl_window_win32_open_device (GstGLWindowWin32 *window_win32); gboolean gst_gl_window_win32_open_device (GstGLWindowWin32 *window_win32, GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -36,21 +36,19 @@ static gboolean gst_gl_window_win32_wgl_choose_format (GstGLWindowWin32 *
static gboolean gst_gl_window_win32_wgl_activate (GstGLWindowWin32 * static gboolean gst_gl_window_win32_wgl_activate (GstGLWindowWin32 *
window_win32, gboolean activate); window_win32, gboolean activate);
static gboolean gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * static gboolean gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 *
window_win32, GstGLAPI gl_api, guintptr external_gl_context); window_win32, GstGLAPI gl_api, guintptr external_gl_context,
GError ** error);
static void gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 * static void gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 *
window_win32); window_win32);
GstGLAPI gst_gl_window_win32_egl_get_gl_api (GstGLWindow * window); GstGLAPI gst_gl_window_win32_egl_get_gl_api (GstGLWindow * window);
const gchar *WinEGLErrorString (); const gchar *WinEGLErrorString ();
#define GST_CAT_DEFAULT gst_gl_window_win32_egl_debug #define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_win32_wgl_parent_class parent_class #define gst_gl_window_win32_wgl_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowWin32EGL, gst_gl_window_win32_egl, G_DEFINE_TYPE (GstGLWindowWin32EGL, gst_gl_window_win32_egl,
GST_GL_TYPE_WINDOW, DEBUG_INIT); GST_GL_TYPE_WINDOW);
static void static void
gst_gl_window_win32_egl_class_init (GstGLWindowWin32EGLClass * klass) gst_gl_window_win32_egl_class_init (GstGLWindowWin32EGLClass * klass)
@ -82,12 +80,13 @@ gst_gl_window_win32_egl_init (GstGLWindow * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowWin32EGL * GstGLWindowWin32EGL *
gst_gl_window_win32_egl_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_win32_egl_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowWin32EGL *window = GstGLWindowWin32EGL *window =
g_object_new (GST_GL_TYPE_WINDOW_WIN32_EGL, NULL); g_object_new (GST_GL_TYPE_WINDOW_WIN32_EGL, NULL);
gst_gl_window_win32_open_device (GST_GL_WINDOW_WIN32 (window)); gst_gl_window_win32_open_device (GST_GL_WINDOW_WIN32 (window), error);
return window; return window;
} }
@ -95,7 +94,8 @@ gst_gl_window_win32_egl_new (GstGLAPI gl_api, guintptr external_gl_context)
guintptr guintptr
gst_gl_window_win32_egl_get_gl_context (GstGLWindowWin32 * window_win32) gst_gl_window_win32_egl_get_gl_context (GstGLWindowWin32 * window_win32)
{ {
return (guintptr) GST_GL_WINDOW_WIN32_EGL (window_win32)->wgl_context} return (guintptr) GST_GL_WINDOW_WIN32_EGL (window_win32)->wgl_context;
}
static gboolean static gboolean
gst_gl_window_win32_egl_activate (GstGLWindowWin32 * window_win32, gst_gl_window_win32_egl_activate (GstGLWindowWin32 * window_win32,
@ -119,7 +119,7 @@ gst_gl_window_win32_egl_activate (GstGLWindowWin32 * window_win32,
static gboolean static gboolean
gst_gl_window_win32_egl_create_context (GstGLWindowWin32 * window_win32, gst_gl_window_win32_egl_create_context (GstGLWindowWin32 * window_win32,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowWin32EGL *window_egl; GstGLWindowWin32EGL *window_egl;
EGLint majorVersion; EGLint majorVersion;
@ -144,33 +144,36 @@ gst_gl_window_win32_egl_create_context (GstGLWindowWin32 * window_win32,
window_egl->display = eglGetDisplay (window_win32->device); window_egl->display = eglGetDisplay (window_win32->device);
if (priv->display != EGL_NO_DISPLAY) if (priv->display != EGL_NO_DISPLAY)
GST_DEBUG ("display retrieved: %d\n", window_egl->display); GST_DEBUG ("display retrieved: %d", window_egl->display);
else { else {
GST_DEBUG ("failed to retrieve display %s\n", WinEGLErrorString ()); g_set_error (error, GST_GL_WINDOW_ERROR,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"failed to retrieve display: %s", WinEGLErrorString ());
goto failure; goto failure;
} }
if (eglInitialize (priv->display, &majorVersion, &minorVersion)) if (eglInitialize (priv->display, &majorVersion, &minorVersion))
GST_DEBUG ("egl initialized: %d.%d\n", majorVersion, minorVersion); GST_DEBUG ("egl initialized: %d.%d", majorVersion, minorVersion);
else { else {
GST_DEBUG ("failed to initialize egl %d, %s\n", priv->display, g_set_error (error, GST_GL_WINDOW_ERROR,
WinEGLErrorString ()); GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"failed to initialize egl: %s", WinEGLErrorString ());
goto failure; goto failure;
} }
if (eglGetConfigs (window_egl->display, NULL, 0, &numConfigs)) if (eglGetConfigs (window_egl->display, NULL, 0, &numConfigs))
GST_DEBUG ("configs retrieved: %d\n", numConfigs); GST_DEBUG ("configs retrieved: %d", numConfigs);
else { else {
GST_DEBUG ("failed to retrieve configs %d, %s\n", window_egl->display, g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
WinEGLErrorString ()); "failed to retrieve configs %s", WinEGLErrorString ());
goto failure; goto failure;
} }
if (eglChooseConfig (priv->display, attribList, &config, 1, &numConfigs)) if (eglChooseConfig (priv->display, attribList, &config, 1, &numConfigs))
GST_DEBUG ("config set: %d, %d\n", config, numConfigs); GST_DEBUG ("config set: %d, %d", config, numConfigs);
else { else {
GST_DEBUG ("failed to set config %d, %s\n", window_egl->display, g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
WinEGLErrorString ()); "failed to set config %s", WinEGLErrorString ());
goto failure; goto failure;
} }
@ -178,10 +181,10 @@ gst_gl_window_win32_egl_create_context (GstGLWindowWin32 * window_win32,
eglCreateWindowSurface (window_egl->display, config, eglCreateWindowSurface (window_egl->display, config,
(EGLNativeWindowType) WindowFromDC (window_win32->device), NULL); (EGLNativeWindowType) WindowFromDC (window_win32->device), NULL);
if (priv->surface != EGL_NO_SURFACE) if (priv->surface != EGL_NO_SURFACE)
GST_DEBUG ("surface created: %d\n", window_egl->surface); GST_DEBUG ("surface created: %d", window_egl->surface);
else { else {
GST_DEBUG ("failed to create surface %d, %d, %s\n", window_egl->display, g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
window_egl->surface, WinEGLErrorString ()); "failed to create surface %s", WinEGLErrorString ());
goto failure; goto failure;
} }
@ -189,13 +192,12 @@ gst_gl_window_win32_egl_create_context (GstGLWindowWin32 * window_win32,
eglCreateContext (window_egl->display, config, external_gl_context, eglCreateContext (window_egl->display, config, external_gl_context,
contextAttribs); contextAttribs);
if (window_egl->egl_context != EGL_NO_CONTEXT) if (window_egl->egl_context != EGL_NO_CONTEXT)
GST_DEBUG ("gl context created: %lud, external: %lud\n", GST_DEBUG ("gl context created: %lud, external: %lud",
(gulong) window_egl->egl_context, (gulong) external_gl_context); (gulong) window_egl->egl_context, (gulong) external_gl_context);
else { else {
GST_DEBUG g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
("failed to create glcontext %lud, extenal: %lud, %s\n", "failed to create glcontext with external: %lud, %s",
(gulong) window_egl->egl_context, (gulong) external_gl_context, (gulong) external_gl_context, WinEGLErrorString ());
WinEGLErrorString ());
goto failure; goto failure;
} }

View file

@ -23,7 +23,8 @@
#include <gst/gst.h> #include <gst/gst.h>
#include "gstglapi.h" #include <EGL/egl.h>
#include "gstglwindow_win32.h" #include "gstglwindow_win32.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -62,7 +63,7 @@ struct _GstGLWindowWin32EGLClass {
GType gst_gl_window_win32_egl_get_type (void); GType gst_gl_window_win32_egl_get_type (void);
GstGLWindowWin32EGL * gst_gl_window_win32_egl_new (GstGLAPI gl_api, GstGLWindowWin32EGL * gst_gl_window_win32_egl_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context, GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -29,14 +29,11 @@
#include "gstglwindow_win32_wgl.h" #include "gstglwindow_win32_wgl.h"
#define GST_CAT_DEFAULT gst_gl_window_win32_wgl_debug #define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_win32_wgl_parent_class parent_class #define gst_gl_window_win32_wgl_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowWin32WGL, gst_gl_window_win32_wgl, G_DEFINE_TYPE (GstGLWindowWin32WGL, gst_gl_window_win32_wgl,
GST_GL_TYPE_WINDOW_WIN32, DEBUG_INIT); GST_GL_TYPE_WINDOW_WIN32);
static guintptr gst_gl_window_win32_wgl_get_gl_context (GstGLWindowWin32 * static guintptr gst_gl_window_win32_wgl_get_gl_context (GstGLWindowWin32 *
window_win32); window_win32);
@ -47,7 +44,8 @@ static gboolean gst_gl_window_win32_wgl_choose_format (GstGLWindowWin32 *
static gboolean gst_gl_window_win32_wgl_activate (GstGLWindowWin32 * static gboolean gst_gl_window_win32_wgl_activate (GstGLWindowWin32 *
window_win32, gboolean activate); window_win32, gboolean activate);
static gboolean gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * static gboolean gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 *
window_win32, GstGLAPI gl_api, guintptr external_gl_context); window_win32, GstGLAPI gl_api, guintptr external_gl_context,
GError ** error);
static void gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 * static void gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 *
window_win32); window_win32);
GstGLAPI gst_gl_window_win32_wgl_get_gl_api (GstGLWindow * window); GstGLAPI gst_gl_window_win32_wgl_get_gl_api (GstGLWindow * window);
@ -55,7 +53,7 @@ GstGLAPI gst_gl_window_win32_wgl_get_gl_api (GstGLWindow * window);
static void static void
gst_gl_window_win32_wgl_class_init (GstGLWindowWin32WGLClass * klass) gst_gl_window_win32_wgl_class_init (GstGLWindowWin32WGLClass * klass)
{ {
GstGLWindowClass *window_class; GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
GstGLWindowWin32Class *window_win32_class = (GstGLWindowWin32Class *) klass; GstGLWindowWin32Class *window_win32_class = (GstGLWindowWin32Class *) klass;
window_win32_class->get_gl_context = window_win32_class->get_gl_context =
@ -82,19 +80,20 @@ gst_gl_window_win32_wgl_init (GstGLWindowWin32WGL * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowWin32WGL * GstGLWindowWin32WGL *
gst_gl_window_win32_wgl_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_win32_wgl_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowWin32WGL *window = GstGLWindowWin32WGL *window =
g_object_new (GST_GL_TYPE_WINDOW_WIN32_WGL, NULL); g_object_new (GST_GL_TYPE_WINDOW_WIN32_WGL, NULL);
gst_gl_window_win32_open_device (GST_GL_WINDOW_WIN32 (window)); gst_gl_window_win32_open_device (GST_GL_WINDOW_WIN32 (window), error);
return window; return window;
} }
static gboolean static gboolean
gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * window_win32, gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * window_win32,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowWin32WGL *window_wgl; GstGLWindowWin32WGL *window_wgl;
@ -102,10 +101,11 @@ gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * window_win32,
window_wgl->wgl_context = wglCreateContext (window_win32->device); window_wgl->wgl_context = wglCreateContext (window_win32->device);
if (window_wgl->wgl_context) if (window_wgl->wgl_context)
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT "\n", GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
(guintptr) window_wgl->wgl_context); (guintptr) window_wgl->wgl_context);
else { else {
GST_DEBUG ("failed to create glcontext:%lud\n", GetLastError ()); g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
"failed to create glcontext:%lu", GetLastError ());
goto failure; goto failure;
} }
g_assert (window_wgl->wgl_context); g_assert (window_wgl->wgl_context);
@ -125,8 +125,8 @@ gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 * window_win32)
window_wgl = GST_GL_WINDOW_WIN32_WGL (window_win32); window_wgl = GST_GL_WINDOW_WIN32_WGL (window_win32);
if (window_wgl->wgl_context)
wglDeleteContext (window_wgl->wgl_context); wglDeleteContext (window_wgl->wgl_context);
window_wgl->wgl_context = 0; window_wgl->wgl_context = 0;
} }

View file

@ -21,7 +21,6 @@
#ifndef __GST_GL_WINDOW_WIN32_WGL_H__ #ifndef __GST_GL_WINDOW_WIN32_WGL_H__
#define __GST_GL_WINDOW_WIN32_WGL_H__ #define __GST_GL_WINDOW_WIN32_WGL_H__
#include "gstglapi.h"
#include "gstglwindow_win32.h" #include "gstglwindow_win32.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -57,7 +56,7 @@ struct _GstGLWindowWin32WGLClass {
GType gst_gl_window_win32_wgl_get_type (void); GType gst_gl_window_win32_wgl_get_type (void);
GstGLWindowWin32WGL * gst_gl_window_win32_wgl_new (GstGLAPI gl_api, GstGLWindowWin32WGL * gst_gl_window_win32_wgl_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context, GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -40,14 +40,10 @@
#define GST_GL_WINDOW_X11_GET_PRIVATE(o) \ #define GST_GL_WINDOW_X11_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11Private)) (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11Private))
#define GST_CAT_DEFAULT gst_gl_window_x11_debug #define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_x11_parent_class parent_class #define gst_gl_window_x11_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowX11, gst_gl_window_x11, GST_GL_TYPE_WINDOW, G_DEFINE_TYPE (GstGLWindowX11, gst_gl_window_x11, GST_GL_TYPE_WINDOW);
DEBUG_INIT);
enum enum
{ {
@ -213,7 +209,8 @@ gst_gl_window_x11_init (GstGLWindowX11 * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowX11 * GstGLWindowX11 *
gst_gl_window_x11_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_x11_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowX11 *window = NULL; GstGLWindowX11 *window = NULL;
const gchar *user_choice; const gchar *user_choice;
@ -229,35 +226,35 @@ gst_gl_window_x11_new (GstGLAPI gl_api, guintptr external_gl_context)
|| g_strstr_len (user_choice, 3, "glx") != NULL)) || g_strstr_len (user_choice, 3, "glx") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api,
external_gl_context)); external_gl_context, error));
if (!window && (!user_choice if (!window && (!user_choice
|| g_strstr_len (user_choice, 3, "egl") != NULL)) || g_strstr_len (user_choice, 3, "egl") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api,
external_gl_context)); external_gl_context, error));
} else { /* try EGL first for OpenGL|ES */ } else { /* try EGL first for OpenGL|ES */
if (!window && (!user_choice if (!window && (!user_choice
|| g_strstr_len (user_choice, 3, "egl") != NULL)) || g_strstr_len (user_choice, 3, "egl") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api,
external_gl_context)); external_gl_context, error));
if (!window && (!user_choice if (!window && (!user_choice
|| g_strstr_len (user_choice, 3, "glx") != NULL)) || g_strstr_len (user_choice, 3, "glx") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api,
external_gl_context)); external_gl_context, error));
} }
#endif /* HAVE_EGL */ #endif /* HAVE_EGL */
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "glx") != NULL)) if (!window && (!user_choice || g_strstr_len (user_choice, 3, "glx") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new (gl_api,
external_gl_context)); external_gl_context, error));
#endif /* HAVE_GLX */ #endif /* HAVE_GLX */
#ifdef HAVE_EGL #ifdef HAVE_EGL
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl") != NULL)) if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl") != NULL))
window = window =
GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api, GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new (gl_api,
external_gl_context)); external_gl_context, error));
#endif /* HAVE_EGL */ #endif /* HAVE_EGL */
if (!window) { if (!window) {
GST_WARNING ("Failed to create x11 window, user_choice:%s", GST_WARNING ("Failed to create x11 window, user_choice:%s",
@ -270,7 +267,7 @@ gst_gl_window_x11_new (GstGLAPI gl_api, guintptr external_gl_context)
gboolean gboolean
gst_gl_window_x11_open_device (GstGLWindowX11 * window_x11, gst_gl_window_x11_open_device (GstGLWindowX11 * window_x11,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11); GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
@ -288,7 +285,9 @@ gst_gl_window_x11_open_device (GstGLWindowX11 * window_x11,
window_x11->device = XOpenDisplay (window_x11->display_name); window_x11->device = XOpenDisplay (window_x11->display_name);
if (window_x11->device == NULL) { if (window_x11->device == NULL) {
GST_WARNING ("Failed to open X display"); g_set_error (error, GST_GL_WINDOW_ERROR,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"Failed to connect to X display server");
goto failure; goto failure;
} }
@ -320,20 +319,20 @@ gst_gl_window_x11_open_device (GstGLWindowX11 * window_x11,
window_x11->connection = ConnectionNumber (window_x11->device); window_x11->connection = ConnectionNumber (window_x11->device);
if (!window_class->choose_format (window_x11)) { if (!window_class->choose_format (window_x11, error)) {
GST_WARNING ("Failed to choose XVisual");
goto failure; goto failure;
} }
gst_gl_window_x11_create_window (window_x11); gst_gl_window_x11_create_window (window_x11);
if (!window_class->create_context (window_x11, gl_api, external_gl_context)) { if (!window_class->create_context (window_x11, gl_api, external_gl_context,
GST_WARNING ("Failed to create context"); error)) {
goto failure; goto failure;
} }
if (!window_class->activate (window_x11, TRUE)) { if (!window_class->activate (window_x11, TRUE)) {
GST_WARNING ("failed to make context current"); g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
"Failed to make context current");
goto failure; goto failure;
} }
@ -645,13 +644,13 @@ gst_gl_window_x11_run (GstGLWindow * window)
if (window_x11->running) { if (window_x11->running) {
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
GstGLWindowCB custom_cb = GstGLWindowCB custom_cb =
(GstGLWindowCB) (((event.xclient. (GstGLWindowCB) (((event.xclient.data.
data.l[0] & 0xffffffff) << 32) | (event.xclient. l[0] & 0xffffffff) << 32) | (event.xclient.data.
data.l[1] & 0xffffffff)); l[1] & 0xffffffff));
gpointer custom_data = gpointer custom_data =
(gpointer) (((event.xclient. (gpointer) (((event.xclient.data.
data.l[2] & 0xffffffff) << 32) | (event.xclient. l[2] & 0xffffffff) << 32) | (event.xclient.data.
data.l[3] & 0xffffffff)); l[3] & 0xffffffff));
#else #else
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0]; GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer custom_data = (gpointer) event.xclient.data.l[1]; gpointer custom_data = (gpointer) event.xclient.data.l[1];
@ -680,13 +679,13 @@ gst_gl_window_x11_run (GstGLWindow * window)
&& event.xclient.message_type == wm_quit_loop) { && event.xclient.message_type == wm_quit_loop) {
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
GstGLWindowCB destroy_cb = GstGLWindowCB destroy_cb =
(GstGLWindowCB) (((event.xclient. (GstGLWindowCB) (((event.xclient.data.
data.l[0] & 0xffffffff) << 32) | (event.xclient. l[0] & 0xffffffff) << 32) | (event.xclient.data.
data.l[1] & 0xffffffff)); l[1] & 0xffffffff));
gpointer destroy_data = gpointer destroy_data =
(gpointer) (((event.xclient. (gpointer) (((event.xclient.data.
data.l[2] & 0xffffffff) << 32) | (event.xclient. l[2] & 0xffffffff) << 32) | (event.xclient.data.
data.l[3] & 0xffffffff)); l[3] & 0xffffffff));
#else #else
GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0]; GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer destroy_data = (gpointer) event.xclient.data.l[1]; gpointer destroy_data = (gpointer) event.xclient.data.l[1];
@ -704,13 +703,13 @@ gst_gl_window_x11_run (GstGLWindow * window)
&pending_event)) { &pending_event)) {
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
GstGLWindowCB custom_cb = GstGLWindowCB custom_cb =
(GstGLWindowCB) (((event.xclient. (GstGLWindowCB) (((event.xclient.data.
data.l[0] & 0xffffffff) << 32) | (event.xclient. l[0] & 0xffffffff) << 32) | (event.xclient.data.
data.l[1] & 0xffffffff)); l[1] & 0xffffffff));
gpointer custom_data = gpointer custom_data =
(gpointer) (((event.xclient. (gpointer) (((event.xclient.data.
data.l[2] & 0xffffffff) << 32) | (event.xclient. l[2] & 0xffffffff) << 32) | (event.xclient.data.
data.l[3] & 0xffffffff)); l[3] & 0xffffffff));
#else #else
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0]; GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer custom_data = (gpointer) event.xclient.data.l[1]; gpointer custom_data = (gpointer) event.xclient.data.l[1];
@ -727,7 +726,7 @@ gst_gl_window_x11_run (GstGLWindow * window)
/* Finally we can destroy opengl ressources (texture/shaders/fbo) */ /* Finally we can destroy opengl ressources (texture/shaders/fbo) */
if (!destroy_cb || !destroy_data) if (!destroy_cb || !destroy_data)
GST_DEBUG ("destroy cb not correctly set"); GST_FIXME ("destroy cb not correctly set");
destroy_cb (destroy_data); destroy_cb (destroy_data);

View file

@ -81,9 +81,9 @@ struct _GstGLWindowX11Class {
/*< private >*/ /*< private >*/
GstGLWindowClass parent_class; GstGLWindowClass parent_class;
gboolean (*choose_format) (GstGLWindowX11 *window); gboolean (*choose_format) (GstGLWindowX11 *window, GError ** error);
gboolean (*create_context) (GstGLWindowX11 *window, GstGLAPI gl_api, gboolean (*create_context) (GstGLWindowX11 *window, GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context, GError ** error);
void (*swap_buffers) (GstGLWindowX11 *window); void (*swap_buffers) (GstGLWindowX11 *window);
gboolean (*activate) (GstGLWindowX11 *window, gboolean activate); gboolean (*activate) (GstGLWindowX11 *window, gboolean activate);
void (*destroy_context) (GstGLWindowX11 *window); void (*destroy_context) (GstGLWindowX11 *window);
@ -96,10 +96,12 @@ struct _GstGLWindowX11Class {
GType gst_gl_window_x11_get_type (void); GType gst_gl_window_x11_get_type (void);
GstGLWindowX11 * gst_gl_window_x11_new (GstGLAPI gl_api, GstGLWindowX11 * gst_gl_window_x11_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
gboolean gst_gl_window_x11_open_device (GstGLWindowX11 *window_x11, gboolean gst_gl_window_x11_open_device (GstGLWindowX11 *window_x11,
GstGLAPI gl_api, GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -29,14 +29,11 @@
const gchar *X11EGLErrorString (); const gchar *X11EGLErrorString ();
#define GST_CAT_DEFAULT gst_gl_window_x11_egl_debug #define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_x11_egl_parent_class parent_class #define gst_gl_window_x11_egl_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowX11EGL, gst_gl_window_x11_egl, G_DEFINE_TYPE (GstGLWindowX11EGL, gst_gl_window_x11_egl,
GST_GL_TYPE_WINDOW_X11, DEBUG_INIT); GST_GL_TYPE_WINDOW_X11);
static guintptr gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 * static guintptr gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 *
window_x11); window_x11);
@ -44,10 +41,10 @@ static void gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11, static gboolean gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11,
gboolean activate); gboolean activate);
static gboolean gst_gl_window_x11_egl_create_context (GstGLWindowX11 * static gboolean gst_gl_window_x11_egl_create_context (GstGLWindowX11 *
window_x11, GstGLAPI gl_api, guintptr external_gl_context); window_x11, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
static void gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11); static void gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * static gboolean gst_gl_window_x11_egl_choose_format (GstGLWindowX11 *
window_x11); window_x11, GError ** error);
GstGLAPI gst_gl_window_x11_egl_get_gl_api (GstGLWindow * window); GstGLAPI gst_gl_window_x11_egl_get_gl_api (GstGLWindow * window);
static void static void
@ -80,18 +77,20 @@ gst_gl_window_x11_egl_init (GstGLWindowX11EGL * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowX11EGL * GstGLWindowX11EGL *
gst_gl_window_x11_egl_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_x11_egl_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowX11EGL *window = g_object_new (GST_GL_TYPE_WINDOW_X11_EGL, NULL); GstGLWindowX11EGL *window = g_object_new (GST_GL_TYPE_WINDOW_X11_EGL, NULL);
gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), gl_api, gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), gl_api,
external_gl_context); external_gl_context, error);
return window; return window;
} }
static gboolean static gboolean
gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * window_x11) gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * window_x11,
GError ** error)
{ {
gint ret; gint ret;
@ -99,12 +98,18 @@ gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * window_x11)
ret = XMatchVisualInfo (window_x11->device, window_x11->screen_num, ret = XMatchVisualInfo (window_x11->device, window_x11->screen_num,
window_x11->depth, TrueColor, window_x11->visual_info); window_x11->depth, TrueColor, window_x11->visual_info);
return ret != 0; if (ret == 0) {
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
"Failed to match XVisualInfo");
return FALSE;
}
return TRUE;
} }
static gboolean static gboolean
gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11, gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowX11EGL *window_egl; GstGLWindowX11EGL *window_egl;
@ -131,19 +136,20 @@ gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11,
eglGetDisplay ((EGLNativeDisplayType) window_x11->device); eglGetDisplay ((EGLNativeDisplayType) window_x11->device);
if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion)) if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion))
g_debug ("egl initialized: %d.%d\n", majorVersion, minorVersion); GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion);
else { else {
g_debug ("failed to initialize egl %ld, %s\n", g_set_error (error, GST_GL_WINDOW_ERROR,
(gulong) window_egl->egl_display, X11EGLErrorString ()); GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
"Failed to initialize egl: %s", X11EGLErrorString ());
goto failure; goto failure;
} }
if (eglChooseConfig (window_egl->egl_display, config_attrib, &config, 1, if (eglChooseConfig (window_egl->egl_display, config_attrib, &config, 1,
&numConfigs)) &numConfigs))
g_debug ("config set: %ld, %ld\n", (gulong) config, (gulong) numConfigs); GST_INFO ("config set: %ld, %ld", (gulong) config, (gulong) numConfigs);
else { else {
g_debug ("failed to set config %ld, %s\n", (gulong) window_egl->egl_display, g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
X11EGLErrorString ()); "Failed to set window configuration: %s", X11EGLErrorString ());
goto failure; goto failure;
} }
@ -151,26 +157,24 @@ gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11,
eglCreateWindowSurface (window_egl->egl_display, config, eglCreateWindowSurface (window_egl->egl_display, config,
(EGLNativeWindowType) window_x11->internal_win_id, NULL); (EGLNativeWindowType) window_x11->internal_win_id, NULL);
if (window_egl->egl_surface != EGL_NO_SURFACE) if (window_egl->egl_surface != EGL_NO_SURFACE)
g_debug ("surface created: %ld\n", (gulong) window_egl->egl_surface); GST_INFO ("surface created");
else { else {
g_debug ("failed to create surface %ld, %ld, %ld, %s\n", g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
(gulong) window_egl->egl_display, (gulong) window_egl->egl_surface, "Failed to create window surface: %s", X11EGLErrorString ());
(gulong) window_egl->egl_display, X11EGLErrorString ());
goto failure; goto failure;
} }
g_debug ("about to create gl context\n"); GST_DEBUG ("about to create gl context\n");
window_egl->egl_context = window_egl->egl_context =
eglCreateContext (window_egl->egl_display, config, eglCreateContext (window_egl->egl_display, config,
(EGLContext) external_gl_context, context_attrib); (EGLContext) external_gl_context, context_attrib);
if (window_egl->egl_context != EGL_NO_CONTEXT) if (window_egl->egl_context != EGL_NO_CONTEXT)
g_debug ("gl context created: %ld\n", (gulong) window_egl->egl_context); GST_INFO ("gl context created: %ld", (gulong) window_egl->egl_context);
else { else {
g_debug ("failed to create glcontext %ld, %ld, %s\n", g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
(gulong) window_egl->egl_context, (gulong) window_egl->egl_display, "Failed to create a OpenGL context: %s", X11EGLErrorString ());
X11EGLErrorString ());
goto failure; goto failure;
} }

View file

@ -21,9 +21,10 @@
#ifndef __GST_GL_WINDOW_X11_EGL_H__ #ifndef __GST_GL_WINDOW_X11_EGL_H__
#define __GST_GL_WINDOW_X11_EGL_H__ #define __GST_GL_WINDOW_X11_EGL_H__
#include "gstglapi.h"
#include "gstglwindow_x11.h" #include "gstglwindow_x11.h"
#include <EGL/egl.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_GL_TYPE_WINDOW_X11_EGL (gst_gl_window_x11_egl_get_type()) #define GST_GL_TYPE_WINDOW_X11_EGL (gst_gl_window_x11_egl_get_type())
@ -58,7 +59,8 @@ struct _GstGLWindowX11EGLClass {
GType gst_gl_window_x11_egl_get_type (void); GType gst_gl_window_x11_egl_get_type (void);
GstGLWindowX11EGL * gst_gl_window_x11_egl_new (GstGLAPI gl_api, GstGLWindowX11EGL * gst_gl_window_x11_egl_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
G_END_DECLS G_END_DECLS

View file

@ -29,14 +29,11 @@
#include "gstglwindow_x11_glx.h" #include "gstglwindow_x11_glx.h"
#define GST_CAT_DEFAULT gst_gl_window_x11_glx_debug #define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_x11_glx_parent_class parent_class #define gst_gl_window_x11_glx_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowX11GLX, gst_gl_window_x11_glx, G_DEFINE_TYPE (GstGLWindowX11GLX, gst_gl_window_x11_glx,
GST_GL_TYPE_WINDOW_X11, DEBUG_INIT); GST_GL_TYPE_WINDOW_X11);
static guintptr gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 * static guintptr gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 *
window_x11); window_x11);
@ -44,10 +41,10 @@ static void gst_gl_window_x11_glx_swap_buffers (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11, static gboolean gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11,
gboolean activate); gboolean activate);
static gboolean gst_gl_window_x11_glx_create_context (GstGLWindowX11 * static gboolean gst_gl_window_x11_glx_create_context (GstGLWindowX11 *
window_x11, GstGLAPI gl_api, guintptr external_gl_context); window_x11, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
static void gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11); static void gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * static gboolean gst_gl_window_x11_glx_choose_format (GstGLWindowX11 *
window_x11); window_x11, GError ** error);
GstGLAPI gst_gl_window_x11_glx_get_gl_api (GstGLWindow * window); GstGLAPI gst_gl_window_x11_glx_get_gl_api (GstGLWindow * window);
static void static void
@ -80,19 +77,20 @@ gst_gl_window_x11_glx_init (GstGLWindowX11GLX * window)
/* Must be called in the gl thread */ /* Must be called in the gl thread */
GstGLWindowX11GLX * GstGLWindowX11GLX *
gst_gl_window_x11_glx_new (GstGLAPI gl_api, guintptr external_gl_context) gst_gl_window_x11_glx_new (GstGLAPI gl_api, guintptr external_gl_context,
GError ** error)
{ {
GstGLWindowX11GLX *window = g_object_new (GST_GL_TYPE_WINDOW_X11_GLX, NULL); GstGLWindowX11GLX *window = g_object_new (GST_GL_TYPE_WINDOW_X11_GLX, NULL);
gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), gl_api, gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), gl_api,
external_gl_context); external_gl_context, error);
return window; return window;
} }
static gboolean static gboolean
gst_gl_window_x11_glx_create_context (GstGLWindowX11 * window_x11, gst_gl_window_x11_glx_create_context (GstGLWindowX11 * window_x11,
GstGLAPI gl_api, guintptr external_gl_context) GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
{ {
GstGLWindowX11GLX *window_glx; GstGLWindowX11GLX *window_glx;
@ -103,7 +101,8 @@ gst_gl_window_x11_glx_create_context (GstGLWindowX11 * window_x11,
(GLXContext) external_gl_context, TRUE); (GLXContext) external_gl_context, TRUE);
if (!window_glx->glx_context) { if (!window_glx->glx_context) {
GST_WARNING ("failed to create opengl context (glXCreateContext failed)"); g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
"Failed to create opengl context (glXCreateContext failed)");
goto failure; goto failure;
} }
@ -128,7 +127,8 @@ gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11)
} }
static gboolean static gboolean
gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * window_x11) gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * window_x11,
GError ** error)
{ {
gint error_base; gint error_base;
gint event_base; gint event_base;
@ -142,7 +142,8 @@ gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * window_x11)
}; };
if (!glXQueryExtension (window_x11->device, &error_base, &event_base)) { if (!glXQueryExtension (window_x11->device, &error_base, &event_base)) {
GST_WARNING ("No GLX extension"); g_set_error (error, GST_GL_WINDOW_ERROR,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, "No GLX extension");
goto failure; goto failure;
} }
@ -150,7 +151,8 @@ gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * window_x11)
window_x11->screen_num, attrib); window_x11->screen_num, attrib);
if (!window_x11->visual_info) { if (!window_x11->visual_info) {
GST_WARNING ("glx visual is null (bad attributes)"); g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
"Bad attributes in glXChooseVisual");
goto failure; goto failure;
} }

View file

@ -21,9 +21,10 @@
#ifndef __GST_GL_WINDOW_X11_GLX_H__ #ifndef __GST_GL_WINDOW_X11_GLX_H__
#define __GST_GL_WINDOW_X11_GLX_H__ #define __GST_GL_WINDOW_X11_GLX_H__
#include "gstglapi.h"
#include "gstglwindow_x11.h" #include "gstglwindow_x11.h"
#include <GL/glx.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_GL_TYPE_WINDOW_X11_GLX (gst_gl_window_x11_glx_get_type()) #define GST_GL_TYPE_WINDOW_X11_GLX (gst_gl_window_x11_glx_get_type())
@ -56,7 +57,8 @@ struct _GstGLWindowX11GLXClass {
GType gst_gl_window_x11_glx_get_type (void); GType gst_gl_window_x11_glx_get_type (void);
GstGLWindowX11GLX * gst_gl_window_x11_glx_new (GstGLAPI gl_api, GstGLWindowX11GLX * gst_gl_window_x11_glx_new (GstGLAPI gl_api,
guintptr external_gl_context); guintptr external_gl_context,
GError ** error);
G_END_DECLS G_END_DECLS