[281/906] Make cube example work on x11. Finish TODO task 9.

This commit is contained in:
Julien Isorce 2008-11-23 16:04:27 +01:00 committed by Matthew Waters
parent c8c7f8733b
commit 1fbc72393c
4 changed files with 84 additions and 24 deletions

View file

@ -1363,8 +1363,8 @@ void gst_gl_display_on_draw(GstGLDisplay* display)
display->clientDrawCallback (display->redisplay_texture, display->clientDrawCallback (display->redisplay_texture,
display->redisplay_texture_width, display->redisplay_texture_height); display->redisplay_texture_width, display->redisplay_texture_height);
if (doRedisplay) if (doRedisplay && display->gl_window)
gst_gl_window_draw (display->gl_window); gst_gl_window_draw_unlocked (display->gl_window);
} }
//default opengl scene //default opengl scene
else else

View file

@ -71,6 +71,7 @@ void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callbac
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data); void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data); void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_draw_unlocked (GstGLWindow *window);
void gst_gl_window_draw (GstGLWindow *window); void gst_gl_window_draw (GstGLWindow *window);
void gst_gl_window_run_loop (GstGLWindow *window); void gst_gl_window_run_loop (GstGLWindow *window);
void gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer data); void gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer data);

View file

@ -262,6 +262,12 @@ gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, g
priv->close_data = data; priv->close_data = data;
} }
void
gst_gl_window_draw_unlocked (GstGLWindow *window)
{
gst_gl_window_draw (window);
}
/* Thread safe */ /* Thread safe */
void void
gst_gl_window_draw (GstGLWindow *window) gst_gl_window_draw (GstGLWindow *window)

View file

@ -41,6 +41,7 @@ struct _GstGLWindowPrivate
GCond *cond_send_message; GCond *cond_send_message;
gboolean running; gboolean running;
gboolean visible; gboolean visible;
gboolean allow_extra_expose_events;
gchar *display_name; gchar *display_name;
Display *device; Display *device;
@ -116,14 +117,20 @@ gst_gl_window_finalize (GObject * object)
XSetCloseDownMode (priv->device, DestroyAll); XSetCloseDownMode (priv->device, DestroyAll);
XCloseDisplay (priv->device);
XCloseDisplay (priv->disp_send);
/*XAddToSaveSet (display, w) /*XAddToSaveSet (display, w)
Display *display; Display *display;
Window w;*/ 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 (priv->device);
XCloseDisplay (priv->disp_send);
g_debug ("display closed\n"); g_debug ("display closed\n");
if (priv->cond_send_message) if (priv->cond_send_message)
@ -269,6 +276,7 @@ gst_gl_window_new (gint width, gint height)
priv->running = TRUE; priv->running = TRUE;
priv->visible = FALSE; priv->visible = FALSE;
priv->parent = 0; priv->parent = 0;
priv->allow_extra_expose_events = TRUE;
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
@ -472,6 +480,33 @@ gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, g
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);
} }
void
gst_gl_window_draw_unlocked (GstGLWindow *window)
{
GstGLWindowPrivate *priv = window->priv;
if (priv->running && priv->allow_extra_expose_events)
{
XEvent event;
XWindowAttributes attr;
XGetWindowAttributes (priv->device, priv->internal_win_id, &attr);
event.xexpose.type = Expose;
event.xexpose.send_event = TRUE;
event.xexpose.display = priv->device;
event.xexpose.window = priv->internal_win_id;
event.xexpose.x = attr.x;
event.xexpose.y = attr.y;
event.xexpose.width = attr.width;
event.xexpose.height = attr.height;
event.xexpose.count = 0;
XSendEvent (priv->device, priv->internal_win_id, FALSE, ExposureMask, &event);
XSync (priv->disp_send, FALSE);
}
}
/* Thread safe */ /* Thread safe */
void void
gst_gl_window_draw (GstGLWindow *window) gst_gl_window_draw (GstGLWindow *window)
@ -535,7 +570,6 @@ gst_gl_window_run_loop (GstGLWindow *window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
g_debug ("begin loop\n"); g_debug ("begin loop\n");
g_mutex_lock (priv->x_lock); g_mutex_lock (priv->x_lock);
@ -543,6 +577,7 @@ gst_gl_window_run_loop (GstGLWindow *window)
while (priv->running) while (priv->running)
{ {
XEvent event; XEvent event;
XEvent pending_event;
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);
@ -609,7 +644,6 @@ gst_gl_window_run_loop (GstGLWindow *window)
else if (wm_quit_loop != None && event.xclient.message_type == wm_quit_loop) else if (wm_quit_loop != None && event.xclient.message_type == wm_quit_loop)
{ {
XEvent pending_event;
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];
@ -702,6 +736,25 @@ gst_gl_window_run_loop (GstGLWindow *window)
}// switch }// switch
// use in cube example
if (XPending (priv->device) > 10)
{
XEvent extra_expose_event;
priv->allow_extra_expose_events = FALSE;
while (XCheckTypedWindowEvent (priv->device, priv->internal_win_id, Expose, &extra_expose_event))
{
if (priv->draw_cb)
{
if (glXGetCurrentContext () != priv->gl_context)
g_warning ("current gl context has changed\n");
priv->draw_cb (priv->draw_data);
glFlush();
glXSwapBuffers (priv->device, priv->internal_win_id);
}
}
priv->allow_extra_expose_events = TRUE;
}
}// while running }// while running
g_mutex_unlock (priv->x_lock); g_mutex_unlock (priv->x_lock);