From 6cf97eb2213df2ef2f2bc0fb292a62aef15c4b14 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 29 Jan 2015 22:25:00 +1100 Subject: [PATCH] glwindow: make showing a window explicit Also fixes the cgl context always displaying a window to render to for every GstGLContextCocoa created --- ext/gl/gstglimagesink.c | 6 +- gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m | 91 +++++++++++++---------- gst-libs/gst/gl/gstglwindow.c | 21 ++++++ gst-libs/gst/gl/gstglwindow.h | 2 + gst-libs/gst/gl/win32/gstglwindow_win32.c | 38 ++++++---- gst-libs/gst/gl/x11/gstglwindow_x11.c | 49 ++++++++---- 6 files changed, 135 insertions(+), 72 deletions(-) diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index f812a0a8b3..469255224c 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -1439,13 +1439,15 @@ gst_glimage_sink_redisplay (GstGLImageSink * gl_sink) gst_object_unref (window); return FALSE; } + + gst_gl_window_set_preferred_size (window, GST_VIDEO_SINK_WIDTH (gl_sink), + GST_VIDEO_SINK_HEIGHT (gl_sink)); + gst_gl_window_show (window); } /* Drawing is asynchronous: gst_gl_window_draw is not blocking * It means that it does not wait for stuff to be executed in other threads */ - gst_gl_window_set_preferred_size (window, GST_VIDEO_SINK_WIDTH (gl_sink), - GST_VIDEO_SINK_HEIGHT (gl_sink)); gst_gl_window_draw (window); } alive = gst_gl_window_is_running (window); diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index f5084d5426..678fd63d84 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -77,6 +77,7 @@ static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); static void gst_gl_window_cocoa_set_preferred_size (GstGLWindow * window, gint width, gint height); +static void gst_gl_window_cocoa_show (GstGLWindow * window); struct _GstGLWindowCocoaPrivate { @@ -114,6 +115,7 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass) GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async); window_class->set_preferred_size = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_preferred_size); + window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_show); } static void @@ -220,6 +222,56 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle) } } +static void +gst_gl_window_cocoa_show (GstGLWindow * window) +{ + GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window); + GstGLWindowCocoaPrivate *priv = window_cocoa->priv; + + if (!priv->visible) { + /* useful when set_window_handle is called before + * the internal NSWindow */ + if (priv->external_view) { + gst_gl_window_cocoa_set_window_handle (window, (guintptr) priv->external_view); + priv->visible = TRUE; + return; + } + + dispatch_sync (dispatch_get_main_queue(), ^{ + if (!priv->external_view && !priv->visible) { + NSRect mainRect = [[NSScreen mainScreen] visibleFrame]; + NSRect windowRect = [priv->internal_win_id frame]; + gint x = 0; + gint y = 0; + + GST_DEBUG_OBJECT (window_cocoa, "main screen rect: %d %d %d %d\n", (int) mainRect.origin.x, + (int) mainRect.origin.y, (int) mainRect.size.width, + (int) mainRect.size.height); + + windowRect.origin.x += x; + windowRect.origin.y += mainRect.size.height > y ? (mainRect.size.height - y) * 0.5 : y; + windowRect.size.width = window_cocoa->priv->preferred_width; + windowRect.size.height = window_cocoa->priv->preferred_height; + + GST_DEBUG_OBJECT (window_cocoa, "window rect: %d %d %d %d\n", (int) windowRect.origin.x, + (int) windowRect.origin.y, (int) windowRect.size.width, + (int) windowRect.size.height); + + x += 20; + y += 20; + + [priv->internal_win_id setFrame:windowRect display:NO]; + GST_DEBUG_OBJECT (window_cocoa, "make the window available\n"); + + [priv->internal_win_id makeMainWindow]; + [priv->internal_win_id orderFrontRegardless]; + [priv->internal_win_id setViewsNeedDisplay:YES]; + + priv->visible = TRUE; + } + }); + } +} static void gst_gl_window_cocoa_draw (GstGLWindow * window) @@ -313,45 +365,6 @@ gst_gl_cocoa_draw_cb (GstGLWindowCocoa *window_cocoa) { GstGLWindowCocoaPrivate *priv = window_cocoa->priv; - /* useful when set_window_handle is called before - * the internal NSWindow */ - if (priv->external_view && !priv->visible) { - gst_gl_window_cocoa_set_window_handle (GST_GL_WINDOW (window_cocoa), (guintptr) priv->external_view); - priv->visible = TRUE; - } - - if (!priv->external_view && !priv->visible) { - NSRect mainRect = [[NSScreen mainScreen] visibleFrame]; - NSRect windowRect = [priv->internal_win_id frame]; - gint x = 0; - gint y = 0; - - GST_DEBUG ("main screen rect: %d %d %d %d\n", (int) mainRect.origin.x, - (int) mainRect.origin.y, (int) mainRect.size.width, - (int) mainRect.size.height); - - windowRect.origin.x += x; - windowRect.origin.y += mainRect.size.height > y ? (mainRect.size.height - y) * 0.5 : y; - windowRect.size.width = window_cocoa->priv->preferred_width; - windowRect.size.height = window_cocoa->priv->preferred_height; - - GST_DEBUG ("window rect: %d %d %d %d\n", (int) windowRect.origin.x, - (int) windowRect.origin.y, (int) windowRect.size.width, - (int) windowRect.size.height); - - x += 20; - y += 20; - - [priv->internal_win_id setFrame:windowRect display:NO]; - GST_DEBUG ("make the window available\n"); - - [priv->internal_win_id makeMainWindow]; - [priv->internal_win_id orderFrontRegardless]; - [priv->internal_win_id setViewsNeedDisplay:YES]; - - priv->visible = TRUE; - } - if (g_main_loop_is_running (priv->loop)) { if (![priv->internal_win_id isClosed]) { GstGLWindow *window = GST_GL_WINDOW (window_cocoa); diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c index a1ae9d6889..cc2eabafc3 100644 --- a/gst-libs/gst/gl/gstglwindow.c +++ b/gst-libs/gst/gl/gstglwindow.c @@ -381,6 +381,27 @@ gst_gl_window_set_preferred_size (GstGLWindow * window, gint width, gint height) window_class->set_preferred_size (window, width, height); } +/** + * gst_gl_window_show: + * @window: a #GstGLWindow + * + * Present the window to the screen. + * + * Since: 1.6 + */ +void +gst_gl_window_show (GstGLWindow * window) +{ + GstGLWindowClass *window_class; + + g_return_if_fail (GST_GL_IS_WINDOW (window)); + window_class = GST_GL_WINDOW_GET_CLASS (window); + g_return_if_fail (window_class->show != NULL); + + if (window_class->show) + window_class->show (window); +} + /** * gst_gl_window_run: * @window: a #GstGLWindow diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h index 1f676f0348..bd13417511 100644 --- a/gst-libs/gst/gl/gstglwindow.h +++ b/gst-libs/gst/gl/gstglwindow.h @@ -141,6 +141,7 @@ struct _GstGLWindowClass { void (*get_surface_dimensions) (GstGLWindow *window, guint *width, guint *height); void (*handle_events) (GstGLWindow *window, gboolean handle_events); void (*set_preferred_size) (GstGLWindow *window, gint width, gint height); + void (*show) (GstGLWindow *window); /*< private >*/ gpointer _reserved[GST_PADDING]; @@ -213,6 +214,7 @@ void gst_gl_window_send_mouse_event (GstGLWindow * window, /* surfaces/rendering */ void gst_gl_window_draw_unlocked (GstGLWindow *window); void gst_gl_window_draw (GstGLWindow *window); +void gst_gl_window_show (GstGLWindow *window); void gst_gl_window_set_preferred_size (GstGLWindow * window, gint width, gint height); diff --git a/gst-libs/gst/gl/win32/gstglwindow_win32.c b/gst-libs/gst/gl/win32/gstglwindow_win32.c index be1d6e99c4..f45ab7286e 100644 --- a/gst-libs/gst/gl/win32/gstglwindow_win32.c +++ b/gst-libs/gst/gl/win32/gstglwindow_win32.c @@ -63,6 +63,7 @@ static void gst_gl_window_win32_set_window_handle (GstGLWindow * window, static guintptr gst_gl_window_win32_get_display (GstGLWindow * window); static void gst_gl_window_win32_set_preferred_size (GstGLWindow * window, gint width, gint height); +static void gst_gl_window_win32_show (GstGLWindow * window); static void gst_gl_window_win32_draw (GstGLWindow * window); static void gst_gl_window_win32_run (GstGLWindow * window); static void gst_gl_window_win32_quit (GstGLWindow * window); @@ -88,6 +89,7 @@ gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass) GST_DEBUG_FUNCPTR (gst_gl_window_win32_get_display); window_class->set_preferred_size = GST_DEBUG_FUNCPTR (gst_gl_window_win32_set_preferred_size); + window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_win32_show); } static void @@ -263,23 +265,10 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id) } static void -gst_gl_window_win32_set_preferred_size (GstGLWindow * window, gint width, - gint height) +gst_gl_window_win32_show (GstGLWindow * window) { GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window); - window_win32->priv->preferred_width = width; - window_win32->priv->preferred_height = height; -} - -/* Thread safe */ -static void -gst_gl_window_win32_draw (GstGLWindow * window) -{ - GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window); - gint width = window_win32->priv->preferred_width; - gint height = window_win32->priv->preferred_height; - if (!window_win32->visible) { HWND parent_id = window_win32->parent_win_id; @@ -295,10 +284,29 @@ gst_gl_window_win32_draw (GstGLWindow * window) MoveWindow (window_win32->internal_win_id, rect.left, rect.top, width, height, FALSE); } - ShowWindowAsync (window_win32->internal_win_id, SW_SHOW); + ShowWindowAsync (window_win32->internal_win_id, SW_SHOW); window_win32->visible = TRUE; } +} + +static void +gst_gl_window_win32_set_preferred_size (GstGLWindow * window, gint width, + gint height) +{ + GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window); + + window_win32->priv->preferred_width = width; + window_win32->priv->preferred_height = height; +} + +/* Thread safe */ +static void +gst_gl_window_win32_draw (GstGLWindow * window) +{ + GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window); + gint width = window_win32->priv->preferred_width; + gint height = window_win32->priv->preferred_height; RedrawWindow (window_win32->internal_win_id, NULL, NULL, RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE); diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c index 71d3ad66b9..c5e7355f2f 100644 --- a/gst-libs/gst/gl/x11/gstglwindow_x11.c +++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c @@ -71,6 +71,7 @@ void gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr gst_gl_window_x11_get_window_handle (GstGLWindow * window); static void gst_gl_window_x11_set_preferred_size (GstGLWindow * window, gint width, gint height); +void gst_gl_window_x11_show (GstGLWindow * window); void gst_gl_window_x11_draw_unlocked (GstGLWindow * window); void gst_gl_window_x11_draw (GstGLWindow * window); void gst_gl_window_x11_run (GstGLWindow * window); @@ -123,6 +124,7 @@ gst_gl_window_x11_class_init (GstGLWindowX11Class * klass) GST_DEBUG_FUNCPTR (gst_gl_window_x11_handle_events); window_class->set_preferred_size = GST_DEBUG_FUNCPTR (gst_gl_window_x11_set_preferred_size); + window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_x11_show); } static void @@ -371,6 +373,37 @@ gst_gl_window_x11_set_preferred_size (GstGLWindow * window, gint width, window_x11->priv->preferred_height = height; } +static void +_show_window (GstGLWindow * window) +{ + GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window); + guint width = window_x11->priv->preferred_width; + guint height = window_x11->priv->preferred_height; + XWindowAttributes attr; + + XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr); + + if (!window_x11->visible) { + + if (!window_x11->parent_win) { + attr.width = width; + attr.height = height; + XResizeWindow (window_x11->device, window_x11->internal_win_id, + attr.width, attr.height); + XSync (window_x11->device, FALSE); + } + + XMapWindow (window_x11->device, window_x11->internal_win_id); + window_x11->visible = TRUE; + } +} + +void +gst_gl_window_x11_show (GstGLWindow * window) +{ + gst_gl_window_send_message (window, (GstGLWindowCB) _show_window, window); +} + /* Called in the gl thread */ void gst_gl_window_x11_draw_unlocked (GstGLWindow * window) @@ -397,8 +430,6 @@ static void draw_cb (gpointer data) { GstGLWindowX11 *window_x11 = data; - guint width = window_x11->priv->preferred_width; - guint height = window_x11->priv->preferred_height; if (g_main_loop_is_running (window_x11->loop)) { XWindowAttributes attr; @@ -406,20 +437,6 @@ draw_cb (gpointer data) XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr); - if (!window_x11->visible) { - - if (!window_x11->parent_win) { - attr.width = width; - attr.height = height; - XResizeWindow (window_x11->device, window_x11->internal_win_id, - attr.width, attr.height); - XSync (window_x11->device, FALSE); - } - - XMapWindow (window_x11->device, window_x11->internal_win_id); - window_x11->visible = TRUE; - } - if (window_x11->parent_win) { XWindowAttributes attr_parent; XGetWindowAttributes (window_x11->device, window_x11->parent_win,