diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index d0c027d431..9e5f9410fe 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -47,7 +47,6 @@ static void gst_gl_display_finalize (GObject* object); /* Called in the gl thread, protected by lock and unlock */ gpointer gst_gl_display_thread_create_context (GstGLDisplay* display); void gst_gl_display_thread_destroy_context (GstGLDisplay* display); -void gst_gl_display_thread_change_context (GstGLDisplay* display); void gst_gl_display_thread_run_generic (GstGLDisplay *display); void gst_gl_display_thread_gen_texture (GstGLDisplay* display); void gst_gl_display_thread_del_texture (GstGLDisplay* display); @@ -107,7 +106,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) //gl context display->gl_thread = NULL; display->gl_window = NULL; - display->winId = 0; display->visible = FALSE; display->isAlive = TRUE; display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal); @@ -120,10 +118,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->redisplay_texture_width = 0; display->redisplay_texture_height = 0; - //action resize - display->resize_width = 0; - display->resize_height = 0; - //action gen and del texture display->gen_texture = 0; display->gen_texture_width = 0; @@ -385,7 +379,7 @@ gst_gl_display_finalize (GObject* object) //------------------------------------------------------------ -//------------------ BEGIN GL THREAD ACTIONS ----------------- +//------------------ BEGIN GL THREAD PROCS ------------------- //------------------------------------------------------------ /* Called in the gl thread */ @@ -1399,7 +1393,7 @@ gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture, GLint wid guint key = (gint)width; key <<= 16; key |= (gint)height; - sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER(key)); + sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER((guint64)key)); //if there is a sub texture pool associated to th given key if (sub_texture_pool && g_queue_get_length(sub_texture_pool) > 0) @@ -1494,13 +1488,13 @@ gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture, GLint wid guint key = (gint)width; key <<= 16; key |= (gint)height; - sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER(key)); + sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER((guint64)key)); //if the size is known if (!sub_texture_pool) { sub_texture_pool = g_queue_new (); - g_hash_table_insert (display->texture_pool, GUINT_TO_POINTER(key), sub_texture_pool); + g_hash_table_insert (display->texture_pool, GUINT_TO_POINTER((guint64)key), sub_texture_pool); GST_INFO ("one more sub texture pool inserted: %d ", key); GST_INFO ("nb sub texture pools: %d", g_hash_table_size (display->texture_pool)); @@ -1582,12 +1576,10 @@ 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 width, GLint height, - gulong winId) + GLint width, GLint height) { gst_gl_display_lock (display); - display->winId = winId; display->upload_width = width; display->upload_height = height; @@ -1614,18 +1606,6 @@ gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible) } -/* Called by the glimagesink element */ -void -gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height) -{ - gst_gl_display_lock (display); - display->resize_width = width; - display->resize_height = height; - gst_gl_window_resize (display->gl_window, display->resize_width, display->resize_height); - gst_gl_display_unlock (display); -} - - /* Called by the glimagesink element */ gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height) @@ -1642,7 +1622,8 @@ gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gin display->redisplay_texture_width = width; display->redisplay_texture_height = height; } - gst_gl_window_draw (display->gl_window); + if (display->gl_window) + gst_gl_window_draw (display->gl_window); } gst_gl_display_unlock (display); @@ -1878,13 +1859,10 @@ gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader) /* Called by the glimagesink */ void -gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId) +gst_gl_display_set_window_id (GstGLDisplay* display, gulong window_id) { - //used only when glimagesink is connected to a gl flow - //otehrwise it can directly create the gl context using the winId gst_gl_display_lock (display); - display->winId = winId; - gst_gl_window_set_external_window_id (display->gl_window, display->winId); + gst_gl_window_set_external_window_id (display->gl_window, window_id); gst_gl_display_unlock (display); } diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 377b418378..0f3c323cc3 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -80,7 +80,6 @@ struct _GstGLDisplay { //gl context GThread* gl_thread; GstGLWindow* gl_window; - gulong winId; gboolean visible; gboolean isAlive; GHashTable* texture_pool; @@ -97,10 +96,6 @@ struct _GstGLDisplay { GLuint redisplay_texture_width; GLuint redisplay_texture_height; - //action resize - gint resize_width; - gint resize_height; - //action gen and del texture GLuint gen_texture; GLuint gen_texture_width; @@ -213,10 +208,8 @@ GType gst_gl_display_get_type (void); GstGLDisplay* gst_gl_display_new (void); void gst_gl_display_create_context (GstGLDisplay* display, - GLint width, GLint height, - gulong winId); + GLint width, GLint height); 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); void gst_gl_display_thread_add (GstGLDisplay *display, @@ -254,7 +247,7 @@ void gst_gl_display_gen_shader (GstGLDisplay* display, GstGLShader** shader); void gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader); -void gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId); +void gst_gl_display_set_window_id (GstGLDisplay* display, gulong window_id); void gst_gl_display_set_client_reshape_callback (GstGLDisplay* display, CRCB cb); void gst_gl_display_set_client_draw_callback (GstGLDisplay* display, CDCB cb); diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h index f8a6c92ffc..b97cfd899e 100644 --- a/gst-libs/gst/gl/gstglwindow.h +++ b/gst-libs/gst/gl/gstglwindow.h @@ -68,15 +68,14 @@ 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_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data); -gboolean gst_gl_window_has_internal_window_id (GstGLWindow *window); -gboolean gst_gl_window_has_internal_gl_context (GstGLWindow *window); +gboolean gst_gl_window_has_external_window_id (GstGLWindow *window); +gboolean gst_gl_window_has_external_gl_context (GstGLWindow *window); guint64 gst_gl_window_get_window_id (GstGLWindow *window); guint64 gst_gl_window_get_gl_context (GstGLWindow *window); void gst_gl_window_visible (GstGLWindow *window, gboolean visible); void gst_gl_window_draw (GstGLWindow *window); -void gst_gl_window_resize (GstGLWindow *window, gint width, gint height); void gst_gl_window_run_loop (GstGLWindow *window); void gst_gl_window_quit_loop (GstGLWindow *window); diff --git a/gst-libs/gst/gl/gstglwindow_win32.c b/gst-libs/gst/gl/gstglwindow_win32.c index b0e834d40c..fc9e1ee86b 100644 --- a/gst-libs/gst/gl/gstglwindow_win32.c +++ b/gst-libs/gst/gl/gstglwindow_win32.c @@ -33,6 +33,7 @@ void gst_gl_window_set_pixel_format (GstGLWindow *window); 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); #define GST_GL_WINDOW_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate)) @@ -66,6 +67,8 @@ G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT); gboolean _gst_gl_window_debug = FALSE; +HHOOK hHook; + /* Must be called in the gl thread */ static void gst_gl_window_finalize (GObject * object) @@ -193,7 +196,6 @@ gst_gl_window_new (gint width, gint height) //device is set in the window_proc g_assert (priv->device); - UpdateWindow (priv->internal_win_id); ShowCursor (TRUE); return window; @@ -208,7 +210,20 @@ gst_gl_window_error_quark (void) void gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id) { - g_warning ("gst_gl_window_set_external_window_id: not implemented\n"); + GstGLWindowPrivate *priv = window->priv; + WNDPROC window_parent_proc = (WNDPROC) (guint64) SetWindowLongPtr ((HWND)id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc); + RECT rect; + GetClientRect ((HWND)id, &rect); + SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); + SetParent (priv->internal_win_id, (HWND)id); + SetProp ((HWND)id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); + SetProp ((HWND)id, "gl_window_id", priv->internal_win_id); + priv->has_external_window_id = TRUE; + + //take changes into account: SWP_FRAMECHANGED + SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, + SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); + MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, rect.bottom, FALSE); } void @@ -253,24 +268,18 @@ gst_gl_window_has_external_window_id (GstGLWindow *window) { gboolean has_internal_window_id = TRUE; GstGLWindowPrivate *priv = window->priv; - - has_internal_window_id = priv->has_external_window_id; - return has_internal_window_id; + return priv->has_external_window_id; } /* Must be called in the gl thread */ gboolean -gst_gl_window_has_internal_gl_context (GstGLWindow *window) +gst_gl_window_has_external_gl_context (GstGLWindow *window) { gboolean has_external_gl_context = TRUE; GstGLWindowPrivate *priv = window->priv; - - - has_external_gl_context = priv->has_external_gl_context; - - return has_external_gl_context; + return priv->has_external_gl_context; } /* Must be called in the gl thread */ @@ -300,9 +309,9 @@ gst_gl_window_visible (GstGLWindow *window, gboolean visible) g_debug ("set visible %d\n", priv->internal_win_id); if (visible) - ret = ShowWindow (priv->internal_win_id, SW_SHOW); + ret = ShowWindowAsync (priv->internal_win_id, SW_SHOW); else - ret = ShowWindow (priv->internal_win_id, SW_HIDE); + ret = ShowWindowAsync (priv->internal_win_id, SW_HIDE); } /* Thread safe */ @@ -310,60 +319,8 @@ void gst_gl_window_draw (GstGLWindow *window) { GstGLWindowPrivate *priv = window->priv; - - if (!priv->has_external_window_id) - RedrawWindow (priv->internal_win_id, NULL, NULL, - RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE); - else - { - PAINTSTRUCT ps; - - /*RECT destsurf_rect; - POINT dest_surf_point; - - dest_surf_point.x = 0; - dest_surf_point.y = 0; - ClientToScreen (priv->external_win_id, &dest_surf_point); - GetClientRect (priv->external_win_id, &destsurf_rect); - OffsetRect (&destsurf_rect, dest_surf_point.x, dest_surf_point.y); - - if (window->State.Width != (destsurf_rect.right - destsurf_rect.left) || - window->State.Height != (destsurf_rect.bottom - destsurf_rect.top)) - { - window->State.Width = destsurf_rect.right - destsurf_rect.left; - window->State.Height = destsurf_rect.bottom - destsurf_rect.top; - window->State.NeedToResize = GL_FALSE; - if( FETCH_WCB( *window, Reshape ) ) - INVOKE_WCB( *window, Reshape, ( window->State.Width, window->State.Height ) ); - glViewport( 0, 0, window->State.Width, window->State.Height ); - }*/ - - BeginPaint (priv->external_win_id, &ps); - priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller - glFlush(); - SwapBuffers (priv->device); - EndPaint (priv->external_win_id, &ps); - } -} - -/* Thread safe */ -void -gst_gl_window_resize (GstGLWindow *window, gint width, gint height) -{ - GstGLWindowPrivate *priv = window->priv; - gint x = 0; - gint y = 0; - RECT winRect; - - GetWindowRect (priv->internal_win_id, &winRect); - x = winRect.left; - y = winRect.top; - - width += 2 * GetSystemMetrics (SM_CXSIZEFRAME); - height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION); - - SetWindowPos (priv->internal_win_id, HWND_TOP, x, y, width, height, - SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER); + RedrawWindow (priv->internal_win_id, NULL, NULL, + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE); } void @@ -515,7 +472,11 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_SIZE: { if (priv->resize_cb) + { + if (priv->has_external_window_id) + MoveWindow (hWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), FALSE); priv->resize_cb (priv->resize_data, LOWORD(lParam), HIWORD(lParam)); + } break; } @@ -589,3 +550,17 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam else return DefWindowProc( hWnd, uMsg, wParam, 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"); + + if (uMsg == WM_SIZE) + { + HWND gl_window_id = GetProp (hWnd, "gl_window_id"); + PostMessage (gl_window_id, WM_SIZE, wParam, lParam); + } + + return CallWindowProc (window_parent_proc, hWnd, uMsg, wParam, lParam); +} +