mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 10:41:04 +00:00
[281/906] Make cube example work on x11. Finish TODO task 9.
This commit is contained in:
parent
c8c7f8733b
commit
1fbc72393c
4 changed files with 84 additions and 24 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* GStreamer
|
* GStreamer
|
||||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||||
*
|
*
|
||||||
|
@ -190,7 +190,7 @@ gst_gl_window_new (gint width, gint height)
|
||||||
|
|
||||||
g_debug ("gl window created: %d\n", priv->internal_win_id);
|
g_debug ("gl window created: %d\n", priv->internal_win_id);
|
||||||
|
|
||||||
//device is set in the window_proc
|
//device is set in the window_proc
|
||||||
g_assert (priv->device);
|
g_assert (priv->device);
|
||||||
|
|
||||||
ShowCursor (TRUE);
|
ShowCursor (TRUE);
|
||||||
|
@ -204,7 +204,7 @@ gst_gl_window_error_quark (void)
|
||||||
return g_quark_from_static_string ("gst-gl-window-error");
|
return g_quark_from_static_string ("gst-gl-window-error");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
|
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
|
||||||
{
|
{
|
||||||
GstGLWindowPrivate *priv = window->priv;
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
|
@ -215,9 +215,9 @@ gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
|
||||||
SetProp ((HWND)id, "gl_window_id", priv->internal_win_id);
|
SetProp ((HWND)id, "gl_window_id", priv->internal_win_id);
|
||||||
SetProp ((HWND)id, "gl_window_parent_proc", (WNDPROC) window_parent_proc);
|
SetProp ((HWND)id, "gl_window_parent_proc", (WNDPROC) window_parent_proc);
|
||||||
SetWindowLongPtr ((HWND)id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc);
|
SetWindowLongPtr ((HWND)id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc);
|
||||||
|
|
||||||
SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE);
|
SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE);
|
||||||
SetParent (priv->internal_win_id, (HWND)id);
|
SetParent (priv->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);
|
||||||
|
@ -226,7 +226,7 @@ gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
|
||||||
MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, rect.bottom, FALSE);
|
MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, rect.bottom, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_window_set_external_gl_context (GstGLWindow *window, guint64 context)
|
gst_gl_window_set_external_gl_context (GstGLWindow *window, guint64 context)
|
||||||
{
|
{
|
||||||
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
|
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
|
||||||
|
@ -237,7 +237,7 @@ void
|
||||||
gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data)
|
gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data)
|
||||||
{
|
{
|
||||||
GstGLWindowPrivate *priv = window->priv;
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
|
|
||||||
priv->draw_cb = callback;
|
priv->draw_cb = callback;
|
||||||
priv->draw_data = data;
|
priv->draw_data = data;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -289,7 +295,7 @@ gst_gl_window_run_loop (GstGLWindow *window)
|
||||||
g_debug ("begin loop\n");
|
g_debug ("begin loop\n");
|
||||||
|
|
||||||
while (running && (bRet = GetMessage (&msg, NULL, 0, 0)) != 0)
|
while (running && (bRet = GetMessage (&msg, NULL, 0, 0)) != 0)
|
||||||
{
|
{
|
||||||
if (bRet == -1)
|
if (bRet == -1)
|
||||||
{
|
{
|
||||||
g_error ("Failed to get message %x\r\n", GetLastError());
|
g_error ("Failed to get message %x\r\n", GetLastError());
|
||||||
|
@ -297,8 +303,8 @@ gst_gl_window_run_loop (GstGLWindow *window)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TranslateMessage (&msg);
|
TranslateMessage (&msg);
|
||||||
DispatchMessage (&msg);
|
DispatchMessage (&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +376,7 @@ gst_gl_window_set_pixel_format (GstGLWindow *window)
|
||||||
pfd.cColorBits = (BYTE) GetDeviceCaps (priv->device, BITSPIXEL);
|
pfd.cColorBits = (BYTE) GetDeviceCaps (priv->device, BITSPIXEL);
|
||||||
|
|
||||||
pixelformat = ChoosePixelFormat (priv->device, &pfd );
|
pixelformat = ChoosePixelFormat (priv->device, &pfd );
|
||||||
|
|
||||||
g_assert (pixelformat);
|
g_assert (pixelformat);
|
||||||
|
|
||||||
res = SetPixelFormat (priv->device, pixelformat, &pfd);
|
res = SetPixelFormat (priv->device, pixelformat, &pfd);
|
||||||
|
@ -432,7 +438,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
if (priv->draw_cb)
|
if (priv->draw_cb)
|
||||||
{
|
{
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
|
@ -447,7 +453,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
ShowWindowAsync (priv->internal_win_id, SW_HIDE);
|
ShowWindowAsync (priv->internal_win_id, SW_HIDE);
|
||||||
|
|
||||||
if (priv->close_cb)
|
if (priv->close_cb)
|
||||||
priv->close_cb (priv->close_data);
|
priv->close_cb (priv->close_data);
|
||||||
|
|
||||||
|
@ -473,7 +479,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||||
if (parent_id)
|
if (parent_id)
|
||||||
{
|
{
|
||||||
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
|
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
|
||||||
|
|
||||||
g_assert (parent_proc);
|
g_assert (parent_proc);
|
||||||
|
|
||||||
SetWindowLongPtr (parent_id, GWL_WNDPROC, (LONG) (guint64) parent_proc);
|
SetWindowLongPtr (parent_id, GWL_WNDPROC, (LONG) (guint64) parent_proc);
|
||||||
|
@ -502,7 +508,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||||
g_debug ("failed to destroy window %d, %x\r\n", hWnd, GetLastError());
|
g_debug ("failed to destroy window %d, %x\r\n", hWnd, GetLastError());
|
||||||
g_debug ("AFTER\n");
|
g_debug ("AFTER\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
PostQuitMessage (0);
|
PostQuitMessage (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +547,7 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||||
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
WNDPROC window_parent_proc = GetProp (hWnd, "gl_window_parent_proc");
|
WNDPROC window_parent_proc = GetProp (hWnd, "gl_window_parent_proc");
|
||||||
|
|
||||||
if (uMsg == WM_SIZE)
|
if (uMsg == WM_SIZE)
|
||||||
{
|
{
|
||||||
HWND gl_window_id = GetProp (hWnd, "gl_window_id");
|
HWND gl_window_id = GetProp (hWnd, "gl_window_id");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue