gl: cocoa: Implement set_render_rectangle
Resize the internal NSView according to the provided render rectangle.
https://bugzilla.gnome.org/show_bug.cgi?id=791445
diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
index 4533b83..c29c97b 100644
--- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
@@ -86,6 +86,8 @@
static void gst_gl_window_cocoa_queue_resize (GstGLWindow * window);
static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
+static gboolean gst_gl_window_cocoa_set_render_rectangle (GstGLWindow *
+ window, gint x, gint y, gint width, gint height);
struct _GstGLWindowCocoaPrivate
{
@@ -95,8 +97,6 @@
gint preferred_width;
gint preferred_height;
- GLint viewport_dim[4];
-
/* atomic set when the internal NSView has been created */
int view_ready;
@@ -124,6 +124,8 @@
window_class->queue_resize = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_queue_resize);
window_class->send_message_async =
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async);
+ window_class->set_render_rectangle =
+ GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_render_rectangle);
gobject_class->finalize = gst_gl_window_cocoa_finalize;
}
@@ -184,6 +186,8 @@
context_cocoa = GST_GL_CONTEXT_COCOA (context);
layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context];
+ layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
+ layer.needsDisplayOnBoundsChange = YES;
glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer];
gst_object_unref (context);
@@ -267,6 +271,7 @@
[external_view addSubview: view];
+ [external_view setAutoresizesSubviews: YES];
[view setFrame: [external_view bounds]];
[view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
});
@@ -447,6 +452,70 @@
g_thread_unref (thread);
}
+struct SetRenderRectangle
+{
+ GstGLWindowCocoa *window_cocoa;
+ GstVideoRectangle rect;
+};
+
+static void
+_free_set_render_rectangle (struct SetRenderRectangle *render)
+{
+ if (render) {
+ if (render->window_cocoa) {
+ gst_object_unref (render->window_cocoa);
+ }
+ g_free (render);
+ }
+}
+
+static void
+_set_render_rectangle (gpointer data)
+{
+ struct SetRenderRectangle *render = data;
+ NSView *view;
+ GstGLWindowCocoaPrivate *priv = render->window_cocoa->priv;
+ GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
+
+ GST_LOG_OBJECT (render->window_cocoa, "setting render rectangle %i,%i+%ix%i",
+ render->rect.x, render->rect.y, render->rect.w, render->rect.h);
+ if (!g_atomic_int_get (&render->window_cocoa->priv->view_ready)) {
+ return;
+ }
+
+ view = [internal_win_id contentView];
+ CGRect newMainViewFrame = CGRectMake(render->rect.x,
+ render->rect.y,
+ render->rect.w,
+ render->rect.h);
+
+ [view.superview setFrame:newMainViewFrame];
+ [view setFrame: view.superview.bounds];
+
+ [CATransaction begin];
+ [view setNeedsDisplay:YES];
+ [CATransaction commit];
+}
+
+static gboolean
+gst_gl_window_cocoa_set_render_rectangle (GstGLWindow * window, gint x, gint y, gint width, gint height)
+{
+ GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window;
+ struct SetRenderRectangle *render;
+
+ render = g_new0 (struct SetRenderRectangle, 1);
+ render->window_cocoa = gst_object_ref (window_cocoa);
+ render->rect.x = x;
+ render->rect.y = y;
+ render->rect.w = width;
+ render->rect.h = height;
+
+ _invoke_on_main ((GstGLWindowCB) _set_render_rectangle, render,
+ (GDestroyNotify) _free_set_render_rectangle);
+
+ return TRUE;
+}
+
/* =============================================================*/
/* */
/* GstGLNSWindow implementation */