From f9756b85d2ff1db2363fffa628827a72c416bc17 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 25 Oct 2008 16:18:23 +0200 Subject: [PATCH] [252/906] avoid a dead lock on window closure --- gst-libs/gst/gl/gstgldisplay.c | 17 ++--- gst-libs/gst/gl/gstglshader.c | 6 ++ gst-libs/gst/gl/gstglwindow.h | 1 - gst-libs/gst/gl/gstglwindow_win32.c | 122 ++++++++++++++++++++++-------------- 4 files changed, 91 insertions(+), 55 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index a68d043..d0c027d 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -346,9 +346,9 @@ gst_gl_display_finalize (GObject* object) //leave gl window loop 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_DEBUG ("quit sent to gl window loop"); + GST_INFO ("quit sent to gl window loop"); gst_gl_display_unlock (display); 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_DEBUG ("loop exited\n"); + GST_INFO ("loop exited\n"); + + display->isAlive = FALSE; gst_gl_display_thread_destroy_context (display); @@ -870,7 +872,7 @@ gst_gl_display_thread_init_download (GstGLDisplay *display) 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) @@ -1054,7 +1056,7 @@ gst_gl_display_thread_init_download (GstGLDisplay *display) else { //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; } } @@ -1325,11 +1327,12 @@ gst_gl_display_on_resize (GstGLDisplay* display, gint width, gint height) 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) return; //opengl scene + GST_INFO ("on draw"); //make sure that the environnement is clean 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) { GST_INFO ("on close"); - gst_gl_display_lock (display); display->isAlive = FALSE; - gst_gl_display_unlock (display); } diff --git a/gst-libs/gst/gl/gstglshader.c b/gst-libs/gst/gl/gstglshader.c index c0f08bc..8cd281e 100644 --- a/gst-libs/gst/gl/gstglshader.c +++ b/gst-libs/gst/gl/gstglshader.c @@ -141,6 +141,12 @@ gst_gl_shader_log_handler (const gchar *domain, GLogLevelFlags flags, } static void +gst_gl_shader_base_init (gpointer g_class) +{ +} + + +static void gst_gl_shader_class_init (GstGLShaderClass * klass) { /* bind class methods .. */ diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h index 1f04758..f8a6c92 100644 --- a/gst-libs/gst/gl/gstglwindow.h +++ b/gst-libs/gst/gl/gstglwindow.h @@ -53,7 +53,6 @@ struct _GstGLWindow { struct _GstGLWindowClass { /*< private >*/ GObjectClass parent_class; - guint64 instance; }; /* methods */ diff --git a/gst-libs/gst/gl/gstglwindow_win32.c b/gst-libs/gst/gl/gstglwindow_win32.c index cc0a082..b0e834d 100644 --- a/gst-libs/gst/gl/gstglwindow_win32.c +++ b/gst-libs/gst/gl/gstglwindow_win32.c @@ -56,6 +56,7 @@ struct _GstGLWindowPrivate gpointer resize_data; GstGLWindowCB close_cb; gpointer close_data; + gboolean is_closed; }; G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT); @@ -85,33 +86,18 @@ gst_gl_window_log_handler (const gchar *domain, GLogLevelFlags flags, } static void +gst_gl_window_base_init (gpointer g_class) +{ +} + +static void gst_gl_window_class_init (GstGLWindowClass * klass) { - WNDCLASS wc; - ATOM atom = 0; GObjectClass *obj_class = G_OBJECT_CLASS (klass); - klass->instance = (guint64) GetModuleHandle (NULL); g_type_class_add_private (klass, sizeof (GstGLWindowPrivate)); 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 @@ -133,9 +119,37 @@ gst_gl_window_new (gint width, gint height) GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL); GstGLWindowPrivate *priv = window->priv; GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window); - + + WNDCLASS wc; + ATOM atom = 0; + HINSTANCE hinstance = GetModuleHandle (NULL); + static gint x = 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; y += 20; @@ -151,6 +165,7 @@ gst_gl_window_new (gint width, gint height) priv->resize_data = NULL; priv->close_cb = NULL; priv->close_data = NULL; + priv->is_closed = FALSE; width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION); @@ -163,11 +178,15 @@ gst_gl_window_new (gint width, gint height) x, y, width, height, (HWND) NULL, (HMENU) NULL, - (HINSTANCE) klass->instance, + hinstance, 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); @@ -177,13 +196,7 @@ gst_gl_window_new (gint width, gint height) UpdateWindow (priv->internal_win_id); ShowCursor (TRUE); - if (wglMakeCurrent (priv->device, priv->gl_context)) - return window; - else - { - g_debug ("Failed to make opengl context current"); - return NULL; - } + return window; } GQuark @@ -283,6 +296,8 @@ gst_gl_window_visible (GstGLWindow *window, gboolean visible) { GstGLWindowPrivate *priv = window->priv; BOOL ret = FALSE; + + g_debug ("set visible %d\n", priv->internal_win_id); if (visible) ret = ShowWindow (priv->internal_win_id, SW_SHOW); @@ -298,7 +313,7 @@ gst_gl_window_draw (GstGLWindow *window) if (!priv->has_external_window_id) RedrawWindow (priv->internal_win_id, NULL, NULL, - RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE /*| RDW_UPDATENOW*/); + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE); else { PAINTSTRUCT ps; @@ -365,7 +380,7 @@ gst_gl_window_run_loop (GstGLWindow *window) { 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; } else @@ -431,7 +446,7 @@ gst_gl_window_set_pixel_format (GstGLWindow *window) pfd.cAccumGreenBits = 0; pfd.cAccumBlueBits = 0; pfd.cAccumAlphaBits = 0; - pfd.cDepthBits = 24; + pfd.cDepthBits = 32; pfd.cStencilBits = 8; pfd.cAuxBuffers = 0; 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"); - SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG)(guint64)(gpointer) window); - g_assert (window); { @@ -471,11 +484,15 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam if (priv->gl_context) g_debug ("gl context created: %d\n", priv->gl_context); 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); 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; } 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->gl_context == wglGetCurrentContext()); + switch ( uMsg ) { case WM_SIZE: @@ -516,18 +535,24 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_CLOSE: { g_debug ("WM_CLOSE\n"); - if (priv->close_cb) - priv->close_cb (priv->close_data); - wglMakeCurrent (NULL, NULL); + priv->is_closed = TRUE; + SetWindowLongPtr (hWnd, GWLP_USERDATA, 0); + + if (!wglMakeCurrent (NULL, NULL)) + g_debug ("failed to make current %d, %x\r\n", hWnd, GetLastError()); 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) - DestroyWindow(priv->internal_win_id); - - SetWindowLongPtr (hWnd, GWLP_USERDATA, 0); - DestroyWindow(hWnd); + { + if (!DestroyWindow(priv->internal_win_id)) + g_debug ("failed to destroy window %d, %x\r\n", hWnd, GetLastError()); + } + PostQuitMessage (0); break; } @@ -542,8 +567,13 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_GSTGLWINDOW: { - GstGLWindowCB custom_cb = (GstGLWindowCB) lParam; - custom_cb ((gpointer) wParam); + if (priv->is_closed && priv->close_cb) + priv->close_cb (priv->close_data); + else + { + GstGLWindowCB custom_cb = (GstGLWindowCB) lParam; + custom_cb ((gpointer) wParam); + } break; } -- 2.7.4