From fc9479d28952ff2bf67a02afb9cc741ffb5e516d Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 25 Oct 2008 02:03:16 +0200 Subject: [PATCH] [251/906] Properly clean OpenGL contexts --- gst-libs/gst/gl/gstgldisplay.c | 26 +++++++---------- gst-libs/gst/gl/gstgldisplay.h | 39 +------------------------ gst-libs/gst/gl/gstglwindow_win32.c | 58 ++++++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 77 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index 794eafb..a68d043 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -108,8 +108,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->gl_thread = NULL; display->gl_window = NULL; display->winId = 0; - display->win_xpos = 0; - display->win_ypos = 0; display->visible = FALSE; display->isAlive = TRUE; display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal); @@ -355,8 +353,9 @@ gst_gl_display_finalize (GObject* object) if (display->gl_thread) { - g_thread_join (display->gl_thread); + gpointer ret = g_thread_join (display->gl_thread); GST_INFO ("gl thread joined"); + g_assert (ret == NULL); display->gl_thread = NULL; } @@ -389,10 +388,6 @@ gst_gl_display_finalize (GObject* object) //------------------ BEGIN GL THREAD ACTIONS ----------------- //------------------------------------------------------------ -//The following functions are thread safe because -//called by the "gst_gl_display_thread_dispatch_action" -//in a lock/unlock scope. - /* Called in the gl thread */ gpointer gst_gl_display_thread_create_context (GstGLDisplay *display) @@ -401,9 +396,15 @@ gst_gl_display_thread_create_context (GstGLDisplay *display) display->gl_window = gst_gl_window_new (display->upload_width, display->upload_height); - GST_INFO ("gl window created"); + if (!display->gl_window) + { + display->isAlive = FALSE; + GST_ERROR_OBJECT (display, "Failed to create gl window"); + g_cond_signal (display->cond_create_context); + return NULL; + } - gst_gl_window_visible (display->gl_window, display->visible); + GST_INFO ("gl window created"); //Init glew err = glewInit(); @@ -1580,19 +1581,14 @@ gst_gl_display_new (void) * Called by the first gl element of a video/x-raw-gl flow */ void gst_gl_display_create_context (GstGLDisplay *display, - GLint x, GLint y, GLint width, GLint height, - gulong winId, - gboolean visible) + gulong winId) { gst_gl_display_lock (display); display->winId = winId; - display->win_xpos = x; - display->win_ypos = y; display->upload_width = width; display->upload_height = height; - display->visible = visible; display->gl_thread = g_thread_create ( (GThreadFunc) gst_gl_display_thread_create_context, display, TRUE, NULL); diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index ee81188..377b418 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -56,39 +56,6 @@ typedef enum { GST_GL_DISPLAY_PROJECTION_PERSPECIVE } GstGLDisplayProjection; - -//Message type -typedef enum { - GST_GL_DISPLAY_ACTION_CREATE_CONTEXT, - GST_GL_DISPLAY_ACTION_DESTROY_CONTEXT, - GST_GL_DISPLAY_ACTION_CHANGE_CONTEXT, - GST_GL_DISPLAY_ACTION_VISIBLE_CONTEXT, - GST_GL_DISPLAY_ACTION_RESIZE_CONTEXT, - GST_GL_DISPLAY_ACTION_REDISPLAY_CONTEXT, - GST_GL_DISPLAY_ACTION_GENERIC, - GST_GL_DISPLAY_ACTION_GEN_TEXTURE, - GST_GL_DISPLAY_ACTION_DEL_TEXTURE, - GST_GL_DISPLAY_ACTION_INIT_UPLOAD, - GST_GL_DISPLAY_ACTION_DO_UPLOAD, - GST_GL_DISPLAY_ACTION_INIT_DOWNLOAD, - GST_GL_DISPLAY_ACTION_DO_DOWNLOAD, - GST_GL_DISPLAY_ACTION_GEN_FBO, - GST_GL_DISPLAY_ACTION_USE_FBO, - GST_GL_DISPLAY_ACTION_DEL_FBO, - GST_GL_DISPLAY_ACTION_GEN_SHADER, - GST_GL_DISPLAY_ACTION_DEL_SHADER - -} GstGLDisplayAction; - - -//Message to communicate with the gl thread -typedef struct _GstGLDisplayMsg { - GstGLDisplayAction action; - gint glutWinId; - GstGLDisplay* display; -} GstGLDisplayMsg; - - //Texture pool elements typedef struct _GstGLDisplayTex { GLuint texture; @@ -114,8 +81,6 @@ struct _GstGLDisplay { GThread* gl_thread; GstGLWindow* gl_window; gulong winId; - gint win_xpos; - gint win_ypos; gboolean visible; gboolean isAlive; GHashTable* texture_pool; @@ -248,10 +213,8 @@ GType gst_gl_display_get_type (void); GstGLDisplay* gst_gl_display_new (void); void gst_gl_display_create_context (GstGLDisplay* display, - GLint x, GLint y, GLint width, GLint height, - gulong winId, - gboolean visible); + gulong winId); void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible); void gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height); gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height); diff --git a/gst-libs/gst/gl/gstglwindow_win32.c b/gst-libs/gst/gl/gstglwindow_win32.c index 2711934..cc0a082 100644 --- a/gst-libs/gst/gl/gstglwindow_win32.c +++ b/gst-libs/gst/gl/gstglwindow_win32.c @@ -96,7 +96,7 @@ gst_gl_window_class_init (GstGLWindowClass * klass) obj_class->finalize = gst_gl_window_finalize; - GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc); + atom = GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc); ZeroMemory (&wc, sizeof(WNDCLASS)); @@ -107,15 +107,11 @@ gst_gl_window_class_init (GstGLWindowClass * klass) wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.hCursor = LoadCursor( NULL, IDC_ARROW ); - wc.hbrBackground = NULL; + wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "GSTGL"; atom = RegisterClass (&wc); - - g_assert (atom); - - g_debug ("GSTGL window class registered\n"); } static void @@ -138,9 +134,10 @@ gst_gl_window_new (gint width, gint height) GstGLWindowPrivate *priv = window->priv; GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window); - static gint x = 50; + static gint x = 0; static gint y = 0; - y = 50 + height * y++; + x += 20; + y += 20; priv->internal_win_id = 0; priv->external_win_id = 0; @@ -180,9 +177,13 @@ gst_gl_window_new (gint width, gint height) UpdateWindow (priv->internal_win_id); ShowCursor (TRUE); - wglMakeCurrent (priv->device, priv->gl_context); - - return window; + if (wglMakeCurrent (priv->device, priv->gl_context)) + return window; + else + { + g_debug ("Failed to make opengl context current"); + return NULL; + } } GQuark @@ -324,7 +325,7 @@ gst_gl_window_draw (GstGLWindow *window) BeginPaint (priv->external_win_id, &ps); priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller - //glFlush(); + glFlush(); SwapBuffers (priv->device); EndPaint (priv->external_win_id, &ps); } @@ -386,6 +387,7 @@ gst_gl_window_quit_loop (GstGLWindow *window) GstGLWindowPrivate *priv = window->priv; LRESULT res = PostMessage(priv->internal_win_id, WM_CLOSE, 0, 0); g_assert (SUCCEEDED (res)); + g_debug ("end loop requested\n"); } } @@ -451,8 +453,6 @@ gst_gl_window_set_pixel_format (GstGLWindow *window) LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static gboolean created = FALSE; - if (uMsg == WM_CREATE) { GstGLWindow *window = (GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams); @@ -468,14 +468,17 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam priv->device = GetDC (hWnd); gst_gl_window_set_pixel_format (window); priv->gl_context = wglCreateContext (priv->device); + 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_assert (priv->gl_context); ReleaseDC (hWnd, priv->device); } - created = TRUE; - return 0; } - else if (created) { + else if (GetWindowLongPtr(hWnd, GWLP_USERDATA)) { GstGLWindow *window = (GstGLWindow *) (guint64) GetWindowLongPtr(hWnd, GWLP_USERDATA); GstGLWindowPrivate *priv = NULL; @@ -486,6 +489,8 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam g_assert (priv); + g_assert (priv->internal_win_id == hWnd); + switch ( uMsg ) { case WM_SIZE: @@ -513,14 +518,16 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam g_debug ("WM_CLOSE\n"); if (priv->close_cb) priv->close_cb (priv->close_data); - DestroyWindow(hWnd); - break; - } + wglMakeCurrent (NULL, NULL); - case WM_DESTROY: - { - g_debug ("WM_DESTROY\n"); - created = FALSE; + if (priv->gl_context) + wglDeleteContext (priv->gl_context); + + if (priv->internal_win_id) + DestroyWindow(priv->internal_win_id); + + SetWindowLongPtr (hWnd, GWLP_USERDATA, 0); + DestroyWindow(hWnd); PostQuitMessage (0); break; } @@ -540,6 +547,9 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam break; } + case WM_ERASEBKGND: + return TRUE; + default: return DefWindowProc( hWnd, uMsg, wParam, lParam ); } -- 2.7.4