diff --git a/gst-libs/gst/vulkan/gstvkswapper.c b/gst-libs/gst/vulkan/gstvkswapper.c index 89cc922425..6ac06f4c47 100644 --- a/gst-libs/gst/vulkan/gstvkswapper.c +++ b/gst-libs/gst/vulkan/gstvkswapper.c @@ -66,10 +66,12 @@ struct _GstVulkanSwapperPrivate /* runtime variables */ gint to_quit; GstBuffer *current_buffer; + gboolean any_current_extent; /* signal handlers */ gulong close_id; gulong draw_id; + gulong resize_id; /* properties */ gboolean force_aspect_ratio; @@ -104,6 +106,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVulkanSwapper, gst_vulkan_swapper, static void _on_window_draw (GstVulkanWindow * window, GstVulkanSwapper * swapper); +static void _on_window_resize (GstVulkanWindow * window, + guint width, guint height, GstVulkanSwapper * swapper); static gboolean _get_function_table (GstVulkanSwapper * swapper) @@ -525,6 +529,9 @@ gst_vulkan_swapper_finalize (GObject * object) g_signal_handler_disconnect (swapper->window, swapper->priv->close_id); swapper->priv->close_id = 0; + g_signal_handler_disconnect (swapper->window, swapper->priv->resize_id); + swapper->priv->resize_id = 0; + if (swapper->window) gst_object_unref (swapper->window); swapper->window = NULL; @@ -586,6 +593,8 @@ gst_vulkan_swapper_new (GstVulkanDevice * device, GstVulkanWindow * window) (GCallback) _on_window_close, swapper); swapper->priv->draw_id = g_signal_connect (swapper->window, "draw", (GCallback) _on_window_draw, swapper); + swapper->priv->resize_id = g_signal_connect (swapper->window, "resize", + (GCallback) _on_window_resize, swapper); return swapper; } @@ -672,11 +681,15 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps, if (swapper->priv->surf_props.currentExtent.width == -1) { /* If the surface size is undefined, the size is set to * the size of the images requested. */ - swapchain_dims.width = 320; - swapchain_dims.height = 240; + guint width, height; + gst_vulkan_window_get_surface_dimensions (swapper->window, &width, &height); + swapchain_dims.width = width; + swapchain_dims.height = height; + swapper->priv->any_current_extent = TRUE; } else { /* If the surface size is defined, the swap chain size must match */ swapchain_dims = swapper->priv->surf_props.currentExtent; + swapper->priv->any_current_extent = FALSE; } /* If mailbox mode is available, use it, as is the lowest-latency non- @@ -1319,3 +1332,18 @@ _on_window_draw (GstVulkanWindow * window, GstVulkanSwapper * swapper) g_clear_error (&error); RENDER_UNLOCK (swapper); } + +static void +_on_window_resize (GstVulkanWindow * window, guint width, guint height, + GstVulkanSwapper * swapper) +{ + GError *error = NULL; + + RENDER_LOCK (swapper); + if (swapper->priv->any_current_extent) { + if (!_swapchain_resize (swapper, &error)) + GST_ERROR_OBJECT (swapper, "Failed to resize swapchain: %s", + error->message); + } + RENDER_UNLOCK (swapper); +} diff --git a/gst-libs/gst/vulkan/gstvkwindow.c b/gst-libs/gst/vulkan/gstvkwindow.c index b7264bba46..1482cbd174 100644 --- a/gst-libs/gst/vulkan/gstvkwindow.c +++ b/gst-libs/gst/vulkan/gstvkwindow.c @@ -93,6 +93,7 @@ enum SIGNAL_0, SIGNAL_CLOSE, SIGNAL_DRAW, + SIGNAL_RESIZE, LAST_SIGNAL }; @@ -193,6 +194,10 @@ gst_vulkan_window_class_init (GstVulkanWindowClass * klass) g_signal_new ("draw", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + gst_vulkan_window_signals[SIGNAL_RESIZE] = + g_signal_new ("resize", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + gobject_class->set_property = gst_vulkan_window_set_property; gobject_class->get_property = gst_vulkan_window_get_property; gobject_class->finalize = gst_vulkan_window_finalize; @@ -394,7 +399,8 @@ gst_vulkan_window_resize (GstVulkanWindow * window, gint width, gint height) window->priv->surface_width = width; window->priv->surface_height = height; - /* XXX: possibly queue a resize/redraw */ + g_signal_emit (window, gst_vulkan_window_signals[SIGNAL_RESIZE], 0, width, + height); } /** @@ -431,6 +437,25 @@ gst_vulkan_window_set_window_handle (GstVulkanWindow * window, guintptr handle) } } +void +gst_vulkan_window_get_surface_dimensions (GstVulkanWindow * window, + guint * width, guint * height) +{ + GstVulkanWindowClass *klass; + + g_return_if_fail (GST_IS_VULKAN_WINDOW (window)); + klass = GST_VULKAN_WINDOW_GET_CLASS (window); + + if (klass->get_surface_dimensions) { + klass->get_surface_dimensions (window, width, height); + } else { + GST_DEBUG_OBJECT (window, "Returning size %ix%i", + window->priv->surface_width, window->priv->surface_height); + *width = window->priv->surface_width; + *height = window->priv->surface_height; + } +} + GType gst_vulkan_dummy_window_get_type (void); G_DEFINE_TYPE (GstVulkanDummyWindow, gst_vulkan_dummy_window, GST_TYPE_VULKAN_WINDOW); diff --git a/gst-libs/gst/vulkan/gstvkwindow.h b/gst-libs/gst/vulkan/gstvkwindow.h index 1ece99bce9..1348d04d00 100644 --- a/gst-libs/gst/vulkan/gstvkwindow.h +++ b/gst-libs/gst/vulkan/gstvkwindow.h @@ -90,6 +90,9 @@ struct _GstVulkanWindowClass { guint32 queue_family_idx); void (*set_window_handle) (GstVulkanWindow *window, guintptr handle); + void (*get_surface_dimensions) (GstVulkanWindow *window, + guint * width, + guint * height); /*< private >*/ gpointer _reserved[GST_PADDING]; @@ -108,6 +111,10 @@ gboolean gst_vulkan_window_get_presentation_support (GstVulkanWi GstVulkanDevice *device, guint32 queue_family_idx); GST_VULKAN_API +void gst_vulkan_window_get_surface_dimensions (GstVulkanWindow *window, + guint *width, + guint *height); +GST_VULKAN_API void gst_vulkan_window_set_window_handle (GstVulkanWindow *window, guintptr handle); diff --git a/gst-libs/gst/vulkan/ios/gstvkios_utils.h b/gst-libs/gst/vulkan/ios/gstvkios_utils.h index a0df1ae797..646b81c33d 100644 --- a/gst-libs/gst/vulkan/ios/gstvkios_utils.h +++ b/gst-libs/gst/vulkan/ios/gstvkios_utils.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS @interface GstVulkanUIView : UIView +- (void) setGstWindow:(GstVulkanWindowIos *)window_ios; @end typedef void (*GstVulkanWindowFunc) (gpointer data); diff --git a/gst-libs/gst/vulkan/ios/gstvkwindow_ios.m b/gst-libs/gst/vulkan/ios/gstvkwindow_ios.m index e0fcabc02e..fa9e425b8a 100644 --- a/gst-libs/gst/vulkan/ios/gstvkwindow_ios.m +++ b/gst-libs/gst/vulkan/ios/gstvkwindow_ios.m @@ -142,7 +142,9 @@ _create_window (GstVulkanWindowIos * window_ios) GstVulkanUIView *view; view = [[GstVulkanUIView alloc] initWithFrame:rect]; + [view setGstWindow:window_ios]; view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + view.contentMode = UIViewContentModeRedraw; priv->internal_view = (__bridge_retained gpointer)view; [external_view addSubview:view]; @@ -216,7 +218,9 @@ static void gst_vulkan_window_ios_close (GstVulkanWindow * window) { GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (window); + GstVulkanUIView *view = (__bridge GstVulkanUIView *) window_ios->priv->internal_view; + [view setGstWindow:NULL]; CFBridgingRelease (window_ios->priv->internal_view); window_ios->priv->internal_view = NULL; @@ -240,13 +244,36 @@ gst_vulkan_window_ios_set_window_handle (GstVulkanWindow * window, window_ios->priv->external_view = view; } -@implementation GstVulkanUIView +@implementation GstVulkanUIView { + GstVulkanWindowIos * window_ios; + + guint width; + guint height; +}; +(Class) layerClass { return [CAMetalLayer class]; } +-(void) setGstWindow:(GstVulkanWindowIos *) window +{ + window_ios = window; +} + +-(void) layoutSubViews +{ + [super layoutSubviews]; + CGSize rect = self.bounds.size; + GST_ERROR ("%ix%i", (int) rect.width, (int) rect.height); + gboolean resize = self->width != rect.width || self->height != rect.height; + self->width = rect.width; + self->height = rect.height; + if (resize && self->window_ios) { + gst_vulkan_window_resize (GST_VULKAN_WINDOW (self->window_ios), rect.width, rect.height); + } +} + @end void