[252/906] avoid a dead lock on window closure

This commit is contained in:
Julien Isorce 2008-10-25 16:18:23 +02:00 committed by Tim-Philipp Müller
parent fc9479d289
commit f9756b85d2
4 changed files with 91 additions and 55 deletions

View File

@ -346,9 +346,9 @@ gst_gl_display_finalize (GObject* object)
//leave gl window loop //leave gl window loop
gst_gl_display_lock (display); gst_gl_display_lock (display);
GST_DEBUG ("send quit gl window loop"); GST_INFO ("send quit gl window loop");
gst_gl_window_quit_loop (display->gl_window); gst_gl_window_quit_loop (display->gl_window);
GST_DEBUG ("quit sent to gl window loop"); GST_INFO ("quit sent to gl window loop");
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
if (display->gl_thread) if (display->gl_thread)
@ -453,7 +453,9 @@ gst_gl_display_thread_create_context (GstGLDisplay *display)
gst_gl_window_run_loop (display->gl_window); gst_gl_window_run_loop (display->gl_window);
GST_DEBUG ("loop exited\n"); GST_INFO ("loop exited\n");
display->isAlive = FALSE;
gst_gl_display_thread_destroy_context (display); gst_gl_display_thread_destroy_context (display);
@ -870,7 +872,7 @@ gst_gl_display_thread_init_download (GstGLDisplay *display)
if (GLEW_EXT_framebuffer_object) if (GLEW_EXT_framebuffer_object)
{ {
GST_DEBUG ("Context, EXT_framebuffer_object supported: yes"); GST_INFO ("Context, EXT_framebuffer_object supported: yes");
//-- init output frame buffer object (GL -> video) //-- init output frame buffer object (GL -> video)
@ -1054,7 +1056,7 @@ gst_gl_display_thread_init_download (GstGLDisplay *display)
else else
{ {
//turn off the pipeline because colorspace conversion is not possible //turn off the pipeline because colorspace conversion is not possible
GST_DEBUG ("Context, ARB_fragment_shader supported: no"); GST_WARNING ("Context, ARB_fragment_shader supported: no");
display->isAlive = FALSE; display->isAlive = FALSE;
} }
} }
@ -1325,11 +1327,12 @@ gst_gl_display_on_resize (GstGLDisplay* display, gint width, gint height)
void gst_gl_display_on_draw(GstGLDisplay* display) void gst_gl_display_on_draw(GstGLDisplay* display)
{ {
//check if video format has been setup //check if tecture is ready for being drawn
if (!display->redisplay_texture) if (!display->redisplay_texture)
return; return;
//opengl scene //opengl scene
GST_INFO ("on draw");
//make sure that the environnement is clean //make sure that the environnement is clean
if (display->upload_colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL) if (display->upload_colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL)
@ -1378,9 +1381,7 @@ void gst_gl_display_on_draw(GstGLDisplay* display)
void gst_gl_display_on_close (GstGLDisplay* display) void gst_gl_display_on_close (GstGLDisplay* display)
{ {
GST_INFO ("on close"); GST_INFO ("on close");
gst_gl_display_lock (display);
display->isAlive = FALSE; display->isAlive = FALSE;
gst_gl_display_unlock (display);
} }

View File

@ -140,6 +140,12 @@ gst_gl_shader_log_handler (const gchar *domain, GLogLevelFlags flags,
} }
} }
static void
gst_gl_shader_base_init (gpointer g_class)
{
}
static void static void
gst_gl_shader_class_init (GstGLShaderClass * klass) gst_gl_shader_class_init (GstGLShaderClass * klass)
{ {

View File

@ -53,7 +53,6 @@ struct _GstGLWindow {
struct _GstGLWindowClass { struct _GstGLWindowClass {
/*< private >*/ /*< private >*/
GObjectClass parent_class; GObjectClass parent_class;
guint64 instance;
}; };
/* methods */ /* methods */

View File

@ -56,6 +56,7 @@ struct _GstGLWindowPrivate
gpointer resize_data; gpointer resize_data;
GstGLWindowCB close_cb; GstGLWindowCB close_cb;
gpointer close_data; gpointer close_data;
gboolean is_closed;
}; };
G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT); G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
@ -84,34 +85,19 @@ gst_gl_window_log_handler (const gchar *domain, GLogLevelFlags flags,
} }
} }
static void
gst_gl_window_base_init (gpointer g_class)
{
}
static void static void
gst_gl_window_class_init (GstGLWindowClass * klass) gst_gl_window_class_init (GstGLWindowClass * klass)
{ {
WNDCLASS wc;
ATOM atom = 0;
GObjectClass *obj_class = G_OBJECT_CLASS (klass); GObjectClass *obj_class = G_OBJECT_CLASS (klass);
klass->instance = (guint64) GetModuleHandle (NULL);
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate)); g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
obj_class->finalize = gst_gl_window_finalize; obj_class->finalize = gst_gl_window_finalize;
atom = GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc);
ZeroMemory (&wc, sizeof(WNDCLASS));
wc.lpfnWndProc = window_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE) klass->instance;
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GSTGL";
atom = RegisterClass (&wc);
} }
static void static void
@ -134,8 +120,36 @@ gst_gl_window_new (gint width, gint height)
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window); GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window);
WNDCLASS wc;
ATOM atom = 0;
HINSTANCE hinstance = GetModuleHandle (NULL);
static gint x = 0; static gint x = 0;
static gint y = 0; static gint y = 0;
atom = GetClassInfo (hinstance, "GSTGL", &wc);
if (atom == 0)
{
ZeroMemory (&wc, sizeof(WNDCLASS));
wc.lpfnWndProc = window_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GSTGL";
atom = RegisterClass (&wc);
if (atom == 0)
g_error ("Failed to register window class %x\r\n", GetLastError());
}
x += 20; x += 20;
y += 20; y += 20;
@ -151,6 +165,7 @@ gst_gl_window_new (gint width, gint height)
priv->resize_data = NULL; priv->resize_data = NULL;
priv->close_cb = NULL; priv->close_cb = NULL;
priv->close_data = NULL; priv->close_data = NULL;
priv->is_closed = FALSE;
width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); width += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION); height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
@ -163,11 +178,15 @@ gst_gl_window_new (gint width, gint height)
x, y, width, height, x, y, width, height,
(HWND) NULL, (HWND) NULL,
(HMENU) NULL, (HMENU) NULL,
(HINSTANCE) klass->instance, hinstance,
window window
); );
g_assert (priv->internal_win_id); if (!priv->internal_win_id)
{
g_debug ("failed to create gl window: %d\n", priv->internal_win_id);
return NULL;
}
g_debug ("gl window created: %d\n", priv->internal_win_id); g_debug ("gl window created: %d\n", priv->internal_win_id);
@ -177,13 +196,7 @@ gst_gl_window_new (gint width, gint height)
UpdateWindow (priv->internal_win_id); UpdateWindow (priv->internal_win_id);
ShowCursor (TRUE); ShowCursor (TRUE);
if (wglMakeCurrent (priv->device, priv->gl_context))
return window; return window;
else
{
g_debug ("Failed to make opengl context current");
return NULL;
}
} }
GQuark GQuark
@ -284,6 +297,8 @@ gst_gl_window_visible (GstGLWindow *window, gboolean visible)
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
BOOL ret = FALSE; BOOL ret = FALSE;
g_debug ("set visible %d\n", priv->internal_win_id);
if (visible) if (visible)
ret = ShowWindow (priv->internal_win_id, SW_SHOW); ret = ShowWindow (priv->internal_win_id, SW_SHOW);
else else
@ -298,7 +313,7 @@ gst_gl_window_draw (GstGLWindow *window)
if (!priv->has_external_window_id) if (!priv->has_external_window_id)
RedrawWindow (priv->internal_win_id, NULL, NULL, RedrawWindow (priv->internal_win_id, NULL, NULL,
RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE /*| RDW_UPDATENOW*/); RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE);
else else
{ {
PAINTSTRUCT ps; PAINTSTRUCT ps;
@ -365,7 +380,7 @@ gst_gl_window_run_loop (GstGLWindow *window)
{ {
if (bRet == -1) if (bRet == -1)
{ {
g_debug ("error in gst_gl_window_run_loop\n"); g_error ("Failed to get message %x\r\n", GetLastError());
running = FALSE; running = FALSE;
} }
else else
@ -431,7 +446,7 @@ gst_gl_window_set_pixel_format (GstGLWindow *window)
pfd.cAccumGreenBits = 0; pfd.cAccumGreenBits = 0;
pfd.cAccumBlueBits = 0; pfd.cAccumBlueBits = 0;
pfd.cAccumAlphaBits = 0; pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 24; pfd.cDepthBits = 32;
pfd.cStencilBits = 8; pfd.cStencilBits = 8;
pfd.cAuxBuffers = 0; pfd.cAuxBuffers = 0;
pfd.iLayerType = PFD_MAIN_PLANE; pfd.iLayerType = PFD_MAIN_PLANE;
@ -459,8 +474,6 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
g_debug ("WM_CREATE\n"); g_debug ("WM_CREATE\n");
SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG)(guint64)(gpointer) window);
g_assert (window); g_assert (window);
{ {
@ -471,11 +484,15 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
if (priv->gl_context) if (priv->gl_context)
g_debug ("gl context created: %d\n", priv->gl_context); g_debug ("gl context created: %d\n", priv->gl_context);
else else
g_debug ("failed to create glcontext %d\n", hWnd); g_debug ("failed to create glcontext %d, %x\r\n", hWnd, GetLastError());
g_assert (priv->gl_context); g_assert (priv->gl_context);
ReleaseDC (hWnd, priv->device); ReleaseDC (hWnd, priv->device);
if (!wglMakeCurrent (priv->device, priv->gl_context))
g_debug ("failed to make opengl context current %d, %x\r\n", hWnd, GetLastError());
} }
SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG)(guint64)(gpointer) window);
return 0; return 0;
} }
else if (GetWindowLongPtr(hWnd, GWLP_USERDATA)) { else if (GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
@ -491,6 +508,8 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
g_assert (priv->internal_win_id == hWnd); g_assert (priv->internal_win_id == hWnd);
g_assert (priv->gl_context == wglGetCurrentContext());
switch ( uMsg ) { switch ( uMsg ) {
case WM_SIZE: case WM_SIZE:
@ -516,18 +535,24 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_CLOSE: case WM_CLOSE:
{ {
g_debug ("WM_CLOSE\n"); g_debug ("WM_CLOSE\n");
if (priv->close_cb) priv->is_closed = TRUE;
priv->close_cb (priv->close_data); SetWindowLongPtr (hWnd, GWLP_USERDATA, 0);
wglMakeCurrent (NULL, NULL);
if (!wglMakeCurrent (NULL, NULL))
g_debug ("failed to make current %d, %x\r\n", hWnd, GetLastError());
if (priv->gl_context) if (priv->gl_context)
wglDeleteContext (priv->gl_context); {
if (!wglDeleteContext (priv->gl_context))
g_debug ("failed to destroy context %d, %x\r\n", priv->gl_context, GetLastError());
}
if (priv->internal_win_id) if (priv->internal_win_id)
DestroyWindow(priv->internal_win_id); {
if (!DestroyWindow(priv->internal_win_id))
g_debug ("failed to destroy window %d, %x\r\n", hWnd, GetLastError());
}
SetWindowLongPtr (hWnd, GWLP_USERDATA, 0);
DestroyWindow(hWnd);
PostQuitMessage (0); PostQuitMessage (0);
break; break;
} }
@ -541,9 +566,14 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
} }
case WM_GSTGLWINDOW: case WM_GSTGLWINDOW:
{
if (priv->is_closed && priv->close_cb)
priv->close_cb (priv->close_data);
else
{ {
GstGLWindowCB custom_cb = (GstGLWindowCB) lParam; GstGLWindowCB custom_cb = (GstGLWindowCB) lParam;
custom_cb ((gpointer) wParam); custom_cb ((gpointer) wParam);
}
break; break;
} }