gst_gl_window_finalize (GObject * object)
{
GstGLWindow *window = GST_GL_WINDOW (object);
+ GstGLWindowClass *window_class = GST_GL_WINDOW_GET_CLASS (window);
if (window) {
gst_gl_window_set_resize_callback (window, NULL, NULL);
window->priv->gl_thread = NULL;
}
+ if (window_class->close) {
+ window_class->close (window);
+ }
+
g_mutex_clear (&window->priv->render_lock);
g_cond_clear (&window->priv->cond_destroy_context);
return ret;
}
-
-gboolean
-_priv_gst_gl_window_create_context (GstGLWindow * window, GstGLAPI gl_api,
- guintptr external_gl_context, GError ** error)
-{
- gboolean ret;
- GstGLWindowClass *window_class;
-
- g_return_val_if_fail (GST_GL_IS_WINDOW (window), FALSE);
- window_class = GST_GL_WINDOW_GET_CLASS (window);
- g_return_val_if_fail (window_class->create_context != NULL, FALSE);
-
- GST_GL_WINDOW_LOCK (window);
-
- ret =
- window_class->create_context (window, gl_api, external_gl_context, error);
-
- GST_GL_WINDOW_UNLOCK (window);
-
- return ret;
-}
-
gpointer
gst_gl_window_default_get_proc_address (GstGLWindow * window,
const gchar * name)
g_mutex_lock (&window->priv->render_lock);
+ if (window_class->open) {
+ if (!(alive = window_class->open (window, error)))
+ goto out;
+ }
+
if (!window->priv->context_created) {
window->priv->external_gl_context = external_gl_context;
window->priv->error = error;
g_mutex_unlock (&window->priv->render_lock);
+out:
return alive;
}
}
static gboolean
-_create_context_gles2 (GstGLWindow * window, gint * gl_major, gint * gl_minor)
+_create_context_gles2 (GstGLWindow * window, gint * gl_major, gint * gl_minor,
+ GError ** error)
{
GstGLDisplay *display;
const GstGLFuncs *gl;
GLenum gl_err = GL_NO_ERROR;
- GError **error;
display = window->priv->display;
gl = display->gl_vtable;
- error = window->priv->error;
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
}
gboolean
-_create_context_opengl (GstGLWindow * window, gint * gl_major, gint * gl_minor)
+_create_context_opengl (GstGLWindow * window, gint * gl_major, gint * gl_minor,
+ GError ** error)
{
GstGLDisplay *display;
const GstGLFuncs *gl;
guint maj, min;
GLenum gl_err = GL_NO_ERROR;
GString *opengl_version = NULL;
- GError **error;
display = window->priv->display;
gl = display->gl_vtable;
- error = window->priv->error;
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
/* gl api specific code */
if (!ret && USING_OPENGL (display))
- ret = _create_context_opengl (window, &gl_major, NULL);
+ ret = _create_context_opengl (window, &gl_major, NULL, error);
if (!ret && USING_GLES2 (display))
- ret = _create_context_gles2 (window, &gl_major, NULL);
+ ret = _create_context_gles2 (window, &gl_major, NULL, error);
- if (!ret || !gl_major) {
- g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
- "GL api specific initialization failed");
+ if (!ret)
goto failure;
- }
g_cond_signal (&window->priv->cond_create_context);
GstGLWindowCB callback, gpointer data);
gboolean gst_gl_window_x11_create_context (GstGLWindow * window,
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
+gboolean gst_gl_window_x11_open (GstGLWindow * window, GError ** error);
+void gst_gl_window_x11_close (GstGLWindow * window);
static gboolean gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11);
-/* Must be called in the gl thread */
-static void
-gst_gl_window_x11_finalize (GObject * object)
-{
- GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (object);
- GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
- XEvent event;
- Bool ret = TRUE;
-
- GST_GL_WINDOW_LOCK (window_x11);
-
- window_x11->parent_win = 0;
- if (window_x11->device) {
- if (window_x11->internal_win_id)
- XUnmapWindow (window_x11->device, window_x11->internal_win_id);
-
- ret = window_class->activate (window_x11, FALSE);
- if (!ret)
- GST_DEBUG ("failed to release opengl context");
- window_class->destroy_context (window_x11);
-
- XFree (window_x11->visual_info);
-
- if (window_x11->internal_win_id) {
- XReparentWindow (window_x11->device, window_x11->internal_win_id,
- window_x11->root, 0, 0);
- XDestroyWindow (window_x11->device, window_x11->internal_win_id);
- }
- XSync (window_x11->device, FALSE);
-
- while (XPending (window_x11->device))
- XNextEvent (window_x11->device, &event);
-
- XSetCloseDownMode (window_x11->device, DestroyAll);
-
- /*XAddToSaveSet (display, w)
- Display *display;
- Window w; */
-
- //FIXME: it seems it causes destroy all created windows, even by other display connection:
- //This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink
- //When the first window is closed and so its display is closed by the following line, then the other Window managed by the
- //other glimagesink, is not useable and so each opengl call causes a segmentation fault.
- //Maybe the solution is to use: XAddToSaveSet
- //The following line is commented to avoid the disagreement explained before.
- //XCloseDisplay (window_x11->device);
-
- GST_DEBUG ("display receiver closed");
- XCloseDisplay (window_x11->disp_send);
- GST_DEBUG ("display sender closed");
- }
-
- g_cond_clear (&window_x11->cond_send_message);
-
- GST_GL_WINDOW_UNLOCK (window_x11);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
static void
gst_gl_window_x11_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
g_type_class_add_private (klass, sizeof (GstGLWindowX11Private));
- obj_class->finalize = gst_gl_window_x11_finalize;
obj_class->set_property = gst_gl_window_x11_set_property;
obj_class->get_property = gst_gl_window_x11_get_property;
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_x11_quit);
window_class->send_message =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_send_message);
+ window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_x11_open);
+ window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_x11_close);
}
static void
}
gboolean
-gst_gl_window_x11_create_context (GstGLWindow * window,
- GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
+gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
{
GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
- GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
-
- setlocale (LC_NUMERIC, "C");
-
- gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), TRUE);
-
- window_x11->running = TRUE;
- window_x11->visible = FALSE;
- window_x11->parent_win = 0;
- window_x11->allow_extra_expose_events = TRUE;
window_x11->device = XOpenDisplay (window_x11->display_name);
if (window_x11->device == NULL) {
GST_LOG ("gl display sender: %ld", (gulong) window_x11->disp_send);
+ return TRUE;
+
+failure:
+ return FALSE;
+}
+
+gboolean
+gst_gl_window_x11_create_context (GstGLWindow * window,
+ GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
+{
+ GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
+ GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
+
+ setlocale (LC_NUMERIC, "C");
+
+ gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), TRUE);
+
+ window_x11->running = TRUE;
+ window_x11->visible = FALSE;
+ window_x11->parent_win = 0;
+ window_x11->allow_extra_expose_events = TRUE;
+
+ g_assert (window_x11->device);
+
window_x11->screen = DefaultScreenOfDisplay (window_x11->device);
window_x11->screen_num = DefaultScreen (window_x11->device);
window_x11->visual =
return TRUE;
}
+void
+gst_gl_window_x11_close (GstGLWindow * window)
+{
+ GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
+ GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
+ XEvent event;
+ Bool ret = TRUE;
+
+ GST_GL_WINDOW_LOCK (window_x11);
+
+ window_x11->parent_win = 0;
+ if (window_x11->device) {
+ if (window_x11->internal_win_id)
+ XUnmapWindow (window_x11->device, window_x11->internal_win_id);
+
+ ret = window_class->activate (window_x11, FALSE);
+ if (!ret)
+ GST_DEBUG ("failed to release opengl context");
+ window_class->destroy_context (window_x11);
+
+ XFree (window_x11->visual_info);
+
+ if (window_x11->internal_win_id) {
+ XReparentWindow (window_x11->device, window_x11->internal_win_id,
+ window_x11->root, 0, 0);
+ XDestroyWindow (window_x11->device, window_x11->internal_win_id);
+ }
+ XSync (window_x11->device, FALSE);
+
+ while (XPending (window_x11->device))
+ XNextEvent (window_x11->device, &event);
+
+ XSetCloseDownMode (window_x11->device, DestroyAll);
+
+ /*XAddToSaveSet (display, w)
+ Display *display;
+ Window w; */
+
+ //FIXME: it seems it causes destroy all created windows, even by other display connection:
+ //This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink
+ //When the first window is closed and so its display is closed by the following line, then the other Window managed by the
+ //other glimagesink, is not useable and so each opengl call causes a segmentation fault.
+ //Maybe the solution is to use: XAddToSaveSet
+ //The following line is commented to avoid the disagreement explained before.
+ //XCloseDisplay (window_x11->device);
+
+ GST_DEBUG ("display receiver closed");
+ XCloseDisplay (window_x11->disp_send);
+ GST_DEBUG ("display sender closed");
+ }
+
+ g_cond_clear (&window_x11->cond_send_message);
+
+ GST_GL_WINDOW_UNLOCK (window_x11);
+}
+
guintptr
gst_gl_window_x11_get_gl_context (GstGLWindow * window)
{
if (window_x11->running) {
#if SIZEOF_VOID_P == 8
GstGLWindowCB custom_cb =
- (GstGLWindowCB) (((event.xclient.
- data.l[0] & 0xffffffff) << 32) | (event.xclient.
- data.l[1] & 0xffffffff));
+ (GstGLWindowCB) (((event.xclient.data.
+ l[0] & 0xffffffff) << 32) | (event.xclient.data.
+ l[1] & 0xffffffff));
gpointer custom_data =
- (gpointer) (((event.xclient.
- data.l[2] & 0xffffffff) << 32) | (event.xclient.
- data.l[3] & 0xffffffff));
+ (gpointer) (((event.xclient.data.
+ l[2] & 0xffffffff) << 32) | (event.xclient.data.
+ l[3] & 0xffffffff));
#else
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer custom_data = (gpointer) event.xclient.data.l[1];
&& event.xclient.message_type == wm_quit_loop) {
#if SIZEOF_VOID_P == 8
GstGLWindowCB destroy_cb =
- (GstGLWindowCB) (((event.xclient.
- data.l[0] & 0xffffffff) << 32) | (event.xclient.
- data.l[1] & 0xffffffff));
+ (GstGLWindowCB) (((event.xclient.data.
+ l[0] & 0xffffffff) << 32) | (event.xclient.data.
+ l[1] & 0xffffffff));
gpointer destroy_data =
- (gpointer) (((event.xclient.
- data.l[2] & 0xffffffff) << 32) | (event.xclient.
- data.l[3] & 0xffffffff));
+ (gpointer) (((event.xclient.data.
+ l[2] & 0xffffffff) << 32) | (event.xclient.data.
+ l[3] & 0xffffffff));
#else
GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer destroy_data = (gpointer) event.xclient.data.l[1];
&pending_event)) {
#if SIZEOF_VOID_P == 8
GstGLWindowCB custom_cb =
- (GstGLWindowCB) (((event.xclient.
- data.l[0] & 0xffffffff) << 32) | (event.xclient.
- data.l[1] & 0xffffffff));
+ (GstGLWindowCB) (((event.xclient.data.
+ l[0] & 0xffffffff) << 32) | (event.xclient.data.
+ l[1] & 0xffffffff));
gpointer custom_data =
- (gpointer) (((event.xclient.
- data.l[2] & 0xffffffff) << 32) | (event.xclient.
- data.l[3] & 0xffffffff));
+ (gpointer) (((event.xclient.data.
+ l[2] & 0xffffffff) << 32) | (event.xclient.data.
+ l[3] & 0xffffffff));
#else
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
gpointer custom_data = (gpointer) event.xclient.data.l[1];