glwindow: make showing a window explicit

Also fixes the cgl context always displaying a window to render to for
every GstGLContextCocoa created
This commit is contained in:
Matthew Waters 2015-01-29 22:25:00 +11:00
parent 71e4c485f0
commit 6cf97eb221
6 changed files with 135 additions and 72 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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,